简体   繁体   English

Java - 碰撞检测(故障)

[英]Java - Collision detection (glitch)

I am working on a platformer game for the final year project in HS.我正在为 HS 的最后一年项目开发一个平台游戏。 However... The collision detection system I use is basically about checking wether a specific part of the character intersects with another block or not.但是...我使用的碰撞检测系统基本上是关于检查角色的特定部分是否与另一个块相交。

The collision seems to be working fine except that it causes some bugs such as player kind of getting stuck or slowing down when hitting from the sides or gets thrown up when both upper and < or > keys are used.碰撞似乎工作正常,但它会导致一些错误,例如玩家在从侧面击球时卡住或减速,或者在使用上键和 < 或 > 键时被抛出。

My question is;我的问题是; How can I improve the collision code in order to avoid such glitches and have sort of 'slippery' collisions?如何改进碰撞代码以避免此类故障并产生某种“滑溜”碰撞?

This is the kind of collision effect that I am trying to achieve:这是我试图实现的那种碰撞效果:
( https://i.imgur.com/KB1M3bt.mp4 ) ( https://i.imgur.com/KB1M3bt.mp4 )
在此处输入图片说明

( https://i.imgur.com/I44fmPc.mp4 ) ( https://i.imgur.com/I44fmPc.mp4 ) 在此处输入图片说明

here is a preview of how the bounds look这是边界外观的预览

在此处输入图片说明


and here is a preview of what it actually looks like in game ( click for better quality )这是游戏中实际外观的预览(单击以获得更好的质量 在此处输入图片说明
The code i use for collision detection: (tempObject are blocks that the player is intersecting with)我用于碰撞检测的代码:(tempObject 是玩家与之相交的块)

if(getBoundsTop().intersects(tempObject.getBoundsBottom())){
    y = tempObject.getY() + height;
    velY = 0;
    System.out.println("Top collision");
}

if(getBoundsBottom().intersects(tempObject.getBoundsTop())){
    y = tempObject.getY() - height;
    velY = 0;
    falling = false;
    jumping = false;
    //isOnBlock = true;
} else {
    falling = true;
    //isOnBlock = false;
}

if(getBoundsRight().intersects(tempObject.getBoundsLeft())){
    x = tempObject.getX() - this.width;
}


if(getBoundsLeft().intersects(tempObject.getBoundsRight())){
    x = tempObject.getX() + this.width;
}

and here are the bound methods:这是绑定方法:

public Rectangle getBounds() { return new Rectangle( (int)x, (int)y, (int)width, (int)height ); }

    public Rectangle getBoundsTop() {
        return new Rectangle(
                (int)x, 
                (int)y, 
                (int)(width-(width*0.01f)), 
                (int)(height/2)
        );
    }
    public Rectangle getBoundsBottom() {
        return new Rectangle(
                (int)x,
                (int)(y+(height/2)),
                (int)(width-(width*0.01f)),
                (int)(height/2)
        );
    }

    public Rectangle getBoundsLeft() {
        return new Rectangle(
                (int)x,
                (int)y, 
                (int)((int)width*0.15f), 
                (int)height
        );
    }

    public Rectangle getBoundsRight() {
        return new Rectangle(
                (int) 
                ((int)x+(width-(width*0.15f))), 
                (int)y, 
                (int) ((int)width*0.15f), 
                (int)height
        );
    }

Edit: Im using a constant acceleration speed for setting velocity编辑:我使用恒定的加速度来设置速度

acc = 2.5f;
MAX_SPEED = 10;


if(Game.keyDownMap.containsKey(KeyEvent.VK_A)){

    setVelX(getVelX() - acc);
    if(getVelX() < -MAX_SPEED)
        setVelX(-MAX_SPEED);

} else if(Game.keyDownMap.containsKey(KeyEvent.VK_D)){

    setVelX(getVelX() + acc);
    if(getVelX() > MAX_SPEED)
        setVelX(MAX_SPEED);

}

When there's a sidewards collision, you want to set your sidewards velocity to zero.当发生侧向碰撞时,您希望将侧向速度设置为零。 That way there can only be a vertical velocity, which I assume will be setVelY();这样就只能有一个垂直速度,我假设它是 setVelY();

if(getBoundsRight().intersects(tempObject.getBoundsLeft())){
    x = tempObject.getX() - this.width;
    setVelX(0);
}


if(getBoundsLeft().intersects(tempObject.getBoundsRight())){
    x = tempObject.getX() + this.width;
    setVelX(0);
}

Also you need to check on key down if there's no collision status active.如果没有处于活动状态的碰撞状态,您还需要检查按键是否按下。 You'll probably want to make a method to set if it's currently intersecting with something which you update every gametick.您可能想要创建一个方法来设置它当前是否与您更新每个游戏单的东西相交。

if(Game.keyDownMap.containsKey(KeyEvent.VK_A) && !isIntersectingLeft()){

    setVelX(getVelX() - acc);
    if(getVelX() < -MAX_SPEED)
        setVelX(-MAX_SPEED);

} else if(Game.keyDownMap.containsKey(KeyEvent.VK_D) && !isIntersectingRight()){

    setVelX(getVelX() + acc);
    if(getVelX() > MAX_SPEED)
        setVelX(MAX_SPEED);

}

if you want a little bounce you could set a little velocity in the different direction.如果你想要一点弹跳,你可以在不同的方向设置一点速度。

if(getBoundsRight().intersects(tempObject.getBoundsLeft())){
    x = tempObject.getX() - this.width;
    if(this.getVelX() > 0) {
        setVelX(10);
    }
}


if(getBoundsLeft().intersects(tempObject.getBoundsRight())){
    x = tempObject.getX() + this.width;
    if(this.getVelX() > 0) {
       setVelX(-10);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM