一块儿来写一个小球成长
的游戏吧html
let's go!前端
需求:git
- 小球在画布内不规则运动,不会发生碰撞,只会重叠在一块儿
- 有和小球相同数量的按钮
- 每一个小球都有本身都编号而且和相应编号的按钮绑定
- 长按按钮,相应的小球会变大
- 松开按钮,小球中止变大
- 若是正在变大的小球和其余任何一个小球相碰,两个小球的大小缩小一半而且中止变大
- 每一个球只能变大一次
0. 先把简单的框架搭起来github
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>growing circle</title> <style> * { margin: 0; padding: 0; } </style> </head> <body> <div id="game"></div> <script src="./phaser.min.js"></script> <script> let game let gameOptions = { ballSpeed: 300, // 小球运动速度 balls: 8, // 小球总数 ballRadius: 50, // 小球半径 growRate: 1 // 增加速率 } class PlayGame extends Phaser.Scene { constructor() { super('PlayGame') } preload() { this.load.image('ball', 'ball.png') this.load.image('button', 'button.png') } create() { } update() { } } let gameConfig = { type: Phaser.AUTO, scale: { mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT, autoCenter: Phaser.Scale.CENTER_BOTH, parent: 'game', width: 750, height: 1464 }, physics: { default: 'arcade' }, scene: PlayGame } game = new Phaser.Game(gameConfig) </script> </body> </html>
引入 arcade
物理系统,方便小球作不规则运动app
1. 放置小球框架
class PlayGame extends Phaser.Scene { create() { // 设置小球的运动区域 this.physics.world.setBounds(0, 0, game.config.width, game.config.width) let gameArea = new Phaser.Geom.Rectangle(0, 0, game.config.width, game.config.width) // 物理组对象,存放全部的小球 this.ballGroup = this.physics.add.group() // 生成小球 for (let i = 0; i < gameOptions.balls; i++) { // 运动区域内随机一个点 let randomPosition = Phaser.Geom.Rectangle.Random(gameArea) // 放置小球 let ball = this.ballGroup.create(randomPosition.x, randomPosition.y, 'ball') // arcade 物理系统中设置小球的边界为圆形 ball.setCircle(256) ball.setCollideWorldBounds(true) // 宽高 ball.displayHeight = gameOptions.ballRadius ball.displayWidth = gameOptions.ballRadius // 编号 ball.index = i let ballText = this.add.text(ball.x, ball.y, i, { fontFamily: 'Arial', fontSize: 24, color: '#000000' }) ballText.setOrigin(0.5, 0.5) } } }
2. 放置按钮dom
class PlayGame extends Phaser.Scene { create() { let buttonPerRow = gameOptions.balls / 2 let buttonWidth = game.config.width / buttonPerRow this.buttonGroup = this.add.group() // 生成按钮 for (let i < 0; i < gameOptions.balls; i++) { let buttonX = buttonWidth * (i % (gameOptions.balls / 2)) let buttonY = game.config.width + buttonWidth * Math.floor(i / (gameOptions.balls / 2)) let button = this.add.sprite(buttonX, buttonY, 'button') button.setOrigin(0, 0) button.displayWidth = buttonWidth button.displayHeight = buttonWidth button.index = i this.buttonGroup.add(button) let buttonText = this.add.text(button.getBounds().centerX, button.getBounds().centerY, i, { fontFamily: 'Arial', fontSize: 64, color: '#000000' }) buttonText.setOrigin(0.5, 0.5) } } }
3. 设置分数ide
class PlayGame extends Phaser.Scene { create() { this.scoreText = this.add.text(0, game.config.height, 'Score: 0', { fontFamily: 'Arial', fontSize: 64 }) this.scoreText.setOrigin(0, 1) } }
4. 让小球动起来,不会碰撞,只会重叠this
class PlayGame extends Phaser.Scene { create() { this.ballArray = [] this.textArray = [] for (let i < 0; i < gameOptions.balls; i++) { this.ballArray.push(ball) this.textArray.push(ballText) // 随机一个方向向量 let directionVector = Phaser.Math.RandomXY(new Phaser.Math.Vector2, gameOptions.ballSpeed) // 设置小球的运动方向和速度 ball.setVelocity(directionVector.x, directionVector.y) // 设置小球碰到边界反弹 ball.setBounce(1) } } update() { for (let i = 0; i < gameOptions.balls; i++) { this.textArray[i].x = this.ballArray[i].x this.textArray[i].y = this.ballArray[i].y } } }
5. 给按钮绑定事件spa
class PlayGame extends Phaser.Scene { create() { this.input.on('pointerdown', this.startGrowing, this) // 小球开始变大 this.input.on('pointerup', this.stopGrowing, this) // 小球中止变大 this.ballToGrow = null } startGrowing(pointer) { this.buttonGroup.getChildren().map(button => { if (Phaser.Geom.Rectangle.Contains(button.getBounds(), pointer.x, pointer.y) && button.alpha === 1) { button.alpha = 0.5 this.ballToGrow = button.index console.log(button.index) } }) } stopGrowing() { this.ballToGrow = null } update() { this.score = 0 for (let i = 0; i < gameOptions.balls; i++) { this.score += this.ballArray[i].displayWidth - gameOptions.ballRadius; } this.scoreText.text = 'Score: ' + this.score if (this.ballToGrow != null) { this.ballArray[this.ballToGrow].displayWidth += gameOptions.growRate this.ballArray[this.ballToGrow].displayHeight += gameOptions.growRate } } }
6. 两个球重叠时触发事件
class PlayGame extends Phaser.Scene { create() { // 设置重叠事件 this.physics.add.overlap(this.ballGroup, this.ballGroup, this.handleOverlap, null, this) } handleOverlap(ball1, ball2) { if (this.ballToGrow !== null && (ball1.index === this.ballToGrow || ball2.index === this.ballToGrow)) { // 相机拍照效果,不加也可 this.cameras.main.flash() ball1.displayWidth = Math.max(ball1.displayWidth / 2, gameOptions.ballRadius) ball2.displayWidth = Math.max(ball2.displayWidth / 2, gameOptions.ballRadius) ball1.displayHeight = ball1.displayWidth ball2.displayHeight = ball2.displayWidth this.ballToGrow = null } } }
至此,整个游戏咱们就作完啦!🦍🦍🦍
前端phaser公众号