phaser學習總結之phaser入門教程
- 2019 年 10 月 4 日
- 筆記
前言
最近公司做項目的時候正好使用到phaser,在這裡做一下自己整理出來的一些心得,方便大家參考,phaser這一個遊戲引擎通常是做2d遊戲的,入門也非常簡單,只需你會一點的javascript,但是你想做一個比較完美的遊戲的話,那麼光靠一點點的javascript是遠遠不夠的,本篇部落格將快速帶你入門phaser。
phaser簡介
phaser是一款快速,免費及開源HTML5遊戲框架,它支援WebGL和Canvas兩種渲染模式,可以在任何web瀏覽器環境下運行,遊戲可以通過第三方工具轉為iOS、Android 支援的 Native APP,允許使用 JavaScript 和 TypeScript 進行開發。
phaser核心
語法:new Game(width, height, renderer, parent, state, transparent, antialias, physicsConfig)
phaser中的一切都是從Game類開始,所以我們暫時將Game類當作phaser的中心吧!當你new了一個Game之後,game中的很多屬性就有了,phaser的核心可以用如下這張圖表示。
這裡我們經常使用的對象有load,time,world,input,camera。
入門教程
創建phaser對象
(1):創建phaser對象方式一
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>快速入門phaser</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var game=new Phaser.Game(800,600,Phaser.AUTO,'',{preload:preload,create:create,update:update}); function preload(){ console.log('preload'); } function create(){ console.log('create'); } function update(){ console.log('update'); } </script> </body> </html>
(2):創建phaser對象方式二
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>快速入門phaser<</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var game=new Phaser.Game(800,600,Phaser.AUTO); var main=function(game){ this.init=function(){ //遊戲場景初始化 } this.preload=function(){ //遊戲資源預載入 } this.create=function(){ //遊戲場景創建 } this.update=function(){ //遊戲邏輯實現 } this.render=function(){ //遊戲自定義渲染 } } </script> </body> </html>
(3):創建phaser對象方式三
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>快速入門phaser</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var game=new Phaser.Game(800,600,Phaser.AUTO); game.state.add('state',state); game.state.start('state'); function state(){ this.init=function(){} this.preload=function(){} this.create=function(){} this.update=function(){} this.render=function(){} } </script> </body> </html>
(4):創建phaser對象方式四
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>快速入門phaser</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var game=new Phaser.Game(800,600,Phaser.AUTO,state); function state(){ this.init=function(){ } this.preload=function(){ } this.create=function(){ } this.update=function(){ } this.render=function(){ } } </script> </body> </html>
(5):創建phaser對象方式五
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>快速入門phasr</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update } } var game=new Phaser.Game(config); function preload(){ } function create(){ } function update(){ } </script> </body> </html>
在開發中,我們經常使用方式五創建phaser對象,當然你也可以根據自己的喜好選擇,就看你是喜歡函數創建還是對象創建。
參數詳解
Name | Type | Default |
width:遊戲寬度 | number|string | 800 |
height:遊戲高度 | number|string | 600 |
renderer:遊戲渲染方式 | number | Phaser.AUTO |
parent:遊戲容器 | string|HTMLElement | ” |
state:遊戲默認場景 | object | null |
transparent:畫布元素是否透明 | boolean | false |
antialias:是否開啟抗鋸齒 | boolean | true |
physicsConfig:物理引擎配置 | object | null |
(1):width
畫布寬度,數字或字元串類型可選參數,默認為800,如果以字元串的形式給出,該值必須在0到100之間,為百分比,如果沒有指定父容器,則默認為瀏覽器窗口
(2):height
畫布高度
(3):renderer
指定渲染機制,值可以是Phaser.WebGL,Phaser.Canvas,Phaser.AUTO(自動嘗試使用WebGL,如果瀏覽器或設備不支援,使用canvas)或者Phaser.HEADLESS(不進行渲染)
(4):parent
想插入遊戲畫布的DOM元素,畫布的父元素,可選值為DOM本身或者是id,如果為空字元串,畫布將被插入到body元素中
(5):state
默認的狀態對象,對象類型,可以是null,也可以是Phaser.state函數(初始化,預載入,創建,更新,渲染)
(6):transparent
畫布背景是否透明,布爾值,默認為false
(7):antialias
是否繪製為平滑紋理,布爾值,默認為true
(8):physicsConfig
一個物理配置對象,在Physics world創建時傳遞,對象默認為null
註:renderer可選Phaser.AUTO,Phaser.Canvas,Phaser.WebGL
參考文檔:https://photonstorm.github.io/phaser-ce/Phaser.Game.html
中文網:http://www.phaserengine.com/
phaser小站:https://www.phaser-china.com/example-detail-422.html
社區:http://club.phaser-china.com/
實例解析
接下來我們通過phaser實現一個小遊戲以及快速入門,見識下phaser開發遊戲的功能有多麼的強大,需要說明的是,這個就是phaser官方入門的案例,廢話不多說,直接上源碼。
(1):創建遊戲和添加場景
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); function preload(){ //載入資源 } function create(){ //對象的創建及初始化 } function update(){ //遊戲主循環 } </script> </body> </html>
在這裡,我們已經創建了遊戲場景和載入了遊戲場景,但是我們看到一片黑的,接下來我們加點東西。
(2):資源載入
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/star.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.add.sprite(0,0,'star'); } function update(){ //遊戲主循環 } </script> </body> </html>
我們看到螢幕的左上角出現了一顆星星,但是還是缺點什麼,這種效果依然不是我們想要的效果,接下來我們讓它更具體化。
(3):載入場地
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); var platforms;//場地 function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/platform.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0,0,'sky'); //將圖片添加到遊戲場景中 platforms=game.add.group(); platforms.enableBody=true; var ground=platforms.create(0,game.world.height-64,'ground'); ground.scale.setTo(2,2); ground.body.immovable=true; var ledge=platforms.create(400,400,'ground'); ledge.body.immovable=true; ledge=platforms.create(-150,250,'ground'); ledge.body.immovable=true; } function update(){ //遊戲主循環 } </script> </body> </html>
在這裡我們已經將場景加入進來了以及開啟了物理引擎,當然這只是為後面做準備,然後我們創建了天空,大地和兩個平板。大地和平板的位置定位,我們是通過坐標來進行的,
其中,大地和兩個平板都被加到了platforms這個組中,這個組我們為它啟動了物理屬性,然後我們設置了大地和兩個平板是不能動的,這樣他們就不會由於撞擊被改變位置。接下來,我們來加入一個小人,這個小人也是我們遊戲的主角。
(4):載入主角
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); var platforms;//場地 var player;//遊戲主角 function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/platform.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0,0,'sky'); //夾圖片添加到遊戲場景中 platforms=game.add.group(); platforms.enableBody=true; var ground=platforms.create(0,game.world.height-64,'ground'); ground.scale.setTo(2,2); ground.body.immovable=true; var ledge=platforms.create(400,400,'ground'); ledge.body.immovable=true; ledge=platforms.create(-150,250,'ground'); ledge.body.immovable=true; //載入主角 player=game.add.sprite(32,game.world.height-150,'dude'); game.physics.arcade.enable(player); player.body.bounce.y=0.2; //設置主角的彈性 player.body.gravity.y=300; //設置主角的重力 player.body.collideWorldBounds=true; player.animations.add('left',[0,1,2,3],10,true); //設置主角向左方向的序列幀 player.animations.add('right',[5,6,7,8],10,true); //設置主角向右方向的序列幀 } function update(){ //遊戲主循環 } </script> </body> </html>
dude.png圖片
同樣是通過game.add.sprite將精靈加入進來,但是大家仔細看看dude.png這張資源圖片,這是一個幀動畫序列,裡面包含了主角左移和右移的動畫幀。我們同樣給它開啟了物理屬性,然後設置了它的彈性和重力。player.body.collideWorldBounds = true;這句話設置了它會與邊界進行碰撞,這就是為什麼主角落下的時候,到遊戲區域邊界就不會掉下去,大家可以把這句話注釋掉再運行,看看會是什麼情況。在這裡,我們還為小人添加了兩個動畫,一個是向左移動,一個是向右移動,分別指定了響應的動畫幀,這也是為後續的動畫做準備。
(5):使主角站立平台上
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); var platforms;//場地 var player;//遊戲主角 function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/platform.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0,0,'sky'); //夾圖片添加到遊戲場景中 platforms=game.add.group(); platforms.enableBody=true; var ground=platforms.create(0,game.world.height-64,'ground'); ground.scale.setTo(2,2); ground.body.immovable=true; var ledge=platforms.create(400,400,'ground'); ledge.body.immovable=true; ledge=platforms.create(-150,250,'ground'); ledge.body.immovable=true; //載入主角 player=game.add.sprite(32,game.world.height-150,'dude'); game.physics.arcade.enable(player); player.body.bounce.y=0.2; //設置主角的彈性 player.body.gravity.y=300; //設置主角的重力 player.body.collideWorldBounds=true; player.animations.add('left',[0,1,2,3],10,true); //設置主角向左方向的序列幀 player.animations.add('right',[5,6,7,8],10,true); //設置主角向右方向的序列幀 } function update(){ //遊戲主循環 game.physics.arcade.collide(player,platforms); } </script> </body> </html>
是不是很驚訝?要讓主角站在地上,只要在update中加上一句,game.physics.arcade.collide(player, platforms);就可以了,這句話表示,檢測主角與platforms組的碰撞,而大地正是在platforms組中,這樣,主角就不會穿過大地了。同樣地,當主角與兩個平板碰撞時,也不會穿過了。接下來我們讓主角運動。
(5):主角運動
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); var platforms;//場地 var player;//遊戲主角 var cursors;//控制鍵 function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/platform.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0,0,'sky'); //夾圖片添加到遊戲場景中 platforms=game.add.group(); platforms.enableBody=true; var ground=platforms.create(0,game.world.height-64,'ground'); ground.scale.setTo(2,2); ground.body.immovable=true; var ledge=platforms.create(400,400,'ground'); ledge.body.immovable=true; ledge=platforms.create(-150,250,'ground'); ledge.body.immovable=true; //載入主角 player=game.add.sprite(32,game.world.height-150,'dude'); game.physics.arcade.enable(player); player.body.bounce.y=0.2; //設置主角的彈性 player.body.gravity.y=300; //設置主角的重力 player.body.collideWorldBounds=true; player.animations.add('left',[0,1,2,3],10,true); //設置主角向左方向的序列幀 player.animations.add('right',[5,6,7,8],10,true); //設置主角向右方向的序列幀 //創建控制鍵對象 cursors=game.input.keyboard.createCursorKeys(); } function update(){ //遊戲主循環 game.physics.arcade.collide(player,platforms); //控制主角開始 player.body.velocity.x=0; if(cursors.left.isDown){ player.body.velocity.x=-150; player.animations.play('left');//播放主角向左運動的序列幀動畫 }else if(cursors.right.isDown){ player.body.velocity.x=150; player.animations.play('right');//播放主角向右的序列幀動畫 }else{ player.animations.stop();//停止動畫 player.frame=4; //小球靜止時顯示第四幀動畫 } if(cursors.up.isDown&&player.body.touching.down){ player.body.velocity.y=-350; } } </script> </body> </html>
我們希望讓主角在按下方向左鍵的時候,向左移動,按下方向右鍵的時候,向右移動,為了實現這一功能,我們又定義了一個cursors,我們通過cursors = game.input.keyboard.createCursorKeys();來獲取系統的鍵盤輸入對象。然後,我們在update中,通過cursors.left.isDown來判斷用戶是否按下了鍵盤左鍵,如果按下了,我們給主角設置一個速度,然後播放左移的動畫,方向右鍵的邏輯是一樣的。如果方向左鍵和右鍵都沒有按下,那麼我們就通過player.frame來設置小人停在第4幀。小人的跳躍是通過方向上鍵來實現的,但是這裡有一個條件,就是小人在空中的時候,不允許跳躍,所以,加上了一個player.body.touching.down的判斷條件。
(6):載入大量星星
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); var platforms;//場地 var player;//遊戲主角 var cursors;//控制鍵 var stars;//星星 function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/platform.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0,0,'sky'); //夾圖片添加到遊戲場景中 platforms=game.add.group(); platforms.enableBody=true; var ground=platforms.create(0,game.world.height-64,'ground'); ground.scale.setTo(2,2); ground.body.immovable=true; var ledge=platforms.create(400,400,'ground'); ledge.body.immovable=true; ledge=platforms.create(-150,250,'ground'); ledge.body.immovable=true; //載入主角 player=game.add.sprite(32,game.world.height-150,'dude'); game.physics.arcade.enable(player); player.body.bounce.y=0.2; //設置主角的彈性 player.body.gravity.y=300; //設置主角的重力 player.body.collideWorldBounds=true; player.animations.add('left',[0,1,2,3],10,true); //設置主角向左方向的序列幀 player.animations.add('right',[5,6,7,8],10,true); //設置主角向右方向的序列幀 //創建控制鍵對象 cursors=game.input.keyboard.createCursorKeys(); //載入星星 stars=game.add.group(); //把星星先添加到組中 stars.enableBody = true; for(var i=0;i<20;i++){ var star=stars.create(i*70,0,'star'); star.body.gravity.y=300; //設置星星的重力 star.body.bounce.y=0.7+Math.random()*0.2; //設置星星的彈性 } } function update(){ //遊戲主循環 game.physics.arcade.collide(player,platforms); //星星載入相關 game.physics.arcade.collide(stars,platforms); game.physics.arcade.overlap(player,stars,collectStar,null,this); //控制主角開始 player.body.velocity.x=0; if(cursors.left.isDown){ player.body.velocity.x=-150; player.animations.play('left');//播放主角向左運動的序列幀動畫 }else if(cursors.right.isDown){ player.body.velocity.x=150; player.animations.play('right');//播放主角向右的序列幀動畫 }else{ player.animations.stop();//停止動畫 player.frame=4; //小球靜止時顯示第四幀動畫 } if(cursors.up.isDown&&player.body.touching.down){ player.body.velocity.y=-350; } } function collectStar(player,stars){ stars.kill();//銷毀星星 } </script> </body> </html>
在create中,我們又創建了一個stars的組,在這個組中,添加了星星,然後設置了它們的重力,隨機設置了彈性,所以它們掉落的時候,碰到平板或者地面,會彈起不同的高度。同樣,星星也不能穿過地面,所以在update中,添加了碰撞檢測。
還有一層碰撞檢測就是小人和星星的碰撞,當主角和星星發生碰撞的時候,需要讓星星消失,這時候,再添加碰撞檢測的時候,我們還添加了一個回調函數collectStar,在這裡面,我們的player和star都會作為參數傳遞進來,通過調用star.kill();將星星銷毀。
(7):顯示分數
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>phaser入門小遊戲</title> </head> <body> <script src="../../js/phaser.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var config={ width:800, height:600, renderer:Phaser.AUTO, antialias:true, multiTexture:true, state:{ preload:preload, create:create, update:update, } } var game=new Phaser.Game(config); var platforms;//場地 var player;//遊戲主角 var cursors;//控制鍵 var stars;//星星 var score=0;//初始分數為0 var scoreText;//展示分數的文本 function preload(){ //載入資源 game.load.image('sky','../../assets/sky.png'); game.load.image('ground','../../assets/platform.png'); game.load.image('star','../../assets/star.png'); game.load.spritesheet('dude','../../assets/dude.png',32,48); } function create(){ //對象的創建及初始化 game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0,0,'sky'); //夾圖片添加到遊戲場景中 platforms=game.add.group(); platforms.enableBody=true; var ground=platforms.create(0,game.world.height-64,'ground'); ground.scale.setTo(2,2); ground.body.immovable=true; var ledge=platforms.create(400,400,'ground'); ledge.body.immovable=true; ledge=platforms.create(-150,250,'ground'); ledge.body.immovable=true; //載入主角 player=game.add.sprite(32,game.world.height-150,'dude'); game.physics.arcade.enable(player); player.body.bounce.y=0.2; //設置主角的彈性 player.body.gravity.y=300; //設置主角的重力 player.body.collideWorldBounds=true; player.animations.add('left',[0,1,2,3],10,true); //設置主角向左方向的序列幀 player.animations.add('right',[5,6,7,8],10,true); //設置主角向右方向的序列幀 //創建控制鍵對象 cursors=game.input.keyboard.createCursorKeys(); //載入星星 stars=game.add.group(); //把星星先添加到組中 stars.enableBody = true; for(var i=0;i<20;i++){ var star=stars.create(i*70,0,'star'); star.body.gravity.y=300; //設置星星的重力 star.body.bounce.y=0.7+Math.random()*0.2; //設置星星的彈性 } //分數相關 scoreText=game.add.text(16,16,'分數:0',{fontSize:'32px',fill:'#000'}); } function update(){ //遊戲主循環 game.physics.arcade.collide(player,platforms); //星星載入相關 game.physics.arcade.collide(stars,platforms); game.physics.arcade.overlap(player,stars,collectStar,null,this); //控制主角開始 player.body.velocity.x=0; if(cursors.left.isDown){ player.body.velocity.x=-150; player.animations.play('left');//播放主角向左運動的序列幀動畫 }else if(cursors.right.isDown){ player.body.velocity.x=150; player.animations.play('right');//播放主角向右的序列幀動畫 }else{ player.animations.stop();//停止動畫 player.frame=4; //小球靜止時顯示第四幀動畫 } if(cursors.up.isDown&&player.body.touching.down){ player.body.velocity.y=-350; } } function collectStar(player,stars){ stars.kill();//銷毀星星 score+=10; scoreText.text='分數:'+score; } </script> </body> </html>
我們通過game.add.text為場景加上一個文本,顯示在左上角,在collectStar的時候,將分數進行累加,然後更新顯示,這樣就結束啦。到這裡,一個簡單的小遊戲就實現了,是不是比想像中的簡單呢?