【phaser.js學習筆記(1)】使用phaser.js製作遊戲
阿新 • • 發佈:2019-01-11
phaser.js是一款開源的HTML5遊戲框架,GitHub主頁上star超過了2萬。phaser.js支援使用JavaScript或TypeScript編寫遊戲,支援WebGL和Canvas渲染並可藉助第三方工具編譯成iOS,Android原生程式。phaser.js有兩個版本:phaser 3和phaser CE(Community Edition)。phaser CE基於phaser 3並由社群主導,phaser 3是下一代phaser。
1、安裝phaser 3
使用npm安裝
npm install phaser
使用時引入
import 'phaser';
2、建立遊戲物件
import 'phaser'; // 遊戲物件 let game; // 全域性遊戲設定 const gameOptions = { // 角速度,每幀多少度 rotationSpeed: 3, // 投擲飛刀的時間,單位毫秒 throwSpeed: 150, // 兩刀間最小間隔角度 minAngle: 15 } // 載入時初始化 window.onload = function () { // 配置資訊 const config = { // 渲染型別 type: Phaser.CANVAS, // 介面寬度,單位畫素 width: 750, // 介面高度 height: 1334, // 背景色 backgroundColor: 0x444444, // 場景 scene: [playGame] }; // 宣告遊戲物件 game = new Phaser.Game(config); // 獲取焦點,調節介面大小 window.focus(); resize(); window.addEventListener("resize", resize, false); }
首先定義全域性遊戲設定,主要包括各種遊戲引數。之後在視窗載入時宣告配置資訊並將配置資訊傳入Phaser.Game建構函式,獲取焦點、調整視窗。
視窗調整方法如下。
// 調節介面大小 function resize() { const canvas = document.querySelector("canvas"); const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; const windowRatio = windowWidth / windowHeight; const gameRatio = game.config.width / game.config.height; if(windowRatio < gameRatio){ canvas.style.width = windowWidth + "px"; canvas.style.height = (windowWidth / gameRatio) + "px"; } else{ canvas.style.width = (windowHeight * gameRatio) + "px"; canvas.style.height = windowHeight + "px"; } }
高度始終為視窗高度,寬度根據高度等比例調整。
3、建立遊戲主場景
// 遊戲主場景 class playGame extends Phaser.Scene { // 構造器 constructor() { super("PlayGame"); } // 遊戲載入前載入資源 preload() { // 載入圖片 this.load.image("target", "target.png"); this.load.image("knife", "knife.png"); } // 場景建立時執行 create(){ // 是否可以投擲飛刀 this.canThrow = true; // 已投飛刀陣列 this.knifeGroup = this.add.group(); // 增加一把刀 this.knife = this.add.sprite(game.config.width / 2, game.config.height / 5 * 4, "knife"); // 增加圓木 this.target = this.add.sprite(game.config.width / 2, 400, "target"); // 圓木在前,刀在後 this.target.depth = 1; // 等待投擲飛刀 this.input.on("pointerdown", this.throwKnife, this); } // 投擲飛刀方法 throwKnife() { // 判斷是否可以投擲 if (this.canThrow) { // 投擲後一段時間不可再次投擲 this.canThrow = false; // 飛刀動畫 this.tweens.add({ // 將到加入targets targets: [this.knife], // y方向目標 y: this.target.y + this.target.width / 2, // 動畫時間 duration: gameOptions.throwSpeed, // 回撥範圍 callbackScope: this, // 動畫完成後的回撥函式 onComplete: function (tween) { // 判斷飛刀是否可以插入圓木 let legalHit = true; // 獲取在圓木上旋轉的飛刀陣列 const children = this.knifeGroup.getChildren(); // 遍歷飛刀陣列 for (let i = 0; i < children.length; i++) { // 判斷刀間夾角是否滿足條件 if(Math.abs(Phaser.Math.Angle.ShortestBetween( this.target.angle, children[i].impactAngle)) < gameOptions.minAngle) { // 不滿足條件 legalHit = false; break; } } // 判斷是否滿足條件 if (legalHit) { // 可以繼續投擲 this.canThrow = true; // 飛刀陣列中增加本次飛刀 const knife = this.add.sprite(this.knife.x, this.knife.y, "knife"); // 儲存目標角度 knife.impactAngle = this.target.angle; // 新增到陣列 this.knifeGroup.add(knife); // 新生成一把刀 this.knife.y = game.config.height / 5 * 4; } else{ // 掉下來的動畫 this.tweens.add({ // 加到targets陣列 targets: [this.knife], // y方向目標 y: game.config.height + this.knife.height, // 旋轉度數,弧度制 rotation: 5, // 動畫時間 duration: gameOptions.throwSpeed * 4, // 回撥範圍 callbackScope: this, // 回撥函式 onComplete: function(tween) { // 開始新一局 this.scene.start("PlayGame") } }); } } }); } } // 每幀更新 update() { // 旋轉圓木 this.target.angle += gameOptions.rotationSpeed; // 獲取圓木上的飛刀陣列 const children = this.knifeGroup.getChildren(); // 遍歷飛刀陣列 for (let i = 0; i < children.length; i++){ // 旋轉每個飛刀 children[i].angle += gameOptions.rotationSpeed; // 度轉弧度 const radians = Phaser.Math.DegToRad(children[i].angle + 90); // 計算x,y使其圍繞中心旋轉 children[i].x = this.target.x + (this.target.width / 2) * Math.cos(radians); children[i].y = this.target.y + (this.target.width / 2) * Math.sin(radians); } } }
場景類中除建構函式外主要有4種方法:preload、create、throwKnife和update。preload主要用於在場景開始前預載入資源,如圖片、音樂等。create用於場景建立,在場景第一次被建立時呼叫一次,主要用於建立遊戲元素和初始化一些引數。throwKnife是create方法中pointerdown事件的回撥函式,當檢測到點選事件時,判斷是否可以投擲飛刀並呼叫tweens動畫管理器執行動畫。update每幀都會執行,主要用於新增動畫。
遊戲截圖如下。
完整程式見我的GitHub。git clone後先執行npm install安裝phaser,之後執行webpack打包,最後啟動http-server訪問index.html。