PHASER.JS 遊戲框架 心得分享


Email: hank@catchad.com.tw
League of Legends: MiSs830320
Battle.net: MiSs830320#3631 (D3, 爐石戰記, 暴雪英霸)
Blade & Soul: 貴大師
Dragon Nest: 阿貴控肉飯
Twitch: http://www.twitch.tv/hank5678/

阿貴
Phaser.js
Getting Started
Sprites
Physics
Input
Overlap
Camera
Tilemap

Phaser.js
Performance (Pixi.js)
Tiled map editor
Examples
Getting Started
<!DOCTYPE html>
<html>
<head>
<title>phaser demo</title>
<link rel="stylesheet" href="assets/styles/normalize.css">
</head>
<body>
<div id="phaser-container"></div>
</body>
</html>
<script src="assets/scripts/phaser.2.4.4.min.js"></script>
<script src="assets/scripts/game.js"></script>HTML code:
Getting Started
var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-container', { preload: preload, create: create, update: update });
function preload() {
// 預載遊戲裡面需要的東西
}
function create() {
// 預載完成 開始創建phaser世界
}
function update() {
// 刷新
}
JS code:
Demo:
Sprites
function preload() {
// 預載遊戲裡面需要的東西
game.load.image('coin', 'assets/images/coin.png');
game.load.image('ground', 'assets/images/ground.png')
}

coin.png
ground.png
function create() {
// 預載完成 開始創建phaser世界
// 設定背景色
game.stage.backgroundColor = "#6888FF";
// 放一個金幣
var coin = game.add.sprite(600, 350, 'coin');
// 放第一塊陸地
var ground1 = game.add.tileSprite(0, game.height-16, 800, 16, "ground");
// 放第二塊陸地
var ground2 = game.add.tileSprite(450, 500, 300, 16, "ground");
}Sprites










tileSprite
Demo:
Physics
function preload() {
// 預載遊戲裡面需要的東西
...
game.load.spritesheet('mario', 'assets/images/mario.png', 32, 32);
}

mario.png
32
32
32 * 6
function create() {
// 預載完成 開始創建phaser世界
game.physics.startSystem(Phaser.Physics.ARCADE); // ARCADE, NINJA, P2
game.time.desiredFps = 60; // 設定FPS為60
// 新增一個管理物理碰撞的群組
platforms = game.add.group();
// 放第一塊陸地
var ground1 = game.add.tileSprite(0, game.height-16, 800, 16, "ground");
game.physics.arcade.enable(ground1); // 啟動它的物理反應
ground1.body.immovable = true; // 靜止不動
platforms.add(ground1); // 把陸地加入物理碰撞的群組
// 放玩家
player = game.add.sprite(0, 0, 'mario');
game.physics.arcade.enable(player);
player.anchor.set(0.5, 0.5); // 設定基準點
player.body.bounce.y = 0.2; // 彈性
player.body.gravity.y = 300; // 重力
}Physics

(0, 0)
(0.5, 0.5)
(1, 1)
function update() {
// 計算 player 與 platforms 群組的物理碰撞
game.physics.arcade.collide(player, platforms);
}Physics


Player
Platforms




Demo:
Input
function create() {
// 預載完成 開始創建phaser世界
...
// 定義鍵盤方向鍵
cursors = game.input.keyboard.createCursorKeys();
// 放玩家
...
player.body.collideWorldBounds = true;
player.animations.add('walk', [0, 1, 2, 3], 10, true); //loop
}

0
1
2
3
walk
4
5
jump
dead
Input
function update() {
player.body.velocity.x = 0; // 不動
// 按左鍵
if (cursors.left.isDown) {
player.body.velocity.x = -150; // 向左移動
player.scale.x = -1; // 水平翻轉
if( player.body.touching.down ) { // 玩家在地上
player.animations.play('walk');
}
}
// 沒有按左鍵 and 沒有按右鍵 and 玩家在地上
if( cursors.left.isUp && cursors.right.isUp && player.body.touching.down ) {
player.animations.stop(); // 暫停動畫
player.frame = 0; // 顯示原地不動影格
}
// 按上鍵 and 玩家在地上
if (cursors.up.isDown && player.body.touching.down) {
player.body.velocity.y = -300; // 向上移動
player.animations.stop(); // 暫停動畫
player.frame = 4; // 顯示跳影格
}
}Demo:
Overlap
function create() {
// 預載完成 開始創建phaser世界
...
coins = game.add.group(); // 建立coins群組
// 放十二個金幣
for (i = 0; i < 12; i++) {
var coin = game.add.sprite(i*70, 0, 'coin');
game.physics.arcade.enable(coin);
coin.body.gravity.y = 600; // 重力
coin.body.bounce.y = 0.3 + Math.random() * 0.5; // 隨機的彈性值
coins.add(coin); // 把金幣加入coins群組
}
}











