碰撞检测仅在物体的两个侧面工作。为什么?

发布于 2025-01-31 21:12:22 字数 4351 浏览 5 评论 0原文

我正在设计一个基本的2D平台游戏。我有一个玩家,他与WASD一起四处走动(还没有重力),我试图使他们无法遇到任何障碍。这是我的玩家类,正在管理运动:

public class Grogu {
    //Image
    public Image currentGroguImage;
    String which = "Default";
    int step = 0;
    int frames = 0;
    
    //Position
    int x,y;
    int w,h;
    
    float xSpeed,ySpeed;
    Input input;
    
    public Grogu(int x, int y) {
        this.x = x;
        this.y = y;
        input = new Input(1);
        xSpeed = 0;
        ySpeed = 0;
        
    }
    
    public void update() {  
        move();
    }
    
    public void render(Graphics g) {
        //g.drawString("" + collision, Main.getScreenWidth()/2, Main.getScreenHeight()/2);
        g.drawImage(currentGroguImage,x, y);
    }
    
    public void move() {    
        x+=xSpeed;
        y+=ySpeed;
    }
    
    public void keyPressed(int key, char c)
    {
        
        if(key == Input.KEY_A) {
            xSpeed = -7;
        }
        
        if(key == Input.KEY_D) {
            xSpeed = 7;
        }

        if(key == Input.KEY_W) {
            ySpeed = -7;
        }
        
        if(key == Input.KEY_S) {
            ySpeed = 7;
        }
        
        if(key == Input.KEY_D) {
            which = "Right";
        }
        else if(key == Input.KEY_A) {
            which = "Left";
        }
    }
    
    public void keyReleased(int key, char c) {
        if(key == Input.KEY_D || key == Input.KEY_A) {
            which = "Default";
        }
        if(key == Input.KEY_A) {
            xSpeed = 0;
        }
        
        if(key == Input.KEY_D) {
            xSpeed = 0;
        }
        
        if(key == Input.KEY_W) {
            ySpeed = 0;
            
        }
        
        if(key == Input.KEY_S) {
            ySpeed = 0;
        }
    }
    
    public Rectangle getBounds() {
        Rectangle r = new Rectangle(x - (int)xSpeed,y - (int)ySpeed,currentGroguImage.getWidth() + (int)xSpeed * 2,currentGroguImage.getHeight() + (int)ySpeed * 2);
        return r;
    }
    
    public void setX(int s) {
        x = s;
    }
    public void setY(int s) {
        y = s;
    }
    
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public float getXSpeed() {
        return xSpeed;
    }
    public float getYSpeed() {
        return ySpeed;
    }
    public int getWidth() {
        return currentGroguImage.getWidth();
    }
    public int getHeight() {
        return currentGroguImage.getHeight();
    }
}

这是阶段类(基本上是一个级别的超级类),我管理碰撞并在一个级别上渲染/更新所有内容:

public class Stage {
    public ArrayList<Obstacle> obstacles = new ArrayList<Obstacle>();
    public ArrayList<Enemy> enemies = new ArrayList<Enemy>();
    Grogu grogu;
    public Stage() {
        grogu = new Grogu(75,5*Main.getScreenHeight()/6 - Images.frontGrogu.getHeight()/2);
    }
    public void update() {
        checkCollisions();
        grogu.update();
        
    }
    
    public void render(Graphics g) {
        
        for(Obstacle o: obstacles) {
            o.render(g);
        }
        
        grogu.render(g);
    }
    
    public void keyPressed(int key, char c) {
        grogu.keyPressed(key, c);
    }
    
    public void keyReleased(int key, char c) {
        grogu.keyReleased(key, c);
    }
    
    private void checkCollisions() {
        for(Obstacle o: obstacles) {
            if(grogu.getBounds().intersects(o.getBounds())) {
                o.setR();
                if(grogu.getX() + grogu.getWidth() <= o.getX()) {
                    grogu.setX(grogu.getX() - (int)grogu.getXSpeed() - 1);
                }
                if(grogu.getX() > o.getX() + o.getWidth()) {
                    grogu.setX(grogu.getX() - (int)grogu.getXSpeed() + 1);
                }
                if(grogu.getY() + grogu.getHeight() <= o.getY()) {
                    grogu.setY(grogu.getY() - (int)grogu.getYSpeed() - 1);
                }
                if(grogu.getY() >= o.getY() + o.getHeight()) {
                    grogu.setY(grogu.getY() - (int)grogu.getYSpeed() + 1);
                }
                //return grogu.collision =true;
            }
        }
    }
}

出于某种原因,Grogu将碰撞并从对象中反弹当他在物体的左侧或顶侧与它们碰撞时。但是,尽管我的碰撞检测会注意到碰撞,但从底部或右侧,Grogu顺畅地通过对象移动(当Grogu与它们碰撞时,对象变红了)。任何帮助都将受到赞赏。

