本週的目标是要让横向卷轴中的角色可以左右移动及跳跃, 在没有碰到场景物件时自由落体, 碰到墙壁时被阻挡在墙的一侧。
在限定所有物件的形状都是没有对座标轴旋转的长方体时,可以使用简单的AABB碰撞盒来检测是否碰撞
private boolean isCollision(GameObj obj) { if (this.left() > obj.right()) return false; if (this.right() < obj.left()) return false; if (this.top() > rect.bottom()) return false; if (this.bottom() < rect.top()) return false; return true; }
为了让角色有越掉越快, 需要让角色的速度每次更新一个定值
private void update(){ velocity.offsetY(Gravity) // y 轴速度每次增加 offsetX = velocity(x); offsetY = velocity(y)}
为了让角色合理的被场景物件阻挡, 要和场景物件判定碰撞, 并因碰撞结果设定角色位置和归零速度
原本的AABB碰撞仅依据物件的位置获得是否碰撞的结果,
因此需要知道物件的速度, 才会知道是与场景的哪个边碰撞,
再者, 因为与顶点接触时会判定为碰撞, 将使角色在行走在互相连接的下一块底板时,
无法判定与下一块地板的顶点碰撞是"墙壁或地板", 因此将角色碰撞后的位置设定在地板的上缘之上(1 单位)
actor.update(); for (int i = 0; i < gameObjects.size(); i++) { GameObject obj = gameObjects.get(i); if (actor.isCollision(obj)) { actor.preMove(); actor.moveY(); if (actor.isCollision(obj)) { // 撞到 Y actor.jumpReset(); if (actor.velocity().y() < 0) { actor.setY(obj.collider().bottom() +1 ); actor.velocity().stopY(); } else if (actor.velocity().y() > 0) { actor.setY(obj.collider().top() - actor.painter().height() -1); actor.velocity().stopY(); } actor.moveX(); } if (actor.collider().bottom() == obj.collider().top() | actor.collider().top() == obj.collider().bottom()) { actor.moveX(); } } }