Slick2D 矩形碰撞检测

2023-12-14

我遇到一个问题,显示一个矩形与另一个矩形发生碰撞。所以我的问题是,如何获得相交方法来检查碰撞?或者说有其他方法来处理这种情况下的碰撞吗?

我正在创建一款回合制战斗游戏(类似于《最终幻想》或《龙骑兵传奇》),其中玩家的角色位于屏幕的右侧,敌人位于屏幕的左侧。玩家和敌人轮流攻击。因此,当玩家攻击时,精灵动画会从右向左在屏幕上移动,直到停在敌人面前,进行攻击,然后返回到其起始坐标。玩家和敌人周围都有一个矩形来代表每个角色的边界。

当玩家向前移动时,他会穿过敌人的矩形并停在其中。此时控制台应该输出“INTERSECT!”表明两个矩形之间发生了碰撞,但不幸的是没有。

请注意,我省略了类中不必要的代码片段,并尝试提供与我的问题相关的代码。

这是我的入口点,GameClass:

public class GameClass extends BasicGame{
//other variable declarations

public void init(GameContainer container) throws SlickException {
player = new Player();
enemy = new Enemy();
skeleton = new Skeleton();
enemy = skeleton;
playX = player.getStartX(); //700
playY = player.getStartY(); //140
playW = player.rect.getWidth(); //40
playH = player.rect.getHeight(); //70
enemyX = enemy.getStartX(); //100
enemyY = enemy.getStartY(); //140
enemyWidth = enemy.getWidth(); //50
enemyHeight = enemy.getHeight(); //55

SpriteSheet sheet = new SpriteSheet("data/homeranim.png", 36, 65);
    anim = new Animation();
    for (int i=0;i<8;i++) {
        anim.addFrame(sheet.getSprite(i,0), 150);
    }
}

public void render(GameContainer container, Graphics g)
        throws SlickException {
anim.draw(playX,playY); // draws player animation
skeletonAnim.draw(enemyX, enemyY); // draws enemy
g.draw(player.rect); //draws player bounds
g.draw(enemy.rect); //draws enemy bounds
}

public void update(GameContainer container, int delta)
        throws SlickException {
playerUpdate(delta);
if (player.rect.intersects(enemy.rect)) {
             System.out.println("INTERSECT!");

         System.out.println("Player minX: " + player.rect.getMinX());
         System.out.println("Player maxX: " + player.rect.getMaxX());
         System.out.println("Enemy minX: " + enemy.rect.getMinX());
         System.out.println("Enemy maxX: " + enemy.rect.getMaxX());
         }
      }

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;}
}
}

这是我的 Player 类的一瞥:

public class Player {

private int startX = 700;
private int startY = 140;
public Shape rect = new Rectangle(startX, startY, 40, 70);
//plus getters and setters
}

还有我的整个敌人班级:

public class Enemy {

private int startX, startY, width, height;
public Shape rect = new Rectangle(startX, startY, width, height);
// plus getters and setters
   }

我的 Skeleton 类扩展了 Enemy:

public class Skeleton extends Enemy {

public Skeleton() {
    // TODO Auto-generated constructor stub
    setMaxHealth(120);
    setStartX(100);
    setStartY(140);
    setWidth(50);
    setHeight(55);
}

}

注意:由于我已将 g.drawRect() 切换为 g.draw(),因此不会绘制敌方矩形。

起点处的矩形边界:http://i.imgur.com/QDDk858.png

碰撞的矩形边界应该是:http://i.imgur.com/pOANfvN.png

我希望我已经提供了足够的代码来向您展示我的问题是什么。我在互联网上翻找了几个小时,但没有成功。如果我需要提供任何其他代码,请随时询问。非常感谢您的帮助和支持!


您没有更新碰撞箱位置本身。

你正在画这个:

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 等之后放置完整的 {...};适当的行缩进,.

  • 思考 OO(面向对象)

这一点非常重要。您的敌人和玩家类都应该扩展某种实体类,因为他们都非常希望获得类似的行为(避免代码重复!)。将类似的行为总结为超类,通过一些可调整的参数简化要控制的行为等等。

例如,您将敌人和玩家的位置作为静态整数存储在主类中。这不是面向对象。将位置移动到实体类,您可以在其中以任何您希望的方式实现它。

  • 不要无缘无故地抛出异常

您的 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
 }

这应该可行,但您可能应该将所有这些属性移至敌人类并将它们放入构造函数中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Slick2D 矩形碰撞检测 的相关文章

