[Phaser] 小遊戲——小球成長

一塊兒來寫一個小球成長的遊戲吧html

let's go!前端

需求:git

  1. 小球在畫布內不規則運動,不會發生碰撞,只會重疊在一塊兒
  2. 有和小球相同數量的按鈕
  3. 每一個小球都有本身都編號而且和相應編號的按鈕綁定
  4. 長按按鈕,相應的小球會變大
  5. 鬆開按鈕,小球中止變大
  6. 若是正在變大的小球和其餘任何一個小球相碰,兩個小球的大小縮小一半而且中止變大
  7. 每一個球只能變大一次

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
    }
  }
}

至此,整個遊戲咱們就作完啦!🦍🦍🦍

在 GitHub 上查看完整代碼👇

前端phaser公衆號
qrcode_for_gh_26cb086dfbf2_258.jpg

相關文章
相關標籤/搜索