能不能讓吃貨自動的發射?想要解決這個問題需要思考一下。
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。
如圖的分析,吃貨的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();
}
}
運行看看效果。
終于解放了雙手,成就了奔放的吃貨。
本節教程代碼下載地址:
碼云
github