6. 判斷PC或手機
player.inputEnabled = true; //只能水平方向上拖動 player.input.allowVerticalDrag = false; //限制主角只能在世界中移動,不能超出屏幕 var dragRect = new Phaser.Rectangle(0,0,gWidth,gHeight); player.input.enableDrag(false,false,false,255,dragRect);
var playerW = this.player.width; //是否正在觸摸 var touching = false; //監聽按下事件 game.input.onDown.add(function(pointer){ //palyer.x是主角的橫向中心,判斷是指觸摸點在主角的最左側到最右側的坐標范圍內, //就是點擊的是小人本身,未判斷y坐標 if(Math.abs(pointer.x - player.x) < player.width/2){ touching = true; } }); //監聽離開事件 game.input.onUp.add(function(){ touching = false; }); //監聽滑動事件 game.input.addMoveCallback(function(pointer,x,y,isTap){ if(!isTap && touching){ x = mid(x, playerW/2, gWidth - playerW/2); player.x = x; } }); function mid(mid,min,max){ if(typeof min === undefined || min == null){ min = Number.NEGATIVE_INFINITY; } if(typeof max == undefined || max == null){ max = Number.POSITIVE_INFINITY; } return Math.min(Math.max(min,mid),max); }
//定時器添加紅包 var redgroup = this.add.group(); this.redgroup = redgroup; //全組開啟body redgroup.enableBody = true; //預先創建8個精靈對象 redgroup.createMultiple(8,'redpack'); //紅包組全體添加邊界檢測和邊界銷毀 redgroup.setAll('outOfBoundsKill',true); redgroup.setAll('checkWorldBounds',true); //定時添加紅包 game.time.events.loop(300,this.fBuildRedpack,this); //生成紅包的函數 this.fBuildRedpack = function(){ //沒有自動創建,getFirstDead和getFistExists此處等價 // var item = this.redgroup.getFirstDead(true); var item = this.redgroup.getFirstExists(false,true); var left = this.rnd.between(60,gWidth - 60); if(item){ //由於有超出邊界檢測,所以不能設置y為負值 item.reset(left,0); item.scale.set(0.5); item.body.velocity.y = 300; item.checkWorldBounds = true; item.outOfBoundsKill = true; } }
//大地 var land = game.add.graphics(0,gHeight-127/2); land.beginFill(0xce9424); land.moveTo(0,0); land.lineTo(gWidth, 0); land.lineTo(gWidth, gHeight); land.lineTo(0,gHeight);
13. 開啟物理引擎
//全局開啟物理引擎 this.physics.startSystem(Phaser.Physics.ARCADE); //單個對象開啟物理引擎 this.physics.arcade.enable(obj);
14. 碰撞檢測
//arcade的兩種碰撞檢測 //碰撞后的對象的消失,一般在update周期中使用overlap方法,碰撞后的回彈效果一般使用collide方法(通常在create周期中),兩種方法可以同時使用,不沖突 //有反彈碰撞 game.physics.arcade.collide(this.bird,Chimney); //無反彈碰撞,碰撞回調中有參與碰撞的對象,可以在回調中將對象kill掉 game.physics.arcade.overlap(this.redgroup,this.player,function(player,redpack){ redpack.kill(); },null,null,this);
15. 添加按鈕注冊點擊事件
//圖片按鈕可以使用精靈來做,精靈可以添加點擊事件 this.startButton = this.add.sprite(0,0,'ui','button.png'); this.startButton.anchor.set(0.5); this.startButton.x = game.world.centerX; this.startButton.y = game.height - 100; this.startButton.inputEnabled = true; this.startButton.input.useHandCursor = true; this.startButton.events.onInputDown.add(this.startGame,this);
setPreloadSprite(sprite, direction)
sprite:在加載過程中會出現的精靈或圖像。
direction:等於0精靈將被水平裁剪,等於1精靈將被垂直裁剪
Loader對象提供了一個 setPreloadSprite 方法,只要把一個sprite對象指定給這個方法,那么這個sprite對象的寬度或高度就會根據當前加載的百分比自動調整,達到一個動態的進度條的效果。
示例代碼如下:
var game = new Phaser.Game('100%', '100%', Phaser.AUTO, 'game'); game.States = {}; game.States.boot = function() { this.preload = function() { game.load.image('loading', 'img/loading.gif'); } this.create = function() { game.state.start('preload'); } } game.States.preload = function() { this.preload = function() { var preloadSprite = game.add.sprite(game.width / 2, game.height / 2, 'loading'); preloadSprite.anchor.setTo(0.5, 0.5); //用setPreloadSprite方法來實現動態進度條的效果,preloadSprite為load的精靈 game.load.setPreloadSprite(preloadSprite); game.load.image('pipe', 'img/pipe.png'); game.load.image('startBtn', 'img/start.jpg'); game.load.image('helpBtn', 'img/help.jpg'); } this.create = function() { game.state.start('menu'); } }
17. 執行補間動畫
Tween對象,是專門用來實現補間動畫的。通過game.add的tween方法得到一個Tween對象,這個方法的參數是需要進行補間動畫的物體。然后我們可以使用Tween對象的to方法來實現補間動畫。
to(properties, duration, ease, autoStart, delay, repeat, yoyo)
properties : 一個js對象,里面包含着需要進行動畫的屬性,如上面代碼中的 {y:120}
duration : 補間動畫持續的時間,單位為毫秒
ease : 緩動函數,默認為勻速動畫
autoStart : 是否自動開始
delay : 動畫開始前的延遲時間,單位為毫秒
repeat : 動畫重復的次數,如果需要動畫永遠循環,則把該值設為 Number.MAX_VALUE
yoyo : 如果該值為true,則動畫會自動反轉
示例:
game.add.tween(titleGroup).to({ y:120 },1000,null,true,0,Number.MAX_VALUE,true); //對這個組添加一個tween動畫,讓它不停的上下移動
ground.body.allowGravity = false; //沒有重力,不會下沉 // ground.body.immovable = true; //不可移動 // ground.body.collideWorldBounds = true; //如果設置為true,那么這個對象在撞到世界的邊界時會被反彈回這個世界。設置為false的話,對象在撞到世界邊界時會離開這個世界
//在render周期中寫調試代碼 this.render = function(){ //game.debug.body用來顯示每個物體的物理輪廓,具體顯示為綠色的形狀 //對組中的每個物體開啟物理輪廓 this.redgroup.forEach(function(item){ game.debug.body(item); }); //對單個物體開啟物理輪廓 game.debug.body(this.player); //屏幕上顯示一些調試文字 game.debug.text('CodeCaptain Shooting Demo', 10, 30); game.debug.text('Click or press space / enter to shoot', 10, 55); }
20. 對組中的元素進行統一操作
var redgroup = this.add.group(); //對組中的物體全部設置屬性 redgroup.setAll('checkWorldBounds',true); //對組中的物體全部調用函數 redgroup.callAll('events.onOutOfBounds.add', 'events.onOutOfBounds', this.fRemoveRedpack); //設置組中所有物體的anchor為0.5,1.0 redgroup.callAll('anchor.setTo', 'anchor', 0.5, 1.0);
21. 修改物理輪廓,即碰撞的區域
this.update = function(){ //設置小人的物理體積為高度的一半 var playerW = this.player.width, playerH = this.player.height; //由於scale 0.5的緣故,寬高設置要加倍 this.player.body.setSize(playerW*2,playerH,0,playerH); //設置方形物理輪廓,前面兩個是寬高,后面兩個是偏移 this.dragon.body.setSize(this.dragon.width, this.dragon.height / 2, 0, this.dragon.height / 2); //設置圓形物理輪廓 this.dragon.body.setCircle(this.dragon.width / 2); //恢復一下偏移為0 this.dragon.body.offset.set(0, 0); }
22. 物體超出邊界監測
1. checkWorldBounds 設置超出邊界檢測 sprite.checkWorldBounds = true; //對精靈進入邊界進行處理 sprite.events.onEnterOfBounds.add(callback,this); //對精靈離開邊界進行處理 sprite.events.onOutOfBounds.add(callback,this); 2. outOfBoundsKill //必須開啟checkWorldBound為true //超出邊界后自動kill,包括上下左右任意邊界 sprite.checkWorldBounds = true; sprite.outOfBoundsKill = true;