Collision Detection only working on two sides of an Object. Why?

28 views Asked by At

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.

0

There are 0 answers