Phaser物理引擎篇
Phaser系列课程初步分成《基础篇上》、《基础篇下》、《动画篇》、《交互篇》、《物理引擎篇》、《图形绘制篇》、《场景篇》。
物理引擎为游戏模拟真实的物理场景,可以大大提升一个游戏的趣味性。官方完整的Phaser本身自带三个物理引擎(你也可以自己构建一个不带任何物理引擎的版本):Arcade、P2、Ninja,可以满足我们大部分的游戏需求,此外还有一个需要花钱购买的物理引擎Box2d插件。此篇,我们逐个介绍三个自带物理引擎,Box2d仅作为拓展知识。
首先,我们先来简单了解一下这三种物理引擎有什么区别?我们需要根据游戏需求选取适合的物理引擎。
Arcade:轻量级高性能AABB式物理碰撞系统,AABB即Axis-aligned Bounded Rectangles,译为轴对称盒子,只能以矩形框计算碰撞区域,精度低,运算速度快,可以实现简单的碰撞、重力等效果。
P2:可以实现多种物理模型和物理特性,如Arcade所不能实现的多边形碰撞区域、弹簧、摩擦力、碰撞材质、反弹系数等,功能强大但也必然会使运算复杂、耗费性能。
Ninja:可以实现平面、凹凸面、球面等的碰撞,物体在非平整面上碰撞时不会翻倒,跟忍者一样。
为专门讲解物理引擎,我们准备一个比较纯净的初始化界面,只保留前面课程中的背景、箱子、艾斯(关键帧雪碧图, json文件),初始Demo,代码如下所示:
1 | var game = new Phaser.Game(750, 750 / window.innerWidth * window.innerHeight, Phaser.CANVAS, 'phaser-container', { |
Arcade
不管是哪个物理引擎,都需要先给游戏引进物理引擎,引进Arcade:
1 | // 开启Arcade物理引擎 |
现在场景是看不出什么效果的,要使物理系统对某个物体起作用,需要开启该物体的物理特性,如下:1
2// 给hero和box添加物理特性
game.physics.enable([hero, box]);
这样,艾斯和箱子都会在重力的作用下做自由落体运动。对比设置前后,开启物理特性后的对象下的body新增了非常多的属性和方法,大多数和物理特性有关,你可以根据需要进行使用。当前的例子,物体会一直往下掉,通过设置body中一些属性,我们可以改变它们的表示,先熟悉一些常用的属性。
body常用属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
acceleration | object | {x=0, y=0} | 加速度 |
allowGravity | boolean | true | 是否启用重力效果 |
bounce | object | {x=0, y=0} | 设置反弹系数 |
collideWorldBounds | boolean | false | 是否监测与游戏世界边沿的碰撞 |
friction | object | {x=1, y=0} | 设置摩擦系数 |
gravity | object | {x=0, y=0} | 设置物体重力,会和世界重力叠加 |
immovable | boolean | false | 设置是否固定不动 |
mass | number | 1 | 设置重量 |
velocity | object | {x=0, y=0} | 设置速度 |
body常用方法
方法 | 参数 | 说明 |
---|---|---|
setSize | (width, height, offsetX, offsetY) | (宽度, 高度, 距离物体左边距, 距离物体上边距),重设物体的碰撞矩形区域 |
所以,我们要检测物体碰到游戏世界边沿就停止,并添加稍微的反弹效果,可以这么做:
1 | hero.body.collideWorldBounds = true; |
为检测艾斯和箱子碰撞,我们添加方向盘事件,控制艾斯移动:
1 | // create |
1 | // update |
这里要注意的是,在Arcade中,如果物体需要检测碰撞,改变物体位置要用velocity添加位移速度,而非动态改变x或者body.x,另外设置箱子静止,并开启调试模式查看物体碰撞区域:
1 | // create |
1 | // render |
改变box碰撞区域:
1 | box.body.setSize(404, 176, -100, 0); |
待续…..