您没有更新碰撞箱位置本身。
你正在画这个:
g.drawRect(playX, playY, playW, playH); //draws player bounds
g.drawRect(enemyX, enemyY, enemyW, enemyH); //draws enemy bounds
但这不是实际的碰撞箱,它只是玩家/敌人的位置,这里绘制的矩形将位于正确的位置,而碰撞箱本身则不然。
我建议您执行以下操作:
public void update(GameContainer container, int delta)
{
playerUpdate(delta);
player.rect.setLocation(playX, playY);
enemy.rect.setLocation(enemyX, enemyY); // update the hitboxes to the new positions
if (player.rect.intersects(enemy.rect))
{
System.out.println("INTERSECT!");
}
}
public void playerUpdate(int delta)
{
if (playerForward == true)
{
playX -= delta * 0.4f;
if (playX <= 140)
{
playX = 140;
playerForward = false;
playerBackward = true;
}
}
if (playerBackward == true)
{
playX += delta * 0.4f;
if (playX >= 700)
{
playX = 700;
playerBackward = false;
delay = 1250;
}
}
}
public void keyReleased(int key, char c)
{
if (key == Input.KEY_ENTER)
{
playerForward = true;
}
}
此外,由于您似乎是 Java 游戏开发新手,因此给您一些提示:
始终在 if、else、switch、while、for 等之后放置完整的 {...};适当的行缩进,.
这一点非常重要。您的敌人和玩家类都应该扩展某种实体类,因为他们都非常希望获得类似的行为(避免代码重复!)。将类似的行为总结为超类,通过一些可调整的参数简化要控制的行为等等。
例如,您将敌人和玩家的位置作为静态整数存储在主类中。这不是面向对象。将位置移动到实体类,您可以在其中以任何您希望的方式实现它。
您的 update(...) 方法会抛出 SlickException,即使它从不需要。
这是很多初学者都会做的事情:只需获取一些参数,将它们作为私有(甚至可能是公共)放在一个类中,并为它们生成 getter 和 setter。这是not封装。这几乎和一开始就将它们公开一样糟糕。
但我们为什么不把一切都公开呢?
我们不希望任何人(甚至我们自己)依赖某些恰好存在的参数,因为我们稍后可能想要更改一些非常具体的实现。不要只是将所有可能的值放在那里进行更改,封装的意义是独立于我们最终使用的实现类型,并通过保护可以设置/更改的内容来保护代码的可用性。
对于任何类型的软件,这是您应该注意的方面之一,但您通常可以在游戏中最明显地看到后果。性能很重要!我的意思并不是说您必须注意每一个细节,而是要牢记如何改进和加强代码的概述,尤其是经常调用的方法,例如 update(..) 和在 Slick2D 中渲染(..)。
Update
作为评论中讨论的另一个问题的解决方案:
public class Enemy {
private int startX, startY, width, height;
public Shape rect = new Rectangle(startX, startY, width, height);
// plus getters and setters
}
宽度和高度只能为 0,因为它们从未被分配为默认值为 0 的整数,因此敌方矩形碰撞箱的宽度确实为 0,并且永远不会触发。
尝试类似的方法:
public class Enemy {
private int startX, startY, width = 50, height = 70;
public Shape rect = new Rectangle(startX, startY, width, height);
// plus getters and setters
}
这应该可行,但您可能应该将所有这些属性移至敌人类并将它们放入构造函数中。