入門8 解放雙手,自由奔放的吃貨

能不能讓吃貨自動的發射?想要解決這個問題需要思考一下。

var x = game.width - moon.width / 2;

這是addMoon方法里給月餅的初始x坐標,在看看她運動一次的終點目標。在moveMoon方法里有這個。

moonTween = game.add.tween(moon).to({
        x : moon.width / 2,
        angle : -720
    }, speed, "Linear", true);

那么月餅運動一次的距離就是game.width - moon.width / 2 - moon.width / 2即game.width - moon.width。所用的時間是一個變量speed,這個值是會慢慢變的。
再來分析下吃貨運動一次的距離和所用的時間。

player.y = game.height - player.height - 150;

這個是addPlayer里吃貨的出生點的y坐標,它運動一次的終點在fire方法里。

playerTween = game.add.tween(player).to({ y : -player.height }, 500, 'Linear', true);

所以吃貨的運動距離應該是game.height - player.height - 150 - ( -player.height)即game.height - 150 = 450。時間是500毫秒。
現在吃貨和月餅的運動距離與運動用的時間都知道了,那么就能求出這兩個的速度來。
吃貨的速度直接口算就出來了,450 / 500 = 0.9,單位是像素/毫秒。
月餅的速度是(game.width - moon.width) / speed。


自由舞動的吃貨.PNG

如圖的分析,吃貨的x坐標是game.width / 2,而且一直不會變,那么吃貨從他的出生點到月餅的y坐標的高度,跟月餅運動到吃貨的x坐標兩者所用時間差不多,就應該能碰撞。
先添加三個變量。

var moon;
var currentMoonSpeed = 0;//月餅的移動速度
var currentPlayerSpeed = 0;//吃貨的移動速度
var playerTime = 0;//吃貨運動到月餅的高度需要的時間

對于支持webGL的瀏覽器我們還是傾向于使用這個來繪圖,所以創建游戲這里也改動一下。

var game = new Phaser.Game(WIDTH, HEIGHT, Phaser.AUTO, 'game');

在game.states.start方法里初始化這幾個變量。

        currentMoonSpeed = 0;
        currentPlayerSpeed = 0;
        playerTime = 0;

為了避免屏幕上出現多個吃貨,我們在fire方法里添加一行代碼,給吃貨添加一個屬性。

player.isFlying = true;

添加一個方法計算每次吃貨運動到月餅的高度所需要的時間。

// 計算吃貨運動到月餅高度需要的時間
function playerSpeed() {
    currentPlayerSpeed = 0.9;//(game.height - player.height - 150 + player.height) / 500
    playerTime = (game.height - player.height - 150 - moon.y) / currentPlayerSpeed;
}

在原來的碰撞處理函數collectMoon中添加兩行代碼。

player.isFlying = false;
moon.moving = false;

修改resetSpeed方法。

// 更新速度
function resetSpeed() {
    speed =  speed - 1;
    speed <= 500 ? 500 : speed;
    dropSpeed = dropSpeed - 1;
    dropSpeed <= 800 ? 800 : dropSpeed;
}

修改addMoon和moveMoon添加些難度。

// 添加月餅
function addMoon() {
    var index = game.rnd.between(1, 7);//隨機一個1到7的數字,好創建對應數字的月餅
    //var moon;
    if (score >0 && score % 10 == 0) {
        var name = game.rnd.between(0, 1) === 0 ? 's1' : 's2';
        moon = moonGroup.create(0, 0, name);
        moon.name = 'special';
        game.physics.arcade.enable(moon);
    } else {
        moon = moonGroup.create(0, 0, index.toString());//創建月餅
    }
    moon.anchor.set(0.5); // 設置演員錨點為中心點
    var x = game.width - moon.width / 2;
    var y = -moon.height / 2;
    moon.x = x;
    moon.y = y;
    var moonEnterTween = game.add.tween(moon).to({y : Math.max(moon.height * 2, game.height / 2 - level * 5) }, 
        game.rnd.between(500, 1000), 'Bounce', true);
    moonEnterTween.onComplete.add(moveMoon, this, 0, moon);
    
}

// 滾動月餅
function moveMoon(moon) {
    playerSpeed();
    currentMoonSpeed = (game.width - moon.width) / speed;
    console.log("speed is" + speed + " , moon speed is " + currentMoonSpeed);
    moonTween = game.add.tween(moon).to({
        x : moon.width / 2,
        angle : -720
    }, speed, "Linear", true);
    moon.moving = true;
    moonTween.onUpdateCallback(autoCalc, moonTween);
    moonTween.yoyo(true, 0);
    moonTween.repeat(50, 0);
}

其中moveMoon中我們給moonTween.onUpdateCallback設置了一個觸發的方法,方法名叫autoCalc。這個moonTween每次改變月餅屬性的時候都會回掉這個方法,我們在這個方法里計算吃貨是不是該出發了。

function autoCalc(tween) {
    if (player && player.isFlying) {
        return;
    }//避免放置多個吃貨
    var b = (moon.x - 300) / currentMoonSpeed;//計算月餅所需時間
//所需時間如果小于100毫秒就發射吃貨
    if (moon.moving && Math.abs(playerTime - b) <= 100){
        fire();
    }
}

運行看看效果。

13.gif

14.gif

終于解放了雙手,成就了奔放的吃貨。
本節教程代碼下載地址:
碼云
github

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容