Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am trying to fix the collision between my player and the tilemap that I am using to render my game. For whatever reason the collision is off when I start scrolling in the X-axis, the up and down collision doesn't really work at all with or without scrolling. The algorithm is supposed to take 2 points (the 2 points make a single side of the rectangle that represents the player) and then it checks to see if that side has made contact with a wall or not. I pasted the code below, any ideas?

public void checkCollisions() {
        int top, bottom;
        top = (int)(y + l.m.yOff) / l.getTileSize();
        bottom = (int)(y + l.m.yOff + h) / l.getTileSize();

        canLeft = l.m.getTile((int)(x + l.m.xOff) / l.getTileSize(), top) == 0 && 
                l.m.getTile((int)(x + l.m.xOff) / l.getTileSize(), bottom) == 0;

        canRight = l.m.getTile((int)(x + l.m.xOff + w) / l.getTileSize(), top) == 0 && 
                l.m.getTile((int)(x + l.m.xOff + w) / l.getTileSize(), bottom) == 0;

         canDown = l.m.getTile((int)(x + l.m.xOff) / l.getTileSize(), bottom) == 0 && 
                l.m.getTile((int)(x + l.m.xOff + w) / l.getTileSize(), bottom) == 0;

         canUp = l.m.getTile((int)(x + l.m.xOff) / l.getTileSize(), top) == 0 && 
                    l.m.getTile((int)(x + l.m.xOff + w) / l.getTileSize(), top) == 0;
}

The getTile method is defined as:

public int getTile(int x, int y){
        return map[y][x];
}

and my map is defined as a 2D int array with 40 elements each:

int[][] map = new int[40][40];

and the l.m.xOff and the l.m.yOff variables control the scrolling

EDIT

public void checkCollisions() {
    int top, bottom;
    top = (int)(y) / l.getTileSize() - (l.m.yOff / l.getTileSize());
    bottom = (int)(y + h) / l.getTileSize()- (l.m.yOff / l.getTileSize());

    canLeft = l.m.getTile((int)(x) / l.getTileSize() - (l.m.xOff / l.getTileSize()), top) == 0 && 
                    l.m.getTile((int)(x) / l.getTileSize() - (l.m.xOff / l.getTileSize()), bottom) == 0;

    canRight = l.m.getTile((int)(x + w) / l.getTileSize() - (l.m.xOff / l.getTileSize()), top) == 0 && 
            l.m.getTile((int)(x + w) / l.getTileSize() - (l.m.xOff / l.getTileSize()), bottom) == 0;

     canDown = l.m.getTile((int)(x - l.m.xOff) / l.getTileSize() - (l.m.xOff / l.getTileSize()), bottom) == 0 && 
            l.m.getTile((int)(x + w) / l.getTileSize() - (l.m.xOff / l.getTileSize()), bottom) == 0;

     canUp = l.m.getTile((int)(x) / l.getTileSize() - (l.m.xOff / l.getTileSize()), top) == 0 && 
                l.m.getTile((int)(x + w) / l.getTileSize() - (l.m.xOff / l.getTileSize()), top) == 0;
}

I divided the offsets by the tilesize because the getTile method returns the value of the 2D integer array and the offsets are much larger than the length of the arrays. (for example the xOffset at one point was in the 700's and there are only 40 tiles).

share|improve this question

closed as off-topic by Anko, congusbongus, Trevor Powell, Seth Battin, Byte56 Aug 22 at 14:40

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – Byte56
If this question can be reworded to fit the rules in the help center, please edit the question.

    
What does "doesn't work" mean? Could you draw it perhaps? –  Anko Jul 17 at 13:45

1 Answer 1

Problem 1:

It's possible you need to subtract your offsets from your coordinates rather than add them. This would explain why collision doesn't work when scrolling.

The correct operation (addition or subtraction) depends on how your offset is defined and used elsewhere.

If your player position is in world coordinates and the offset represents the position of your tile map in world coordinates, then the correct operation would be subtraction:

canLeft = l.m.getTile((int)(x - l.m.xOff) / l.getTileSize(), top) == 0 && 
                l.m.getTile((int)(x - l.m.xOff) / l.getTileSize(), bottom) == 0;

Problem 2:

Given your algorithm, moving into a wall horizontally will prevent you from moving up or down as well. This occurs because you are checking after moving to see whether or not you are embedded in a wall. If the lower-left corner of your player rectangle becomes embedded, you won't be able to move either left or down, even if the tiles below you are empty.

A more robust approach would be to first check to see whether the horizontal movement alone would cause a collision and then only allow enough movement to place your player adjacent to the wall, without overlapping it. You can then check the vertical movement and do the same.

This way, your player will never actually overlap a wall tile and horizontal collisions will not interfere with vertical collisions.

share|improve this answer
    
Thanks for the help, but it still doesn't work. I realize that there's a lot of code in my project and the problem might be somewhere else so I pasted the three most important classes for my project that deal with the scrolling on pastebin (the classes are separated by lines of comments) link. I also put the updated collision method that doesn't work in the post above. Thanks, once again! –  user2449865 Jul 18 at 9:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.