phaserjs 總結

什麼是Phaser?javascript

簡單來講,Phaser就是一款免費開源的HTML5遊戲框架html

 

它有什麼特色?html5

高性能:快速、免費、易於維護。一方面,開發者能夠直接經過Koding平臺上的VM開發系統進行代碼編寫及預覽。另外一方面,也能夠在支持Canvas的瀏覽器中直接安裝Phaser來進行遊戲開發。java

多種支持:JavaScript、TypeScript雙重支持、內置遊戲對象的物理屬性、WebGL、Canvas渲染自由切換、徹底支持Web音頻、輸入:多點觸控、鍵盤、鼠標、MSPointer事件。web

兼容性強:除了IE 9+、Firefox、Chrome、Safari及Opera等桌面瀏覽器以外,Phaser還支持Mobile Chrome(Android 2.2+)及Mobile Safari(iOS 5+)等移動瀏覽器。使用Phaser進行遊戲開發沒有任何語言設定。算法

 

爲何選擇它?json

在根據統計到的《2016年最火的15款html5遊戲引擎》(原文地址:https://www.diycode.cc/topics/16)文章中能夠看到,phaser.js排在第二位,在pixi.js和egret.js以前,而排在第一位的three.js學習難度和週期比較高,若是從受歡迎程度來說的話,固然優先考慮phaser.js,若是專一於html5遊戲開發或者有這方面的發展意向,那這幾個均可以深刻學習下。另外值得一提的是,egret.js是國內開發的一款H5框架,也就是俗稱的白鷺,來自北京白鷺時代信息技術有限公司,毫無疑問,國人開發的框架,中文API讀起來是最方便的,有興趣的同窗也能夠優先考慮這個框架。canvas

 

一塊兒學習segmentfault

引入api

<scripttype="text/javascript"src="_site/phaser/phaser.2.7.0.min.js"></script>

 

建立一個簡單得遊戲場景

<div id="phaser-example"></div>
<scripttype="text/javascript"src="_site/phaser/phaser.2.7.0.min.js"></script>
<script>
    var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload,create: create });
