【问题标题】:Java 2D collision response methodJava 2D 碰撞响应方法
【发布时间】:2014-03-22 00:36:09
【问题描述】:

最近,我一直在玩基本的 2D Java 游戏编程,并且在自己发现事物时获得了很多乐趣,但我遇到了一个问题。我创建了一个简单的碰撞方法,但它非常有问题。所以我的问题是当玩家与块碰撞时如何改变玩家的 x 和 y。我已经尝试了下面的代码,它可以识别玩家何时发生碰撞,但它没有将他的 x 和 y 设置为 x 并将 y 设置为 tempx 和 y。代码:

private void update(){
    tempx = player.getX(); 
    tempy = player.getY();
    collided = checkCollision();
    if(collided == false){
        player.update();
    }
    else if(collided){
        player.setX((int)tempx);
        player.setY((int)tempy);
        System.out.println("COLLIDED");
    }
}

private boolean checkCollision(){
    for(int i = 0; i < tiles.size(); i++){
        Tile t = tiles.get(i);
        Rectangle tr = t.getBounds();
        if(tr.intersects(player.getBounds())){
            return tr.intersects(getBounds());
        }
    }
    return false;
}

正在检测到碰撞,但玩家 x 和 y 没有相应地更改。如果您需要更多代码或有任何问题,请提出。感谢您的帮助:)

附:我试过增加重力,如果有帮助的话,碰撞只适用于块的顶部

下面是 player.update() 方法:

@Override
public void keyPressed(KeyEvent e){
    int k = e.getKeyCode();
    if(k != 0){
        if(k == KeyEvent.VK_W){
            y -= vy;
        }
        else if(k == KeyEvent.VK_A){
            x -= vx;
        }
        else if(k == KeyEvent.VK_S){
            y += vy;
        }
        else if(k == KeyEvent.VK_D){
            x += vx;
        }
    }
}
public void update(){

}

【问题讨论】:

  • tempx 和 tempy 不是玩家原始的 x 和 y 坐标吗?那么当调用 player.setX((int)tempx) 和 player.setY((int)tempy) 时,不只是设置原始坐标吗?

标签: java 2d collision-detection collision


【解决方案1】:

问题似乎出在您的更新方法中。

private void update(){
    tempx = player.getX(); // tempx now is the same as the players x location
    tempy = player.getY();
    collided = checkCollision();
    if(collided == false){
        player.update();
    }
    else if(collided){
        player.setX((int)tempx);  // you set players location equal to temp, which is 
        player.setY((int)tempy);  // already the players location
        System.out.println("COLLIDED");
    }
}

由于您将玩家位置设置为与其当前所在的位置相同,因此您根本不会看到角色移动到任何地方。您可能想要更改 tempxtempy 的值

tempx = player.getX() + 10; 
tempy = player.getY() + 10;

更新

更新过程的工作方式似乎有些混乱。

考虑以下几点:

  • 字符从 (0,0) 开始
  • 在 (2,2) chich 的某个对象会导致碰撞

鉴于上述情况,您的更新方法和按此顺序会发生以下情况

  • tempx = player.getX() 两个 x 现在都是 0
  • tempy = player.getY() 现在两个 y 都是 0
  • 检查碰撞,没有
  • 由于没有碰撞,播放器已更新。 (我假设 update 方法移动了字符 (+1,+1)。所以字符现在位于位置 (1,1)。
  • tempx 和 tempy 再次设置为 getX 和 getY。 X 和 Y 现在都是 1。现在 tempx 和 tempy 也是 1
  • 没有冲突,所以角色被更新(移动)到(2,2)
  • tempx 和 tempy 设置为 getX 和 getY。 X 和 Y 现在都是 2,所以 tempx 和 tempy 也是 2。
  • 检查碰撞,确实有一个在 (2,2)
  • 因为发生了碰撞,所以您将角色“移动”到 tempx 和 tempy,但 tempx 和 tempy 与 character.getX 和 character.getY 的值相同。

如果您希望它们在整个角色更新动作中保持不变,您必须将 tempxtempy 设置为等于更新循环之外的角色位置。

【讨论】:

  • 是的,这就是我想要发生的事情。它设置 tempx 或 x 原来的样子,这样如果它不碰撞它就可以改变玩家的位置。但如果确实发生碰撞,则会将玩家位置重置为更新前的位置
  • @user2280906 但是update() 方法可能每秒被调用数百次。每次调用 update() 方法时,它都会获取玩家的新当前位置并将其设置为 tempx。在任何给定点 tempx 都将与 player.getX(); 相同
  • @user2280906 所以如果没有碰撞,它会更新玩家的位置。下一次将 tempx 和 tempy 的值重置为播放器的新位置,然后再次检查是否存在碰撞。如果有这个时间,那么它将player的当前值设置为tempx和tempy,仍然是player.getX()player.getY();的当前值
  • 你一直到最后都是对的。如果发生碰撞,它会将玩家位置重置为移动之前的位置。他实际移动的地方在 player.update();
  • tempx 和 tempy 是玩家移动之前的状态,因此如果发生碰撞,它可以将 x 和 y 设置为玩家移动之前的状态。顺便说一句,感谢您提供的所有帮助,感谢您抽出宝贵时间与我一起尝试解决这个问题。
猜你喜欢
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2013-07-18
相关资源
最近更新 更多