Gornova/MarteEngine

Collision detection problems (0.2)

Closed this issue · 8 comments

I had recently started messing around with Slick and MarteEngine for its simple collision system, and I had followed the collision tutorial on the MarteEngine wiki. Once I got the just of it I tried to mess around with it but I found that for some reason my player would stop at some points of the screen for seemingly no reason. I have the debug mode on and its not colliding with any entities, and sometimes even when it does it fails and I can go right through walls. So I created a debug boolean that was triggered when a collision occurred, and its going off for no reason where no entities are present and thus stopping the player from moving in seemingly empty space.

I am pretty sure I did everything right. I even peeked at the source for the engine and still couldn’t find out what was happening. Even though my knowledge of Java is limited :/. I have put a link to my source down below and I hope someone would be kind enough to take a look at it. Its pretty simple but I just cant figure it out :/. Thanks in advance, any help would be greatly appreciated.

https://dl.dropbox.com/u/9159394/Level_Prototype.zip

Hello False.

I've gone over your code and it all looks straight forward. I compiled it and gave it a try. I couldn't duplicate the player getting stuck in an of the empty (or "Air" spaces as they are in your code). That only instance of getting stuck is with the bottom wall. It seems that your collision code is only working half-way. The player is able to pass through your wall entitles from the Y axis.

So if the player goes down into the bottom wall then goes left or right they get stopped. Your collision code is okay though. If I understand correctly your collision code is going like this

if(check("RIGHT"))   // If user presses RIGHT
        {
            if (collide("BASICWALL", x + 10, y)==null) // And is the player doesn't encounter a wall
            {
                x = x + 10; // Move 10 pixels to the right
                collided = false; // the collided boolean is marked as false
            }
            else
            {
                x = last_Position_X; // x stays as it was before
                y = last_Position_Y; // y stays as it was before
                collided = true; // collided boolean is marked as true
            }
        }

I don;'t really know the solution to this problem. The way you check for collision is kinda different but it works in some aspects. I'm not sure if this helped, but I hope it helped you understand.

Thanks for taking a look! I didn’t expect anyone to give it a shot. Please re download the archive. I have replaced the grassmap.tmx file with one that actually has entities placed around the centre of the map. These seem to stop me. I have also added a small collision debug boolean, which goes off whenever a collision occurs. As you can see it blocks me in empty spaces. Also if you press 1 you can see the entities that the player is obviously not colliding with lol.

If you would like a faster demonstration I have recorded a short video displaying the problem:
https://dl.dropbox.com/u/9159394/out-2.ogv

Hmmmm. The .zip didn't add anything new for me so I just went ahead and added some wall entities to the middle and you're correct. It's certainly odd to say the least. My best guess is the parsing/level building. It seems to be adding "phantom" wall entities. If it's not that, then it's the collision code releasing false flags. :/ It's certainly unusual.

Thank you for taking a look. I really have no idea why this is occurring. I suppose I will just have to do my own collision :/.

hi falsechicken (nice nickname :P).
I've downloaded your code and levelbuilder seems good (free tip: don't use static stuff if you don't need it, you can always use a method levelBuilder.build("...level.tmx") that return and array of entities to add to your world), anyway!

Your collision problem is when you check for collision, because you mess with input checking and collision stuff and lastpositions.

First a working update method (from your sorce code):

@Override
public void update(GameContainer container, int delta)
        throws SlickException {
    super.update(container, delta);

    int dx = 0;
    int dy = 0;
    if(check("RIGHT")){
        dx = 1;
    } else if(check("LEFT")){
        dx = -1;
    }
    if(check("UP")){
        dy = -1;
    } else if(check("DOWN")){
        dy = 1;
    }
            // 5 = your player speed
    if (collide("BASICWALL",x+dx*5, y+dy*5)==null){
        last_Position_X = x;
        last_Position_Y = y;

        x += dx * 5;
        y += dy * 5;
        debug_collision = false;
    } else {
        debug_collision = true;
    }
    }

What I'm doing here?

  1. check from input: left and right then up and down, so you can have diagonal movement. 0 means no input on axis, so dx = -1 mean move left and so on. Now you have player movement, so you can check collisions!

  2. check fro collisions: you search collision on type "BASICWALL", but you can check for collision when player will be after movements. So if your player speed is 5 (for example), just check in that direction. If is safe to move, move!,

  3. movement: you can move because no collision here, so save lastPosition (you do so in your example, but you don't need last position) and move

You can certainly do all together, but if you divide a problem in smaller parts, it's more easy

I hope this could help you!

Wow thanks Gornova! I didn't expect you to chime in xD. Thanks to you its working great! Which is good because implementing my own collision was giving me a headache lol.

Thanks for helping out Gornova. :)

you are welcome! :D