Tìm hiểu về Phaser
1.Phaser là gì? Phaser là một HTML5 game framework mã nguồn mở. Phaser sử dụng Pixi.js để rendering trên WebGL và Canvas , Phaser hỗ trợ các trình duyệt web trên cả desktop và mobile. Game được phát triển bởi Phaser có thể dễ dàng được biên soạn thành ứng dụng cho iOS, Android và desktop thông ...
1.Phaser là gì?
Phaser là một HTML5 game framework mã nguồn mở. Phaser sử dụng Pixi.js để rendering trên WebGL và Canvas , Phaser hỗ trợ các trình duyệt web trên cả desktop và mobile. Game được phát triển bởi Phaser có thể dễ dàng được biên soạn thành ứng dụng cho iOS, Android và desktop thông qua các công cụ của bên thứ ba. Phaser là một framework cho HTML5 nên có thể viết bằng JavaScript hoặc TypeScript.
Hiện tại Phaser đã có Phaser 2 và 3, version mới nhất của phaser 2 là 2.6.2. Phaser 3 đã ra mắt tuy nhiên not yet ready for production use
Cùng với cộng đồng mã nguồn mở, Phaser được tích cực phát triển và duy trì bởi Photon Storm. Nhờ việc hỗ trợ nhanh chóng và xâu dựng một API thân thiện với người phát triển, Phaser hiện là một trong những most starred game frameworks trên GitHub.
2.Cài đặt Phaser
Có 2 cách để install Phaser: Sử dụng bower (hoặc npm) và dùng CDN
-
Bower / npm
bower install phaser npm install phaser
-
CDN: Chỉ cần thêm 1 trong 2 dòng sau vào file html
<script src="//cdn.jsdelivr.net/phaser/2.6.2/phaser.js"></script> <script src="//cdn.jsdelivr.net/phaser/2.6.2/phaser.min.js"></script>
Webpack
Bắt đầu từ Phaser 2.4.5, người dùng có thể sử dụng Webpack Khi đó p2 trở thành một dependency.
Webpack Config
var path = require('path'); var webpack = require('webpack'); var phaserModule = path.join(__dirname, '/node_modules/phaser/'); var phaser = path.join(phaserModule, 'build/custom/phaser-split.js'), pixi = path.join(phaserModule, 'build/custom/pixi.js'), p2 = path.join(phaserModule, 'build/custom/p2.js'); module.exports = { ... module: { loaders: [ { test: /pixi.js/, loader: "script" }, ] }, resolve: { alias: { 'phaser': phaser, 'pixi.js': pixi, 'p2': p2, } } ... }
Main js file
require('pixi.js'); require('p2'); require('phaser');
Game Breakout
Breakout là game có luật chơi đơn giản:
- Có 4 hàng x 15 viên gạch(break)
- Có một thanh ngang(paddle) và một quả bóng đặt ở trên(ball)
- Khi người chơi click thì quả bóng sẽ bay lên. Mỗi khi quả bóng chạm vào một viên gạch thì viên gạch đó sẽ biến mất
- Người chơi phải dùng thanh ngang đỡ quả bóng khi nó đang rơi xuống
- Khi tất cả breaks biến mất thì sẽ qua bàn mới. Khi người chơi mất hết mạng tức là làm rơi tất cả số bóng thì game over
Trong code phaser game Breakout có 3 func chính:
- preload: load các assets cần thiết
- create: được chạy 1 lần, khởi tạo và thiết lập cấu hình
- update: sẽ được chạy sau một khoảng delta cố định để cập nhật thay đổi
Preload
Ở bước này thì đơn thuần là load asset cho game: background, các hình ảnh của bricks, ball, paddle
function preload() { game.load.atlas('breakout', 'assets/games/breakout/breakout.png', 'assets/games/breakout/breakout.json'); game.load.image('starfield', 'assets/misc/starfield.jpg'); }
Create
Tạo backgound từ một image, starfield là image ta đã khai báo ở preload
s = game.add.tileSprite(0, 0, 800, 600, 'starfield');
Tạo 4 hàng x 15 bricks
bricks = game.add.group(); bricks.enableBody = true; bricks.physicsBodyType = Phaser.Physics.ARCADE; var brick; for (var y = 0; y < 4; y++) { for (var x = 0; x < 15; x++) { brick = bricks.create(120 + (x * 36), 100 + (y * 52), 'breakout', 'brick_' + (y+1) + '_1.png'); brick.body.bounce.set(1); brick.body.immovable = true; } }
Tạo paddle và ball
paddle = game.add.sprite(game.world.centerX, 500, 'breakout', 'paddle_big.png'); paddle.anchor.setTo(0.5, 0.5); game.physics.enable(paddle, Phaser.Physics.ARCADE); paddle.body.collideWorldBounds = true; paddle.body.bounce.set(1); paddle.body.immovable = true; ball = game.add.sprite(game.world.centerX, paddle.y - 16, 'breakout', 'ball_1.png'); ball.anchor.set(0.5); ball.checkWorldBounds = true; game.physics.enable(ball, Phaser.Physics.ARCADE); ball.body.collideWorldBounds = true; ball.body.bounce.set(1); ball.animations.add('spin', [ 'ball_1.png', 'ball_2.png', 'ball_3.png', 'ball_4.png', 'ball_5.png' ], 50, true, false);
Thêm sự kiện khi ball bị rơi ra ngoài paddle tức là người chơi dùng thanh ngang đỡ trượt khi quả bóng rơi xuống. Lúc nàyta giảm lives xuống, kiểm tra nếu lives = 0 thì game over, không thì ta reset, đặt bóng quay trở lại paddle ball.reset(paddle.body.x + 16, paddle.y - 16);
ball.events.onOutOfBounds.add(ballLost, this); function ballLost () { lives--; livesText.text = 'lives: ' + lives; if (lives === 0) { gameOver(); } else { ballOnPaddle = true; ball.reset(paddle.body.x + 16, paddle.y - 16); ball.animations.stop(); } }
Thêm event khi ball rơi xuống tiếp xúc với paddle. Lúc này ta chỉ cẩn set velocity để ball khi chạm vào paddle thì bật ngược lại
game.input.onDown.add(releaseBall, this); function releaseBall () { if (ballOnPaddle) { ballOnPaddle = false; ball.body.velocity.y = -300; ball.body.velocity.x = -75; ball.animations.play('spin'); introText.visible = false; } }
Update
function update () { paddle.x = game.input.x; if (paddle.x < 24) { paddle.x = 24; } else if (paddle.x > game.awidth - 24) { paddle.x = game.awidth - 24; } if (ballOnPaddle) { ball.body.x = paddle.x; } else { game.physics.arcade.collide(ball, paddle, ballHitPaddle, null, this); game.physics.arcade.collide(ball, bricks, ballHitBrick, null, this); } }
Nếu toàn bộ các bricks đã bị vỡ thì sang level mới và đưa ball về đặt trên paddle
game.physics.arcade.collide(ball, bricks, ballHitBrick, null, this); function ballHitBrick (_ball, _brick) { _brick.kill(); score += 10; scoreText.text = 'score: ' + score; if (bricks.countLiving() == 0) { score += 1000; scoreText.text = 'score: ' + score; introText.text = '- Next Level -'; ballOnPaddle = true; ball.body.velocity.set(0); ball.x = paddle.x + 16; ball.y = paddle.y - 16; ball.animations.stop(); bricks.callAll('revive'); } }