关于javascript:使用-Phaser3Matterjs-实现合成大西瓜游戏

9次阅读

共计 4599 个字符,预计需要花费 12 分钟才能阅读完成。

前言

最近有一款“合成大西瓜”的小游戏有点火,试玩了一下,玩法比较简单,实现难度也不大,所以参照游戏原型本人实现了一下,游戏开发次要应用了 Phaser 游戏框架,本文次要分享游戏性能的具体实现,对框架应用的 API 不会做过多介绍。

玩法剖析

首先简略介绍下游戏的玩法:管制水果从上方掉落,两个雷同水果会合成一个更大的水果,最终合成一个大西瓜,成果展现:

游戏的玩法在于正当管制着落的点防止空间的节约,在顶部有一条“死亡线”,当水果超过这个高度就完结,有点像俄罗斯方块,每合成一次水果都会得分,看谁能在游戏完结前或得更高的分数。

有多少种水果

游戏总共会呈现 11 种水果,通过察看,前 5 种水果会随机掉落,前面的水果都是合成才会呈现的

如何计算得分

每次合成新水果都会得分,按程序的话第一种是 1 分,第二种 2 分,第 10 种就是 10 分,最初合成大西瓜后是额定得 100 分:

疾速开始

游戏的根本玩法都曾经分明了,接下来就是开发了,首先咱们通过 Githubclone一个 phaser3 的脚手架来进行开发, 咱们首选 Typescript 版本的,对于这种简单的框架,类型提醒真的十分不便。

#! /bin/bash

$git clone git@github.com:photonstorm/phaser3-typescript-project-template.git hexigua
$cd hexigua
$npm install

#启动
$npm run watch

装置依赖并启动后,进入src/game.ts, 把原来的一些示例代码删掉, 后果如下:

import 'phaser'
export default class Demo extends Phaser.Scene {constructor () {super('demo')
  }

  preload () {}

  create () {}
}

const config = {
  type: Phaser.AUTO,
  backgroundColor: '#125555',
  width: 800,
  height: 600,
  scene: Demo
}

const game = new Phaser.Game(config)

preloadcreate 都属于框架的生命周期,preload次要用于事后下载资源,create用于创建对象或事件。

批改 config 参数

批改游戏初始化参数,指定应用 Matter.js 物理引擎,缩放模式通常设置为等比例缩放模式Phaser.Scale.FIT

const config = {
  type: Phaser.AUTO,
  backgroundColor: '#ffe8a3', // 改为游戏的背景色彩
  mode: Phaser.Scale.FIT, // 缩放模式
  physics: {
    default: 'matter', // 应用 matterjs 物理引擎
    matter: {
      gravity: {y: 2},
      debug: true // 开启调试
    }
  },
  width: window.innerWidth,
  height: window.innerHeight,
  scene: Demo
}

加载资源

接下在 preload 函数中加载筹备好的图片, 后面我曾经筹备好了 11 中类型水果的图片,为了不便开发,别离命名为 1-11.png

preload () {
  // 11 种类型水果
  for (let i = 1; i <= 11; i++) {this.load.image(`${i}`, `assets/${i}.png`)
  }
  // 地板图片
  this.load.image('ground', 'assets/ground.png')
}

新建水果

加载资源后,咱们先来创立游戏中最次要的对象水果,游戏中水果呈现的状况有两种,一种是在顶部落下,一种是碰撞后生成,除了地位不同,还有状态和类型也不同,用一个示意如下:

呈现地位 状态 类型
顶部 先静止点击后落下 前 5 种随机
合成后的地位 非静止 上一种 +1

把不同的局部作为参数,创立一个 createFruite 函数:

 /**
     * 增加一个水果
     * @param x 坐标 x
     * @param y 坐标 y
     * @param key 瓜的类型
     * @param isStatic 是否静止
     */
  createFruite (x: number, y: number, isStatic = true, key?: string,) {if (!key) {
      // 顶部落下的瓜前 5 个随机
      key = `${Phaser.Math.Between(1, 5)}`
    }
    // 创立
    const fruit = this.matter.add.image(x, y, key)
    // 设置物理刚体
    fruit.setBody({
      type: 'circle',
      radius: fruit.width / 2
    }, {
      isStatic,
      label: key // 设置 label 用于后续碰撞判断是否同一类型
    })
    // 增加一个动画成果
    this.tweens.add({
      targets: fruit,
      scale: {
        from: 0,
        to: 1
      },
      ease: 'Back',
      easeParams: [3.5],
      duration: 200
    })
    return fruit
  }

create 函数中创立地板和生成水果

