Push rectangle to where the collision happens?

Started by
0 comments, last by Kaptein 10 years, 9 months ago

Hi. I have a problem in tile collision. I am using Libgdx framework. I got the working tile collision base on their example the problem though is that is collision happens I cant move my sprite. For example if i have a collision in right side I cant move my sprite to move up or down :( Here is my code


 int startX, startY, endX, endY;
        float pushx = 0,pushy = 0;
        // move player
        if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
            dx=-1;
            currentWalk = leftWalk;

        }
        if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
            dx=1;
            currentWalk = rightWalk;

        }
        if(Gdx.input.isKeyPressed(Input.Keys.DOWN)){
            dy=-1;
            currentWalk = downWalk;
        }
        if(Gdx.input.isKeyPressed(Input.Keys.UP)){
            dy=1;
            currentWalk = upWalk;
        }



        sr.setProjectionMatrix(camera.combined);
        sr.begin(ShapeRenderer.ShapeType.Line);
        Rectangle koalaRect = rectPool.obtain();
        koalaRect.set(player.getX(), player.getY(), pw, ph /2 );

        float oldX = player.getX(), oldY = player.getY(); // THIS LINE WAS ADDED

        player.setXY(player.getX() + dx * Gdx.graphics.getDeltaTime() * 4f, player.getY() + dy * Gdx.graphics.getDeltaTime() * 4f); // THIS LINE WAS MOVED HERE FROM DOWN BELOW



            if(dx> 0) {
                startX = endX = (int)(player.getX() + pw);
            } else {
                startX = endX = (int)(player.getX()  );
            }
            startY = (int)(player.getY());
            endY = (int)(player.getY() + ph);
            getTiles(startX, startY, endX, endY, tiles);

            for(Rectangle tile: tiles) {
                sr.rect(tile.x,tile.y,tile.getWidth(),tile.getHeight());
                if(koalaRect.overlaps(tile)) {

                        //dx = 0;
                        player.setX(oldX); // THIS LINE CHANGED
                        Gdx.app.log("x","hit  " + player.getX() + " " + oldX);
                        break;
                    
                }
            }






            if(dy > 0) {
                startY = endY = (int)(player.getY() + ph );
            } else {
                startY = endY = (int)(player.getY() );
            }
            startX = (int)(player.getX());
            endX = (int)(player.getX() + pw);
            getTiles(startX, startY, endX, endY, tiles);

            for(Rectangle tile: tiles) {
                if(koalaRect.overlaps(tile)) {
                    //dy = 0;
                    player.setY(oldY); // THIS LINE CHANGED
                    //Gdx.app.log("y","hit" + player.getY() + " " + oldY);
                    break;
                }
            }


        sr.rect(koalaRect.x,koalaRect.y,koalaRect.getWidth(),koalaRect.getHeight() / 2);
        sr.setColor(Color.GREEN);
        sr.end();

The solution i think is to push back the sprite when collision happens, but i dont know how. pls help :( thanks

Advertisement

If I'm reading your code right then:

1. koalaRect is set to players original location

2. Player is then moved to new position: X + dx, Y + dy

3. If (koalaRect is overlapping something it shouldnt) move player back to old position

As you can see, you are testing collision using old player position before adding (dx, dy),

and that means that collisions only happen once the player is technically already stuck. smile.png

Move the line that sets the koalaRect to after setting new player position to immediately fix the problem,

or simply set koalaRect to player.X + dx, player.Y + dy, and only upon confirming the player won't be stuck there,

move the player.

Finally, it looks like you are trying to check player.X + dx and player.Y + dy independently, which is exactly what you want to do,

however, again koalaRect isn't updated, so the second collision check is the very same test you performed just lines before.

To run independent tests for dx and dy:

koalaRect.set(player.getX() + dx, player.getY(), pw, ph);

if (collisionTest(koalaRect) == false)

{

// (player.X + dx, player.Y) did not collide with anything

// move player on X-axis only:

player.X += dx;

}

koalaRect.set(player.getX(), player.getY() + dy, pw, ph);

if (collisionTest(koalaRect) == false)

{

// (player.X, player.Y + dy) did not collide with anything

// move player on Y-axis only:

player.Y += dy;

}

Hope this helps

This topic is closed to new replies.

Advertisement