【问题标题】:Low FPS in JavaJava中的低FPS
【发布时间】:2013-11-10 10:35:26
【问题描述】:

您好,我的名字是 Ryan,我目前正在开发自己的 2D java 游戏。目前,游戏世界中有很多对象。在游戏重新开始时,世界加载了 100 根随机放置在其上的树,这些树是使用数组列表和树类制作的。我的游戏使用一个名为checkcollisions 的类来检查玩家是否与任何树木相交。然后将此方法放入update 方法中。当不调用此方法时,我会获得额外的 100 FPS,我仍然可以获得这 100 fps 但仍检查碰撞吗?我真的需要提高 FPS,因为我的游戏目前以 30-50 fps 运行

这里是检查碰撞代码:

public void checkCollisions() {
    for (int i = 0; i < Placing_Objects.Small_Trees.size(); i++) {
        if (player.getBounds().intersects(Placing_Objects.getSmall_Tree().get(i).getBounds())) {
            if (gotAxeOn) {Placing_Objects.Small_Trees.get(i).health -= rand.nextInt(3);}
        }
        if (Placing_Objects.Small_Trees.get(i).health <= 0) {
            Placing_Objects.removeSmall_Tree(Placing_Objects.Small_Trees.get(i));
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Stick");
            Player.exp += rand.nextInt(3);
            challenges.choppedDownTrees += 1;
        }
    }
}

【问题讨论】:

  • 速度变慢可能是由 checkCollisions 函数中进行的任意数量的函数调用引起的。玩家调用的interests() 函数可能是罪魁祸首。
  • 在分析器中运行您的游戏。
  • @user2876115 分析器会告诉您每种方法使用了多少时间;让你找到瓶颈。大多数 IDE(例如 netbeans)都带有分析器

标签: java performance frame-rate


【解决方案1】:

仅检查与玩家附近的树木或当前可见矩形内的树木是否发生碰撞。要有效地执行此操作,请保存一组可见的对象并仅对其进行迭代。

【讨论】:

  • 如何在不使用 for 循环的情况下检查每棵树是否在可见矩形(相机)中?
  • 你必须这样做。这是你无法避免的。但是一旦你找到了可见的对象,你就可以在这些对象上执行所有你的游戏逻辑,而不是一切。如果您有很多对象,那将是一个重大改进。
  • 你能给我看一个代码示例吗,java 或pseudo 都可以
【解决方案2】:

正如威尔伯特所说,kd-tree 将是完美的解决方案。 对于包含大量非移动对象的简单 2d 游戏,您可以尝试更简单的方法:

首先,按照你已经完成的方式设置所有树:

将所有这些树保存在 ArrayList 中。

不要将您的游戏区域分成 x 个相同大小的矩形(例如 3x5=15)并检查哪个树与哪个区域相交。将这些计算保存在合适的数据结构中。例如:

HashMap<Rectangle, ArrayList<Tree>> fieldSperation;

树上的白色数字表示它们与哪个矩形相交。一棵树与多个矩形相交是可能的。然后你必须在两个或多个列表中保存一个引用(例如 6/7 或 7/12)。

最后你可以调整你的 checkCollisions() 方法如下:

public void checkCollisions() {
    // 1. check which Rectangle intersects with the player (can be a maximum of 4)
    for (Rectangle r : fieldSeperation.keySet()) {
         if (playerRect.intersect(r)) {
             // 2. do your collision detection with those trees which are intersecting with those
             // trees which are intersecting with the rectangles from 1.)
             for (List<Tree> ts : fieldSeperation.get(r)) {
                 // your old code here
             }
         }
     }
}

我很确定这种技术足以满足您的性能要求。

【讨论】:

  • 如果树动了我还能用这个方法吗
  • 如果一棵树移动,你必须重新计算它的相交矩形。因此,将其从包含它的所有列表中删除,然后将其添加到新的相应列表中。
【解决方案3】:

使用空间数据结构进行碰撞测试。有了这样的结构,可以大大减少测试次数。

两个简单而有效的二维结构是quadtreekd-tree

可以在here 找到一个与 Java 中 kd-tree 实现链接的相关问题。

【讨论】:

    【解决方案4】:

    不要在 Swing 事件调度线程中检查冲突。创建一个执行此操作的并发线程,事件线程只需将它们分配给它。通过最多只检查屏幕上的树木来减少检查碰撞的数量。

    【讨论】:

      【解决方案5】:

      我刚刚重新排列了代码,现在可以正常工作了!感谢所有提供帮助的人,我也很抱歉多次发布这个问题......我是新手,并不真正知道我在做什么。再次感谢您帮助有需要的开发人员的每个人!这是新代码:

      for (int i = 0; i < Placing_Objects.Small_Trees.size(); i++) {
              if (gotAxeOn) {
                  if (player.getBounds().intersects(Placing_Objects.getSmall_Tree().get(i).getBounds())) {
                      Placing_Objects.Small_Trees.get(i).health -= rand.nextInt(3);
                      }
              }
              if (Placing_Objects.Small_Trees.get(i).health <= 0) {
                  Placing_Objects.removeSmall_Tree(Placing_Objects.Small_Trees.get(i));
                  Inventory.addItemToInv("Wood");
                  Inventory.addItemToInv("Wood");
                  Inventory.addItemToInv("Stick");
                  Player.exp += rand.nextInt(3);
                  challenges.choppedDownTrees += 1;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2022-08-03
        • 2018-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多