Tile based map and collision; getting stuck

Started by
3 comments, last by Puyover 12 years, 9 months ago
Hello!

I'm trying to make my character move around a tile map with collisions. Everything works fine except for one thing. I show you a picture with the problem:

bcyz5.jpg

That is, when I reach a tile above then I can not move anywhere. If you come from the left, I can not move either up or down. If you reach the bottom, I can move to the left but not right. And when you reach the right I can move in any direction.

Honestly I have no idea what may be failing. I think it has to do with if (...), because if I change the order, the addresses where I can move change :/

Here I leave some code:


boolean collision = false;

if(Keyboard.isKeyDown(Keyboard.KEY_UP)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if(UpTile(map, i) > 128) {
collision = true;
}
}

if(!collision) AddPos(0.0f, -vel);
}
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if(LeftTile(map, i) > 128) {
collision = true;
}
}

if(!collision) AddPos(-vel, 0.0f);
}
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if(DownTile(map, i) > 128) {
collision = true;
}
}

if(!collision) AddPos(0.0f, vel);
}
if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if(RightTile(map, i) > 128) {
collision = true;
}
}

if(!collision) AddPos(vel, 0.0f);
}


Thanks!
Advertisement
Post the code for UpTile/DownTile/et. al.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Post the code for UpTile/DownTile/et. al.


This is the code:


public int UpTile(Map map, int layer) {
return map.GetValue(layer, (int) (x/size), (int) (y/size));
}

public int LeftTile(Map map, int layer) {
return map.GetValue(layer, (int) (x/size), (int) (y/size));
}

public int DownTile(Map map, int layer) {
return map.GetValue(layer, (int) (x/size), (int) (y/size + 1));
}

public int RightTile(Map map, int layer) {
return map.GetValue(layer, (int) (x/size + 1), (int) (y/size));
}


The map is an array with 3 componentes: [LAYER][Y][X]. So, in RightTile by example, with GetValue, I'm getting the value from the array in the position [layer][y/size][x/size + 1], x/size + 1 because I want to get the kind of tile that is to my right (same with the others). size = 64, that is the width and height of each tile.
Need more input:



What's x, y and size (and which type). Why do you only cater for the next tile in Down Y and Right X, but not up and left?

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>


Need more input:



What's x, y and size (and which type). Why do you only cater for the next tile in Down Y and Right X, but not up and left?

Yes, at the end it was because the sprite went inside the tiles collided and could not leave quitx_x Now I've solved and works fine. Here I leave the code related:


/**
* Control the movement and the collision of the character
* @param map The map which we want to check collision
*/
public void ManageMovement(Map map) {
boolean collision = false;

if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if((LeftTile(map, i, 0) > 128) || (LeftTile(map, i, 1) > 128)) {
collision = true;
}
}

if(!collision) AddPos(-vel, 0.0f);
}
else if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if((RightTile(map, i, 0) > 128) || (RightTile(map, i, 1) > 128)) {
collision = true;
}
}

if(!collision) AddPos(vel, 0.0f);
}

collision = false;
if(Keyboard.isKeyDown(Keyboard.KEY_UP)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if((UpTile(map, i, 0) > 128) || (UpTile(map, i, 1) > 128)) {
collision = true;
}
}

if(!collision) AddPos(0.0f, -vel);
}
else if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
for(int i = 0; i < map.GetNumLayers(); i++) {
if((DownTile(map, i, 0) > 128) || (DownTile(map, i, 1) > 128)) {
collision = true;
}
}

if(!collision) AddPos(0.0f, vel);
}
}

/**
* A method to get the upper tile next to the character
* @param map The map which we want to check the tile
* @param layer The layer of the map
* @param corner 0 indicates the upper-left corner of the character. 1 indicates the upper-right corner of the character
* @return The kind of tile next to the character in that direction
*/
public int UpTile(Map map, int layer, int corner) {
int tile = 255;

switch(corner) {
case 0:
tile = map.GetValue(layer, (int) (x/size), (int) ((y-1)/size));
break;
case 1:
tile = map.GetValue(layer, (int) ((x+size-1)/size), (int) ((y-1)/size));
break;
}

return tile;
}

public int LeftTile(Map map, int layer, int corner) {
int tile = 255;

switch(corner) {
case 0:
tile = map.GetValue(layer, (int) ((x-1)/size), (int) (y/size));
break;
case 1:
tile = map.GetValue(layer, (int) ((x-1)/size), (int) ((y+size-1)/size));
break;
}

return tile;
}

public int DownTile(Map map, int layer, int corner) {
int tile = 255;

switch(corner) {
case 0:
tile = map.GetValue(layer, (int) (x/size), (int) (y/size + 1));
break;
case 1:
tile = map.GetValue(layer, (int) ((x+size-1)/size), (int) (y/size + 1));
break;
}

return tile;
}

public int RightTile(Map map, int layer, int corner) {
int tile = 255;

switch(corner) {
case 0:
tile = map.GetValue(layer, (int) (x/size + 1), (int) (y/size));
break;
case 1:
tile = map.GetValue(layer, (int) (x/size + 1), (int) ((y+size-1)/size));
break;
}

return tile;
}

This topic is closed to new replies.

Advertisement