随机推荐

  • 寻找 snprintf() 的 C 源代码

    我需要将 snprintf 移植到另一个不完全支持 GLibC 的平台 我正在 Glibc 2 14 源代码中寻找底层声明 我跟踪了许多函数调用 但卡在了 vfprintf 上 然后它似乎调用 IO vfprintf 但我找不到定义 宏可能
  • 具有当前用户 ID 的角色分配

    我使用 Azure AD 应用程序注册原则通过 Azure 资源管理器部署资源 以通过管道进行部署 在部署过程中 我需要为部署用户设置一些权限 以确保它有足够的权限 例如上传文件 由于我使用不同的原则 并且我没有在代码中管理这些原则 因此我
  • Visual Studio 2008 安装程序,自定义操作。断点未触发

    我有一个带有自定义操作项目的安装程序 我希望该操作在安装时触发 当我向事件日志写入内容时 该操作会触发 它运行得很好 但我确实需要调试该文件 因为操作非常复杂 所以我有以下安装程序类 namespace InstallerActions u
  • 使用 xpath 获取节点的第 N 个子节点

    我的示例输入 XML 是
  • 如何用编译时泛型验证替换运行时instanceof检查

    对于真正的 Java 泛型专家来说 有一个小难题 假设我有以下两个接口 interface Processor void process Foo foo interface Foo Processor getProcessor 例如 以下两
  • 对列进行排序并选择每组 pandas 数据框中的前 n 行

    我有一个像这样的数据框 mainid pidx pidy score 1 a b 2 1 a c 5 1 c a 7 1 c b 2 1 a e 8 2 x y 1 2 y z 3 2 z y 5 2 x w 12 2 x v 1 2 y
  • Intent不设置相机参数

    我正在打开相机应用程序作为我的应用程序的外部意图 我使用以下代码来调用相机 以下是我的条件 它应该打开前置摄像头 最高的图像质量 闪光灯必须打开 以下是我的代码 Intent action new Intent android media
  • JQplot 在 IE 上的打印问题

    我正在尝试打印我的图表 它可以通过 Firefox 和 Chrome 正确打印 但如果我尝试用 IE 打印它 它会向我显示图表后面的图表画布 HTML 标签 正如你在图片中看到的那样 并且它还将图表轴文本放置在整个图表上 我尝试了下面的解决
  • 如何在C#中处理枚举0(CA1008讨论)

    Rule CA1008指定所有枚举都应该有一个0应该命名的值Unknown 我们不在这里讨论标志 我理解您想要防止未初始化的值自动获得含义的原因 假设我定义以下枚举 enum Gender Male Female class Person
  • 在反应中从另一个钩子调用钩子

    我对反应还很陌生 并试图简化一些开发 我有这个自定义挂钩useApi import useState from react import PetsApiFactory from petstore axios api import useKe
  • 每次调用方法时创建对象的新实例

    Messenger Default Register
  • ASP.net - 按钮 - Javascript 确认对话框 - 执行一些服务器端代码?

    我有一个简单的 ASP net 页面 用户可以在其中编辑有关自己的信息 单击 编辑 按钮时 表单进入编辑模式 并显示 保存 和 取消 按钮 其行为符合预期 我想做的是这样的 单击 保存 后 将显示一个 Javascript 确认对话框 询问
  • 对“DTLS_client_method”的未定义引用

    我目前正在尝试在 android 上实现 DTLS 以加密 UDP 数据报 为此 我构建了 openssl android 项目可以在这里找到 由此我得到了两个共享库 libssl so 和 libcrypto so 我将它们重命名为 li
  • Boost是如何实现这样的语法的呢?

    http www boost org doc libs 1 58 0 doc html program options tutorial html Declare the supported options desc add options
  • 从字符串中提取图像 src

    我试图将所有图像元素匹配为字符串 这是我的正则表达式 html match
  • 将闪亮与facet_grid结合起来

    我正在开展一个学校项目 其中有一些 dyplr 查询 我需要使用 Shiny 库使它们交互 现在我在 dyplr 中有一个查询 在那里我可以看到印度外卖餐厅每个国家的收入 我有以下查询 df gt group by Origin Jaar
  • Node 提供的 ejs 文件可以使用离线引导吗?

    我是节点和全栈开发的新手 希望我正确地提出这个问题 而不是粗心或冒犯您的特定理解水平 我的开发环境已连接互联网 但生产环境不会连接 我想将 bootstrap css 与节点一起使用 Apache httpd 不是生产环境中的一个选项 本地
  • 使用 MySQL Connector for .net 打开 MySQL 连接非常慢

    我正在尝试解决使用 MySQL Connector for net 打开连接时 MySQL 响应时间过长的问题 我已经使用 skip name resolve 安装了在 Azure VM Server 2008 上运行的 MySQL 5 5
  • 查找每个部门的最高薪水 - 是否有更有效的查询?

    我有一个有效的查询 但我怀疑我这样做效率低下 是否有更优雅的方法来查找每个部门的最高薪水以及赚取该薪水的员工 我正在做一个 cte 来查找每个部门 ID 的最高工资 然后通过匹配工资和部门 ID 将其与员工数据结合起来 我有下面的代码来构建
  • Slick2D 矩形碰撞检测

    我遇到一个问题 显示一个矩形与另一个矩形发生碰撞 所以我的问题是 如何获得相交方法来检查碰撞 或者说有其他方法来处理这种情况下的碰撞吗 我正在创建一款回合制战斗游戏 类似于 最终幻想 或 龙骑兵传奇 其中玩家的角色位于屏幕的右侧 敌人位于屏