I am designing a basic 2D platformer. I have a player who moves around (no gravity yet) with WASD and I am attempting to make them not able to move through any obstacles. This is my player class which is managing the movement:

public class Grogu {
    //Image
    public Image currentGroguImage;
    String which = "Default";
    int step = 0;
    int frames = 0;
    
    //Position
    int x,y;
    int w,h;
    
    float xSpeed,ySpeed;
    Input input;
    
    public Grogu(int x, int y) {
        this.x = x;
        this.y = y;
        input = new Input(1);
        xSpeed = 0;
        ySpeed = 0;
        
    }
    
    public void update() {  
        move();
    }
    
    public void render(Graphics g) {
        //g.drawString("" + collision, Main.getScreenWidth()/2, Main.getScreenHeight()/2);
        g.drawImage(currentGroguImage,x, y);
    }
    
    public void move() {    
        x+=xSpeed;
        y+=ySpeed;
    }
    
    public void keyPressed(int key, char c)
    {
        
        if(key == Input.KEY_A) {
            xSpeed = -7;
        }
        
        if(key == Input.KEY_D) {
            xSpeed = 7;
        }

        if(key == Input.KEY_W) {
            ySpeed = -7;
        }
        
        if(key == Input.KEY_S) {
            ySpeed = 7;
        }
        
        if(key == Input.KEY_D) {
            which = "Right";
        }
        else if(key == Input.KEY_A) {
            which = "Left";
        }
    }
    
    public void keyReleased(int key, char c) {
        if(key == Input.KEY_D || key == Input.KEY_A) {
            which = "Default";
        }
        if(key == Input.KEY_A) {
            xSpeed = 0;
        }
        
        if(key == Input.KEY_D) {
            xSpeed = 0;
        }
        
        if(key == Input.KEY_W) {
            ySpeed = 0;
            
        }
        
        if(key == Input.KEY_S) {
            ySpeed = 0;
        }
    }
    
    public Rectangle getBounds() {
        Rectangle r = new Rectangle(x - (int)xSpeed,y - (int)ySpeed,currentGroguImage.getWidth() + (int)xSpeed * 2,currentGroguImage.getHeight() + (int)ySpeed * 2);
        return r;
    }
    
    public void setX(int s) {
        x = s;
    }
    public void setY(int s) {
        y = s;
    }
    
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public float getXSpeed() {
        return xSpeed;
    }
    public float getYSpeed() {
        return ySpeed;
    }
    public int getWidth() {
        return currentGroguImage.getWidth();
    }
    public int getHeight() {
        return currentGroguImage.getHeight();
    }
}

And here is the Stage class (basically a level super class), where I manage collisions and rendering/updating everything on a level:

public class Stage {
    public ArrayList<Obstacle> obstacles = new ArrayList<Obstacle>();
    public ArrayList<Enemy> enemies = new ArrayList<Enemy>();
    Grogu grogu;
    public Stage() {
        grogu = new Grogu(75,5*Main.getScreenHeight()/6 - Images.frontGrogu.getHeight()/2);
    }
    public void update() {
        checkCollisions();
        grogu.update();
        
    }
    
    public void render(Graphics g) {
        
        for(Obstacle o: obstacles) {
            o.render(g);
        }
        
        grogu.render(g);
    }
    
    public void keyPressed(int key, char c) {
        grogu.keyPressed(key, c);
    }
    
    public void keyReleased(int key, char c) {
        grogu.keyReleased(key, c);
    }
    
    private void checkCollisions() {
        for(Obstacle o: obstacles) {
            if(grogu.getBounds().intersects(o.getBounds())) {
                o.setR();
                if(grogu.getX() + grogu.getWidth() <= o.getX()) {
                    grogu.setX(grogu.getX() - (int)grogu.getXSpeed() - 1);
                }
                if(grogu.getX() > o.getX() + o.getWidth()) {
                    grogu.setX(grogu.getX() - (int)grogu.getXSpeed() + 1);
                }
                if(grogu.getY() + grogu.getHeight() <= o.getY()) {
                    grogu.setY(grogu.getY() - (int)grogu.getYSpeed() - 1);
                }
                if(grogu.getY() >= o.getY() + o.getHeight()) {
                    grogu.setY(grogu.getY() - (int)grogu.getYSpeed() + 1);
                }
                //return grogu.collision =true;
            }
        }
    }
}

For some reason, grogu will collide and bounce back from objects when he collides with them on the object's left side or top side. However, from the bottom side or right side, grogu moves through objects smoothly despite my collision detection noticing a collision (objects turn red when grogu collides with them). Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文