Search code examples
javacollision-detection

Collision detected, but bugs - can get inside and not affected platforms move


Please, look at this GIF: enter image description here

Collision is detected properly, but those glitches annoy me... Rectangle is able to get inside another rectangle. When rectangles collides on x-axis (and right-left arrow is still presesd) one not affected is moving. Any ideas how can I get rid of them? keyPressed, keyReleased, move() and checkCollision() methods:

@Override
        public void keyPressed(KeyEvent k) {
                int key = k.getKeyCode();
                switch (key) {
                case KeyEvent.VK_LEFT:
                        left = true;
                        game.physic.xVel = 2;
                        break;
                case KeyEvent.VK_RIGHT:
                        right = true;
                        game.physic.xVel = 2;
                        break;
                case KeyEvent.VK_SPACE:
//jump
                        break;

                default:
                        break;
                }

        }
        /*
         * game.lvl1.getX()[i] to ablica z współrzędnymi platform
         */
        public void move() {
                if (left) {
                        switch (game.currentLevel()) {
                        case 1:
                                for (int i = 0; i < game.lvl1.getX().length; i++)
                                        game.lvl1.getX()[i] += game.physic.xVel;
                                break;

                        }
                } else if (right) {
                        switch (game.currentLevel()) {
                        case 1:
                                for (int i = 0; i < game.lvl1.getX().length; i++)
                                        game.lvl1.getX()[i] -= game.physic.xVel;
                                break;
                        }
                }
        }

        public void checkCollision() {
                switch (game.currentLevel()) {
                case 1:
                        for (int i = 0; i < game.lvl1.getX().length; i++) {
                                if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
                                        if (game.man.getBounds().getY() < game.lvl1.getBounds(i)
                                                        .getY() && !game.man.isOnGround) {
                                                /*
                                                 * collision above platform
                                                 */
                                                game.man.setyPos(-2);
                                                game.man.isOnGround = true;
                                                break;
                                        } else if (game.man.getBounds().getY() > game.lvl1
                                                        .getBounds(i).getY() && isJumping) {
                                                /*
                                                 * collision below 
                                                 */
                                                game.man.setyPos(2);
                                                game.man.isOnGround = false;
                                                break;
                                        } else if (game.man.getBounds().getX() < game.lvl1
                                                        .getBounds(i).getX() && right) {
                                                /*
                                                 * collision from left
                                                 */
                                                game.lvl1.getX()[i] += 2;
                                                right = false;
                                                break;
                                        } else if (game.man.getBounds().getX() > game.lvl1
                                                        .getBounds(i).getX() && left) {
                                                /*
                                                 * collision from right
                                                 */
                                                game.lvl1.getX()[i] -= 2;
                                                left = false;
                                                break;
                                        }

                                } else {
                                        game.physic.xVel = 2;
                                        game.man.isOnGround = false;
                                }
                        }
                }
        }

        @Override
        public void keyReleased(KeyEvent k) {
                int key = k.getKeyCode();
                switch (key) {
                case KeyEvent.VK_LEFT:
                        left = false;
                        game.physic.xVel = 0;
                        break;
                case KeyEvent.VK_RIGHT:
                        right = false;
                        game.physic.xVel = 0;
                        break;
                case KeyEvent.VK_SPACE:
                        break;
                default:
                        break;
                }
        }

paintLevel() is called from paintComponent. And paintComponent is called from gameloop.

private void paintLevel(Graphics2D g2d) {
    switch (currentLevel()) {
    case 1:
        for (int i = 0; i < lvl1.getX().length; i++) {
            g2d.draw(lvl1.getBounds(i));
        }
        break;
    }
}

Solution

  • I'm going to say that this is quite a bad way to do this. Each level should have a list of shapes and whenever your man moves you should check collision. Don't move if there was a collision, otherwise carry on with the position adjustment.

    Here's a basic edit of your current code that might make debugging easier: http://pastebin.com/Sz8gv863

    If you want, I can code up what I meant before, but you should be able to do it yourself. Consider what might happen to your code when you have 10 levels.