function preload() { console.log(
"preload"); //加載資源   }
  function create() { console.log(
"create"); //建立場景   } </script>

new Phaser.Game參數爲:遊戲的寬,遊戲的高,遊戲的引擎,遊戲的容器id,遊戲的各類狀態,背景是否透明,是否消除鋸齒,物理引擎設置。這樣就會在id爲phaser-example建立一個canvas場景,返回這個遊戲對象。

 

物理引擎

 物理引擎,聽起來很高大上,其實說白了,就是解決物理現象的一些算法:好比速度、加速度、重力等等。

 Phaserjs中的物理引擎有三個,Arcade、Ninja和P2,三個物理引擎都提供了關於碰撞、重疊、移動等的處理方法,也都包含了重力、加速度、移動等方面的屬性,不過也有不一樣,Arcade屬於Phaserjs的內置引擎,Ninja引擎不是Phaserjs默認捆綁的物理引擎,使用的話須要先註冊,P2物理引擎則是一個單獨的物理引擎,很強大,不只支持Phaserjs,也支持其餘的一些框架

//使用了ARCADE引擎,並設置這個場景的全部對象有擁有了這個重力
function create() {
    game.physics.startSystem(Phaser.Physics.ARCADE);
 
    //設置遊戲標準重力爲100
    game.physics.arcade.gravity.y = 100;
}

碰撞檢測

function preload() {
    game.load.image('wizball', 'assets/sprites/wizball.png');
}

function create() {
    game.physics.startSystem(Phaser.Physics.ARCADE);
 
    ball1 = game.add.sprite(100, 240, 'wizball');
    ball2 = game.add.sprite(700, 240, 'wizball');
    game.physics.arcade.enable([ball1, ball2]);
}

function update () {
    //每次刷新都進行檢測
    game.physics.arcade.collide(ball1, ball2, function(){ coll(ball1, ball2); });
}

//碰撞檢測回調函數
function coll(obj1, obj2){
    //obj1和obj2爲碰撞的2個對象
}

 

遊戲的狀態

遊戲的狀態中包括初始化遊戲參數,加載資源,建立場景,監測更新,實時渲染等,使用什麼的遊戲狀態,根據本身的需求來

全部狀態:init,preload,loadUpdate,loadRender,create,update,preRender,render,resize,paused,resumed,pauseUpdate,shutdown

 

加載圖片,文字,動畫

//加載圖片
function preload() {
    game.load.image('imageKey','assets/sprites/phaser2.png');
}
//渲染 function create() { //渲染一張圖片   game.add.sprite(0, 0, 'imageKey');   //渲染文字   var text =game.add.text(game.world.centerX, game.world.centerY, "你好,歡迎來到Phaser的世界", textStyle);   //設置錨點 text.anchor.set(0.5, 0.5); }

 

爲了減小請求可使用這種紋理圖片,根據位置找到不一樣的圖片

function preload() {
    //加載紋理圖片和地圖集數據
    game.load.atlas('atlas','assets/sprites/atlas-mixed.png', 'assets/sprites/atlas-mixed.json');
    //加載位圖字體文件
    game.load.xml('fontData','assets/fonts/bitmapFonts/desyrel.xml');
}
function create() {   
//根據位置找到對象的圖片   bmpText = game.add.bitmapText(0, 100,'myFont', 'A Bitmap Font\nfrom a Texture Atlas', 64); }

 

function preload() {
    //39X40是每一個畫面的尺寸
    game.load.spritesheet('mummy', 'assets/sprites/metalslug_monster39x40.png',39, 40);
} 
function create() {
//將sprite添加到場景中 var mummy = game.add.sprite(300, 200,'mummy');   //由於圖片過小,放大爲原來的兩倍顯示   mummy.scale.set(2); //添加一個名叫walk的動畫 //由於咱們沒有設置其餘參數,因此它會執行mummy中全部的frame var walk = mummy.animations.add('walk'); //開始動畫,每秒30幀,循環執行 mummy.animations.play('walk', 30, true);
}

加載動畫其實就是每隔多長時間變化一下渲染的圖片位置

 

經常使用的基礎屬性

 anchor(錨點):取值範圍0~1,其實就是,元素(圖片、文字等)中心與放置位置(添加到的座標)相對於自身長寬的一個比例,好比(0,0)表示元素左上角座標和放置位置座標重合,(1,1)表示元素右下角座標和放置位置座標重合,(0.5,0.5)表示元素中心和放置位置重合,其餘則根據元素長寬比例來設置。

 scale(縮放比例):相對於元素原始尺寸的比例。

 angle(角度):一個有效的數字,通常取值0~360.

 alpha(透明度):也就是rgba中的a,取值範圍0~1.

 

鼠標,觸屏,按鍵事件

//鼠標事件
function create() {
    //阻止事件冒泡
    game.input.mouse.capture = true;
    game.input.mouse.onMouseDown = function(){
        console.log("down"); //點擊
    }
    game.input.mouse.onMouseWheel = function(){
        console.log("wheel"); //鬆開
    }
    game.input.mouse.onMouseMove = function(){
        console.log("move"); //點擊中
    }
}

有不少是都發現down打印不出來,咱們都會使用mousePointer或者activePointer對象來操做鼠標

//觸屏點擊
function create() {
    game.input.onDown.add(function() {
      console.log('DOWN');
      console.log(Date.now());
    });
    game.input.onHold.add(function() { //按下去2s後觸發
      console.log('Hold');
      console.log(Date.now());
    });
    game.input.onUp.add(function() {
      console.log('UP');
    });
    game.input.onTap.add(function() {
      console.log('TAP');
    });
}
// 鍵盤四個方向鍵
function create() { 
    upKey = game.input.keyboard.addKey(Phaser.Keyboard.UP);
    downKey = game.input.keyboard.addKey(Phaser.Keyboard.DOWN);
    leftKey = game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
    rightKey = game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
}
function update() {
    //判斷按鍵是否被按下
    if (upKey.isDown)
    {
        sprite.y--;
    }
    else if (downKey.isDown)
    {
        sprite.y++;
    }
    
    if (leftKey.isDown)
    {
        sprite.x--;
    }
    else if (rightKey.isDown)
    {
        sprite.x++;
    }
}

不一樣的鍵對用不一樣的屬性 http://phaser.io/docs/2.6.2/Phaser.KeyCode.html

 

音頻視頻

//音頻
function preload() {
//這裏要加載的元素支持數組格式 //官方的demo裏說Firefox不支持mp3格式,因此要添加使用ogg格式的備選文件,不過我試了,mp3和ogg火狐都是支持的    game.load.audio('wizball', 'assets/audio/oedipus_wizball_highscore.ogg'); } function create() { //添加音樂到遊戲場景並播放 music = game.add.audio('wizball'); music.play(); //設置音量 music.volume = 0.1; }
//音頻截取,其實很簡單,相似於CSS Sprite,把許多小文件整合在一塊兒,經過標記單獨使用其中的某一部分
function preload() {
    game.load.audio('sfx', 'assets/audio/SoundEffects/fx_mixdown.ogg');
}

function create() {
    game.add.image(0, 0, 'title');
    //註冊音頻文件
    fx = game.add.audio('sfx');
    //是否容許同時播放多段音樂
    fx.allowMultiple = false;
    //定義標記:關鍵字、開始時間、持續時間(單位:秒)
    fx.addMarker('alien death', 1, 1.0);
    fx.addMarker('boss hit', 3, 0.5);
    fx.addMarker('escape', 4, 3.2);//定義按鈕關鍵字和位置
    makeButton('alien death', 600, 100);
    makeButton('boss hit', 600, 140);
    makeButton('escape', 600, 180);
}
//加載視頻
function preload() {
    game.load.video('countryroad', 'assets/video/z0011j50w5k.p302.1.mp4');
}

function create() {
    //註冊視頻並播放
    video = game.add.video('countryroad');
    video.play(true);
    //將視頻添加到遊戲窗口中:x,y,anchorX,anchorY,scaleX,scaleY
    video.addToWorld(400, 250, 0.5, 0.5);
    video.volume = 0.1;
}

音頻和視頻要注意的點就是兼容性,據我測試一些低端的手機是不支持的。剩下的就是播放、暫停、繼續、中止、加大音量、減少音量這類操做,找到對應的api便可

 

位移,拖拽和補間動畫

遊戲j對象的位移都是經過改變遊戲對象x,y座標來實現的

//位移
function preload() {
    game.load.atlasJSONHash('bot', 'assets/sprites/running_bot.png', 'assets/sprites/running_bot.json');
}
var s; function create() { s = game.add.sprite(game.world.centerX, game.world.centerY, 'bot'); s.anchor.setTo(0.5, 0.5); s.animations.add('run'); s.animations.play('run', 10, true); } function update() { if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { s.x -= 4; } else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { s.x += 4; } }
//拖拽
function preload() {
    game.load.image('grid', 'assets/tests/debug-grid-1920x1920.png');
    game.load.image('atari', 'assets/sprites/atari800xl.png');
    game.load.image('sonic', 'assets/sprites/sonic_havok_sanity.png');
}
function create() {
var atari = group.create(32, 100, 'atari'); // 使atari對象能夠操做 atari.inputEnabled = true; atari.input.enableDrag(); // atari.input.enableDrag(true, true, true); atari.events.onDragStart.add(onDragStart, this); atari.events.onDragStop.add(onDragStop, this); }
//能夠獲得拖拽對象和觸摸對象 function onDragStart(sprite, pointer) { }
function onDragStop(sprite, pointer) { }

enableDrag的參數

enableDrag(lockCenter,bringToTop, pixelPerfect, alphaThreshold, boundsRect, boundsSprite)

lockCenter:是否鎖定中心,不管你按下的位置是在sprite的哪裏,下一個畫面sprite中心就會出如今你按下的地方;

bringToTop:是否置頂,就是拖動結束後是否位於最頂層;

pixelPerfect:是否啓用像素識別,這樣翻譯有利於理解,一張png圖片只多是矩形,可是上面的圖像不必定佔滿整個矩形,若是啓用像素識別,代碼會判斷你點擊的位置是否在圖像上,若是點擊的位置在空白區域,則拖動無效;

alphaThreshold:像素識別的精度,取值範圍0~255,數值越大精度越高;

boundsRect:定義矩形邊界;

boundsSprite:定義一個sprite爲邊界,你能夠試着添加一個和遊戲窗口同樣大的sprite圖片,而後參數設置爲它試下。

//補間動畫
function preload() {
    game.load.spritesheet('monster', 'assets/sprites/pixi_monsters.png', 154, 170);
}
function create() {
//添加一個圖像 var monster = game.add.sprite(400, 300, 'monster', 0); monster.anchor.setTo(0.5); game.add.tween(monster)   .to({ x: game.world.width - 10, y: game.world.height - 80 }, 100, "Linear", false) .to({ x: game.world.width - 10, y: 0 }, 400, "Linear", false) .to({ x: game.world.width / 2, y: 0 }, 100, "Linear", true); }

補間動畫最重要的兩個方法是from和to

 

 time(時間對象)和timer(定時器對象)

//時間對象
var timer;
function create() { //延時執行 timer = game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this); //重複運行(重複十次) game.time.events.repeat(Phaser.Timer.SECOND * 2, 10, createBall, this); //循環執行 game.time.events.loop(Phaser.Timer.SECOND, updateCounter, this); }
function fadePicture() { }
function createBall() { }
function updateCounter() { }

time調用獲得時間對象timer,也有對應的api去啓動,暫停,重啓,銷燬

 

function preload() {
    game.load.image('baddie', 'assets/sprites/space-baddie.png');
}
function create() {
//建立一個組 enemies = game.add.group(); for (var i = 0; i < 16; i++) { //在組裏面建立元素 enemies.create(360 + Math.random() * 200, 120 + Math.random() * 200, 'baddie'); } }

組有點相似數組,將子項添加到組內,設置組的屬性會給每一個子項都設置,不用每一個都操做一遍,這樣很方便。

總結:使用phaserjs建立小遊戲要先了解本身得需求適合什麼引擎,像p2引擎支持多邊形碰撞,使用對了引擎才能走向成功。建立對象並給他設置他本身得屬性,搞懂事件知道本身何時作出什麼動做,使用紋理圖和補間動畫讓對象動起來,時間對象就跟普通js得差很少,多個子項必定要使用組,作好碰撞檢測。多去看看例子。

 

phaser官網上有大量的例子,基本涵蓋了經常使用的東西。phaser小站上也有一些大牛寫的例子,仿照着寫寫,就會有提升的。

官網:http://phaser.io/

找了點博客幫助理解: https://blog.csdn.net/qq_36843675/article/details/79096043#load

https://blog.csdn.net/daveleecn/article/details/79017410

http://www.javashuo.com/article/p-rndwdtnp-bx.html

中文網:http://www.phaserengine.com/

phaser小站:https://www.phaser-china.com/example-detail-422.html

製做多邊形圖片:https://www.codeandweb.com/physicseditor

社區:http://club.phaser-china.com/

QQ羣:519413640,384427721

相關文章
相關標籤/搜索