Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java互动游戏-碰撞检测_Java_Collision Detection_Tile - Fatal编程技术网

Java互动游戏-碰撞检测

Java互动游戏-碰撞检测,java,collision-detection,tile,Java,Collision Detection,Tile,我正在用瓷砖制作一个java游戏。我的碰撞元素有问题。我为地图上的每个瓷砖定义矩形,为玩家定义另一个矩形。我遇到的问题是,当玩家击中矩形时,我不知道玩家来自哪一侧,然后按玩家来自的方向将玩家推开。我已经做了一个方法来检查矩形中有多少字符,这样它就可以知道有多少字符被推出,但我不知道如何辨别字符来自哪一侧 这是我当前的碰撞方法-注意rect1是字符,rect2是平铺 public void collision(Rectangle rect1, Rectangle rect2) { floa

我正在用瓷砖制作一个java游戏。我的碰撞元素有问题。我为地图上的每个瓷砖定义矩形,为玩家定义另一个矩形。我遇到的问题是,当玩家击中矩形时,我不知道玩家来自哪一侧,然后按玩家来自的方向将玩家推开。我已经做了一个方法来检查矩形中有多少字符,这样它就可以知道有多少字符被推出,但我不知道如何辨别字符来自哪一侧

这是我当前的碰撞方法-注意rect1是字符,rect2是平铺

public void collision(Rectangle rect1, Rectangle rect2) {
    float xAdd;
    float xAdd2;
    float yAdd;
    float yAdd2;

    boolean hitRight = false;
    boolean hitLeft = false;
    boolean hitTop = false;
    boolean hitBot = false;

    Vector2f rect1Origin = new Vector2f(rect1.x, rect1.y);
    Vector2f rect2Origin = new Vector2f(rect2.x, rect2.y);
    Vector2f rect1Mid = new Vector2f((rect1.x + rect1.width) / 2,(rect1.y + rect1.height) / 2);
    Vector2f rect2Mid = new Vector2f((rect2.x + rect2.width) / 2,(rect2.y + rect2.height) / 2);

    Vector2f rect1A = new Vector2f(rect1Origin.x + rect1.width, rect1.y);
    Vector2f rect1B = new Vector2f(rect1Origin.x, rect1Origin.y+ rect1.height);
    Vector2f rect1C = new Vector2f(rect1Origin.x + rect1.width,rect1Origin.y + rect1.height);

    Vector2f rect2A = new Vector2f(rect2Origin.x + rect2.width, rect2.y);
    Vector2f rect2B = new Vector2f(rect2Origin.x, rect2Origin.y
            + rect2.height);
    Vector2f rect2C = new Vector2f(rect2Origin.x + rect2.width,
            rect2Origin.y + rect2.height);

    xAdd = rect2C.x - rect1B.x;
    xAdd2 = rect1C.x - rect2B.x;

    yAdd = rect2A.y - rect1B.y;
    yAdd2 = rect2C.y - rect1A.y;


    if (rect1Mid.y < rect2Mid.y) {
        if (rect1.intersects(rect2)) {
            y_pos += yAdd;
        }
    }
    if (rect1Mid.y > rect2Mid.y) {
        if (rect1.intersects(rect2)) {
            System.out.println(yAdd2);
            y_pos += yAdd2;
        }

    }
    if(rect1Mid.x > rect2Mid.x){
        if(rect1.intersects(rect2)){
            hitRight = true; x_pos += xAdd;
        }
    } 
    if(rect1Mid.x< rect2Mid.x){ 
          if(rect1.intersects(rect2)) {
              x_pos += -xAdd2;
          } 
    }
}
public void冲突(矩形rect1,矩形rect2){
浮动xAdd;
浮动xAdd2;
浮动yAdd;
浮动yAdd2;
布尔hitRight=false;
布尔hitLeft=false;
布尔hitTop=false;
布尔hitBot=false;
Vector2f rect1Origin=新的Vector2f(rect1.x,rect1.y);
Vector2f rect2Origin=新的Vector2f(rect2.x,rect2.y);
Vector2f rect1Mid=新的Vector2f((rect1.x+rect1.width)/2,(rect1.y+rect1.height)/2);
Vector2f rect2Mid=新的Vector2f((rect2.x+rect2.width)/2,(rect2.y+rect2.height)/2);
Vector2f rect1A=新的Vector2f(rect1Origin.x+rect1.width,rect1.y);
Vector2f rect1B=新的Vector2f(rect1Origin.x,rect1Origin.y+rect1.height);
Vector2f rect1C=新的Vector2f(rect1Origin.x+rect1.width,rect1Origin.y+rect1.height);
Vector2f rect2A=新的Vector2f(rect2Origin.x+rect2.width,rect2.y);
Vector2f rect2B=新的Vector2f(rect2Origin.x,rect2Origin.y
+(2)高度);
Vector2f rect2C=新的Vector2f(rect2Origin.x+rect2.width,
rect2Origin.y+rect2.height);
xAdd=rect2C.x-rect1B.x;
xAdd2=rect1C.x-rect2B.x;
yAdd=rect2A.y-rect1B.y;
yAdd2=rect2C.y-rect1A.y;
if(rect1Mid.yrect2Mid.y){
if(rect1.相交(rect2)){
系统输出println(yAdd2);
y_pos+=yAdd2;
}
}
if(rect1Mid.x>rect2Mid.x){
if(rect1.相交(rect2)){
hitRight=true;x_pos+=xAdd;
}
} 
如果(rect1Mid.x
任何帮助都将不胜感激


谢谢

为角色保留两个位置-角色所在的位置(从最后一帧开始,移动等),以及要移动角色的位置。然后,只有在未检测到冲突时才移动它-如果不允许损坏状态,则不必修复它

编辑:碰撞方法应为
布尔方法
-应在实际移动角色之前执行,如

if (!collision(character, tile))
{
    doMove(character);
}
else
{
    //custom handling if required
}
Edit2:上一步只适用于一小步,如果您需要部分移动,您确实需要知道角色的原始位置,如
移动(原始位置,desiredPosition,tile)
,您可以从
原始位置
平铺
推断方向

主要的一点是,在获得角色的有效位置之前,您不会实际移动角色。

首先,任何精灵(此处的角色和平铺)都应该有四个成员:xPos、YPO、xVec、yVec。记住这一点,你就知道角色在哪里,并且将在下一帧中出现

sprite.xPos += sprite.xVec;
sprite.yPos += sprite.yVec;
再看一下您的代码,您应该改进命题(例如,在四个if语句中检查if(rect1.intersects(rect2))。相反,只检查一次intersects(),并对每个可能的情况(左、右、上、下击)进行内部检查


最后,碰撞方法应该接收2个精灵对象(例如,精灵1和精灵2),然后检查intersects()方法,同时考虑精灵及其向量的原始位置。如果精灵在新位置相交,则相应地反转对象的向量。

假设可以检测到与代码的碰撞。以下是确定角色相对于矩形对象的位置的方法

  • 找到矩形的中点。(Rx,Ry)

  • 找到你的角色精灵的中点。(Sx,Sy)

  • 现在您可以比较Rx、Ry、Sx、Sy,以确定Rx和Ry的哪一侧是Sx和Sy

  • 例如:

    if Sx < Rx then
      Sx = left side of Rx
    
    如果Sx

  • 我自己也在努力解决这个问题,但是经过一些思考,这个检查可以通过将所有实体都放在一个列表中来完成,在我的代码中,我不得不阻止玩家通过块移动。所有块都在一个列表中。现在,当检查玩家的位置时,我创建一个新的矩形,并将玩家的位置向前放置一帧,在下一帧更新发生的方向上,如果矩形与该方向的更新相交,则不会发生。这是我的代码:

        if (isKeyPressed(KeyEvent.VK_LEFT)) {
            if(!collisionWithBlocks(1)){
                pl.x = pl.x - updatePlayerPosition;
            }
        }
        if (isKeyPressed(KeyEvent.VK_RIGHT)) {
            if(!collisionWithBlocks(0)){
                pl.x = pl.x + updatePlayerPosition;
            }
        }
        if (isKeyPressed(KeyEvent.VK_UP)) {
            if(!collisionWithBlocks(3)){
                pl.y = pl.y - updatePlayerPosition;
            }
        }
        if (isKeyPressed(KeyEvent.VK_DOWN)) {
            if(!collisionWithBlocks(2)){
                pl.y = pl.y + updatePlayerPosition;
            }
        }
    
    collisionWithBlocks():

    updatePlayerPosition为2,我的代码中有更改,但这已经足够了。
    在您的情况下,我建议将实体放入一个列表中,然后像我之前那样进行检查。

    这将导致奇怪的情况,具体取决于时间步长。@Matzi不是真的,在执行某个用户命令之前进行验证-如果不进行验证,你可以做定制处理。@KirilRaychev我真的不明白你想做什么say@grimrader22我试着说得更清楚些,请问它是否还不够好。@KirilRaychev从个人经验来看,不是这样的。:)如果步长很小,它可以有小的evvect,但问题是存在的。xVec和yVec变量代表什么?很抱歉,我不太清楚,这些是精灵的方向向量(也可以使用Vector2f或Point2D)。该值可以被解释
    public boolean collisionWithBlocks(int side){
        for(Block b : main.blocks){
            Rectangle block = b.getBounds();
            Rectangle player = null;
            if(side == 0){
                player = new Rectangle(pl.x + updatePlayerPosition, pl.y, pl.getWidth(), pl.getHeight());
            } else if(side == 1){
                player = new Rectangle(pl.x - updatePlayerPosition, pl.y, pl.getWidth(), pl.getHeight());
            } else if(side == 2){
                player = new Rectangle(pl.x, pl.y + updatePlayerPosition, pl.getWidth(), pl.getHeight());
            } else if(side == 3){
                player = new Rectangle(pl.x, pl.y - updatePlayerPosition, pl.getWidth(), pl.getHeight());
            }
    
            if(player.intersects(block)){
                return true;
            }
        }
    
        return false;
    }