我正在尝试创造一款游戏,我有一个玩家和一个带有墙壁和障碍的平铺地图,玩家可以向上,向右,向下,向左移动,我希望玩家不要穿过墙壁或障碍。
我使用了扑动火焰的碰撞系统来实现这个,但是我有一个bug,它杀死了我,让我用一个例子来解释这个bug
让我们假设玩家向上并与一堵墙相撞,那么玩家便不能再向上移动了但如果他一直与上边缘碰撞并开始向左或向右移动当他到达边缘时他将穿过左边或右边的墙壁
class Player extends SpriteComponent
with CollisionCallbacks, HasGameRef<MobArena> {
final MovementJoystick joystick;
bool collided = false;
double speed = 50;
JoystickDirection collidedDirection = JoystickDirection.idle;
Player({required this.joystick}) : super(size: Vector2.all(16));
@override
Future<void> onLoad() async {
await super.onLoad();
add(RectangleHitbox());
}
@override
void update(double dt) {
super.update(dt);
if (!joystick.relativeDelta.isZero()) {
switch (joystick.direction) {
case JoystickDirection.up:
if (collided && collidedDirection == JoystickDirection.up) {
break;
}
position.y += (joystick.relativeDelta * speed * dt)[1];
break;
case JoystickDirection.right:
if (collided && collidedDirection == JoystickDirection.right) {
break;
}
position.x += (joystick.relativeDelta * speed * dt)[0];
break;
case JoystickDirection.down:
if (collided && collidedDirection == JoystickDirection.down) {
break;
}
position.y += (joystick.relativeDelta * speed * dt)[1];
break;
case JoystickDirection.left:
if (collided && collidedDirection == JoystickDirection.left) {
break;
}
position.x += (joystick.relativeDelta * speed * dt)[0];
break;
}
}
}
@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
super.onCollision(intersectionPoints, other);
if (other is Obstacle && !collided) {
collided = true;
collidedDirection = joystick.direction;
}
}
@override
void onCollisionEnd(PositionComponent other) {
super.onCollisionEnd(other);
collidedDirection = JoystickDirection.idle;
collided = false;
}
}
如果你想使用这种类型的检查,你将不得不有一个碰撞方向的列表,而不是只有一个,因为它可以在同一时间从多个方向碰撞。
在onCollsionEnd
中,你还必须从列表中删除它不再与之冲突的方向。
为了使它更有效,你可以使用onCollisionStart
而不是onCollision
来检查当你开始与新墙碰撞时。