Overlap
function update() {
// 計算 player 與 platforms 群組的物理碰撞
game.physics.arcade.collide(player, platforms);
// 計算 coins群組 與 platforms 群組的物理碰撞
game.physics.arcade.collide(coins, platforms);
// 計算 player 與 coins 群組的重疊狀態
game.physics.arcade.overlap(player, coins, collectCoin);
...
}
function collectCoin(player, coin) {
coin.kill(); // 刪除金幣
}




Player
Platforms
Coins


Demo:
Overlap
function preload() {
// 預載遊戲裡面需要的東西
...
game.load.image('luigi', 'assets/images/luigi.png');
}
luigi.png
Overlap
function create() {
...
// 放壞人
enemies = game.add.group();
var luigi = game.add.sprite(650, 350, 'luigi');
game.physics.arcade.enable(luigi);
luigi.anchor.set(0.5, 0.5);
luigi.body.gravity.y = 600;
luigi.body.bounce.y = 0.5;
enemies.add(luigi);
}(0, 0)
(0.5, 0.5)
(1, 1)

Overlap
function update() {
// 計算 player 與 platforms 群組的物理碰撞
game.physics.arcade.overlap(player, enemies, overlapEnemies);
...
}
function overlapEnemies(player, enemy) {
if( player.y + player.body.halfHeight <= enemy.y - enemy.body.halfHeight ) {
player.body.velocity.y = -150; // 向上移動
enemy.kill();
} else {
game.physics.arcade.isPaused = true; // 暫停物理引擎的運算
game.add.tween(player).to( { y: player.y+500 }, 1000, Phaser.Easing.Back.In, 500);
player.animations.stop(); //暫停目前的動畫
player.frame = 5; //顯示死掉的影格
}
}

player.y
halfHeight
enemy.y
halfHeight
Demo:
Camera
var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-container', { preload: preload, create: create, update: update });
function create() {
// 設定phaser遊戲世界的範圍
game.world.setBounds(0, 0, 1600, 600);
var ground1 = game.add.tileSprite(0, game.height-16, 1600, 16, "ground");
...
}800
600

1600
Camera
function update() {
// 鏡頭跟隨玩家位置
game.camera.focusOnXY(player.x , player.y );
...
}800
600


Demo:
Tilemap


Tilemap
function preload() {
game.load.tilemap('map', 'assets/mapdata/map.json', Phaser.Tilemap.TILED_JSON);
game.load.image('tiles', 'assets/images/tiles.png');
}
tiles.png
Tilemap
function create() {
game.stage.backgroundColor = '#6888FF'; // 設定背景色
map = game.add.tilemap('map'); // 把 map 加入遊戲
map.addTilesetImage('tiles'); // 把 map 使用到的圖塊加入進去
layer = map.createLayer('world'); // 把 Tiled 定義的圖層加進來
layer.resizeWorld(); // 設定layer範圍為遊戲世界邊界(setBounds)
map.setCollisionBetween(14, 16); // 設定圖塊中需要物理碰撞的單位
map.setCollisionBetween(20, 25);
map.setCollisionBetween(27, 29);
map.setCollision(40);
map.setTileIndexCallback(11, getCoin); // 設定圖塊被碰到時的 callback
...
}

1
14
15
16
20
25
11
40
Tilemap
function update() {
game.physics.arcade.collide(player, layer);
...
}
Player

Layer
Demo:
END
參考連結:
簡報demo:
https://event.catchad.com.tw/hanktest/phaser_demo/demo-01.html ~ demo-08.html
phaser:
http://phaser.io/
phaser社群:
http://www.html5gamedevs.com/forum/14-phaser/
Tiled:
http://www.mapeditor.org/
Phaser.js 遊戲框架 心得分享
By 蔡阿貴
Phaser.js 遊戲框架 心得分享
2016/03/09 前端工程師聚會簡報
- 1,911