《星辰战机》使用P2物理引擎
(该游戏并不需要模拟物理,这里有些大材小用,只用来检测碰撞,哈哈哈)
1、首先初始化p2 world:
this.world = new p2.World({ gravity: [0, 0] }); // 不需要重力
2、更新物理计算
egret.startTick(this.updateWorld, this); /** * 更新世界 */ private updateWorld(ts: number): boolean { var timeStep = ts / 1000; this.world.step(timeStep); var bodys = this.world.bodies; var len: number = bodys.length; for (var i: number = 0; i < len; i++) { var body: p2.Body = bodys[i]; if (body.userData && body.userData.skin) { // 更新素材的坐标和角度 var skin: egret.DisplayObject = body.userData.skin; skin.x = body.position[0]; skin.y = body.position[1]; skin.rotation = body.angle * 180 / Math.PI; } } return true; }
3、给需要检测的对象加上刚体
比如玩家操作的飞机:
let points = [[0, 100], [40, 0], [80, 100]]; let body = new p2.Body({ mass: 0 }); body.type = p2.Body.DYNAMIC; body.userData = {}; body.fromPolygon(points, { optimalDecomp: false }); this.world.addBody(body);
4、为每个碰撞对象进行分组
比如玩家操作的飞机:
this.body.userData[emBodyType.Player] = true; for (let i = 0; i < this.body.shapes.length; i++) { this.body.shapes[i].collisionGroup = emCollisionGroup.Player; this.body.shapes[i].collisionMask = emCollisionGroup.Enemy | emCollisionGroup.BOSSBullet | emCollisionGroup.Devil; }
5、监听碰撞事件并处理对应的逻辑:
this.world.on("beginContact", this.CheckCollisionP2.bind(this)); /** * p2碰撞检测 */ private CheckCollisionP2(event): void { var bodyA: p2.Body = event.bodyA; var bodyB: p2.Body = event.bodyB; if (bodyA.userData[emBodyType.Player] || bodyB.userData[emBodyType.Player]) { // 玩家碰撞 this.CheckCollisionPlayerP2(bodyA, bodyB); } else if (bodyA.userData[emBodyType.Bullet] || bodyB.userData[emBodyType.Bullet]) { // 玩家子弹碰撞 this.CheckCollisionBulletP2(bodyA, bodyB); } return; } /** * 玩家碰撞 */ private CheckCollisionPlayerP2(bodyA: p2.Body, bodyB: p2.Body): void { // 玩家与敌机或BOSS子弹碰撞 let isAPlayer = bodyA.userData[emBodyType.Player]; // A 是否是玩家 if (bodyA.userData[emBodyType.Enemy] || bodyB.userData[emBodyType.Enemy]) { let enemy = isAPlayer ? bodyB : bodyA; // 玩家与敌机碰撞 this.CheckCollisionPlayerEnemyP2(bodyA, bodyB); } else if (bodyA.userData[emBodyType.BOSSBullet] || bodyB.userData[emBodyType.BOSSBullet]) { // 玩家与BOSS子弹碰撞 this.CheckCollisionBossBulletP2(bodyA, bodyB); } else if (bodyA.userData[emBodyType.Devil] || bodyB.userData[emBodyType.Devil]) { // 玩家与陷阱碰撞 this.CheckCollisionDevilP2(bodyA, bodyB); } return; } /** * 玩家与敌机碰撞 */ private CheckCollisionPlayerEnemyP2(bodyA: p2.Body, bodyB: p2.Body): void { let enemy: EnemyPlane = (bodyA.userData[emBodyType.Enemy] ? bodyA : bodyB).userData["self"]; if (gameInfo.player.CheckBuff(emItemType.Shield)) { gameInfo.RemoveEnemy(enemy); } else { gameInfo.gameState = emGameState.GameOver; } return; } /** * 玩家与BOSS子弹碰撞 */ private CheckCollisionBossBulletP2(bodyA: p2.Body, bodyB: p2.Body): void { let bullet: BossBullet = (bodyA.userData[emBodyType.BOSSBullet] ? bodyA : bodyB).userData["self"]; if (gameInfo.lastBossDeadScore != -1) return; if (gameInfo.player.CheckBuff(emItemType.Shield)) { gameInfo.RemoveBossBullets(bullet); } else { gameInfo.gameState = emGameState.GameOver; } return; } /** * 玩家与陷阱碰撞 */ private CheckCollisionDevilP2(bodyA: p2.Body, bodyB: p2.Body): void { let devil: Devil = (bodyA.userData[emBodyType.Devil] ? bodyA : bodyB).userData["self"]; devil.RemoveDevil(); if (!gameInfo.player.CheckBuff(emItemType.Shield)) { // 玩家沒有防护罩则游戏结束 gameInfo.gameState = emGameState.GameOver; } return; } /** * 子弹碰撞 */ private CheckCollisionBulletP2(bodyA: p2.Body, bodyB: p2.Body): void { if (bodyA.userData[emBodyType.Enemy] || bodyB.userData[emBodyType.Enemy]) { // 子弹和敌机碰撞 this.CheckCollisionEnemyP2(bodyA, bodyB); } else if (bodyA.userData[emBodyType.BOSS] || bodyB.userData[emBodyType.BOSS]) { // 子弹和BOSS碰撞 this.CheckCollisionBOSSP2(bodyA, bodyB); } else if (bodyA.userData[emBodyType.Coin] || bodyB.userData[emBodyType.Coin]) { // 子弹和金币碰撞 this.CheckCollisionCoinP2(bodyA, bodyB); } else if (bodyA.userData[emBodyType.Item] || bodyB.userData[emBodyType.Item]) { // 子弹和道具碰撞 this.CheckCollisionItemP2(bodyA, bodyB); } return; } ……
6、回收对象,也要记得移除对应的刚体!
if (body.userData && body.userData.skin) { skin = body.userData.skin; if (skin.parent != null) { //skin.parent.removeChild(skin); } body.userData = null; } this.world.removeBody(body);
上一篇:白鹭使用第三方扩展库
下一篇:在白鹭中使用P2物理引擎