create(){

    // 设置边界
    this.matter.world.setBounds()
    // 增加高空
    const groundSprite = this.add.tileSprite(WINDOW_WIDTH / 2, WINDOW_HEIGHT - 127 / 2, WINDOW_WIDTH, 127, 'ground')
    this.matter.add.gameObject(groundSprite, { isStatic: true})

    // 初始化第一个一个水果
    const x = WINDOW_WIDTH / 2
    const y = WINDOW_HEIGHT / 10
    let fruit = this.createFruite(x, y)

}

绑定点击屏幕事件

接下来就是增加事件点击屏幕的时候水果往下掉,并生成一个新的水果,新水果生成的工夫点就设在落下后一秒钟

create(){
     ...
    // 绑定 pointerdown 事件
    this.input.on('pointerdown', (point) => {if (this.enableAdd) {
            this.enableAdd = false
            // 先 x 轴上挪动到手指按下的点
            this.tweens.add({
                targets: fruit,
                x: point.x,
                duration: 100,
                ease: 'Power1',
                onComplete: () => {
                    // 勾销静止状态,让物体掉落
                    fruit.setStatic(false)
                    //1s 后生成新的水果
                    setTimeout(() => {fruit = this.createFruite(x, y)
                        this.enableAdd = true
                    }, 1000);
                }
            })
        }
    }
}

物体碰撞事件

实现水果生成后,下一步就是增加碰撞事件,在 phaser 中咱们能够应用 this.matter.world.on('collisionstart',fn) 来监听物体的碰撞事件,fn中会返回两个互相碰撞的物体对象,咱们依据后面设置的 label 值就能判断是否同一组,并进行后续操作

create(){
  ...
  this.matter.world.on('collisionstart', (event, bodyA, bodyB) => {
      const notXigua = bodyA.label !== '11'   // 非大西瓜
      const same = bodyA.label === bodyB.label // 雷同水果
      const live = !bodyA.isStatic && !bodyB.isStatic // 非动态
      if (notXigua && same && live) {
          // 设置为 Static, 这样能够调整物体地位,使物体重合
          bodyA.isStatic = true
          bodyB.isStatic = true
          const {x, y} = bodyA.position
          const lable = parseInt(bodyA.label) + 1
          // 增加两个动画合并的动画
          this.tweens.add({
              targets: bodyB.position,
              props: {x: { value: x, ease: 'Power3'},
                  y: {value: y, ease: 'Power3'}
              },
              duration: 150,
              onComplete: () => {
                  // 物体销毁
                  bodyA.gameObject.alpha = 0
                  bodyB.gameObject.alpha = 0
                  bodyB.destroy()
                  bodyA.destroy()
                  // 合成新水果
                  this.createFruite(x, y, false, `${lable}`)

              }
          })
      }
  })
}

到这一步咱们就根本实现了游戏的外围局部,先看下成果:

合成后只是简略的销毁物体,有工夫的话能够退出一些帧动画之类的成果会更好,这里就不加了,接下来持续加上完结断定和得分。

完结判断

后面提到,当落下的球超过指定的高度游戏即完结,咱们还是应用一个碰撞检测来实现,创立一个矩形物体作为咱们的“完结线”,当矩形碰到物体的时候即示意空间曾经不够游戏完结,还有一点须要非凡解决的是当咱们点击水果落下时是会碰到线的,这次碰撞须要过滤掉

create(){
...
// 线创立在水果 200px 下的地位
const endLineSprite = this.add.tileSprite(WINDOW_WIDTH / 2, y + 200, WINDOW_WIDTH, 8, 'endLine')
// 设为暗藏
endLineSprite.setVisible(false)
// 设置物理成果
this.matter.add.gameObject(endLineSprite, {
  // 静止
  isStatic: true,
  // 传感器模式,能够检测到碰撞,然而不会对物体产品成果
  isSensor: true,
  // 物体碰撞回调,
  onCollideCallback: () => {
     // 落下时碰到线不触发
     if(this.enableAdd){
        // 游戏完结
        console.log('end')
     }
  })
 })
}

得分

得分的逻辑其实比较简单了,在合成胜利后退出代码

let score = parseInt(bodyA.label)
this.score += score
// 合成西瓜额定加 100 分
if (score === 10) {this.score += 100}
this.scoreText.setText(this.score)
//
create(){
    // 创立一个 Text
    this.scoreText = this.add.text(30, 20, `${this.score}`, {font: '90px Arial Black', color: '#ffe325'}).setStroke('#974c1e', 16)
}

最初

到这里游戏的根底玩法就开发完结了,借助 Phaser 框架根本算能疾速的开发游戏的原型,如果你是老手对 H5 游戏开发感兴趣的话,那么 Phaser 是一个非常容易上手的框架,api 的设计也比拟敌对,还有大量的 demo 能够学习,或者下一个爆款游戏就出自于你呢。

本我的项目源码曾经公布到 github 仓库,感兴趣的能够自行查看

参考文章

如何顺手合成大西瓜,把把 1000 分?手残必看的高分攻略来了!

Phaser


欢送关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。

正文完
 0