-
|
|
Object Collision with tiles
|
Hey, I have a tile system that is very similar, but not exactly the same (having done it mysellf, then discovering the tutorials and facepalming over time wasted) as Nick Gravelyn's tile engine.
To cut to the chase, anyone who's been through his tutorials or made your own tile engine, what would be the best way (or Nick's way) to implement tile-object collision checking?
I was thinking a loop that goes through every tile on the map, checking to see if it overlaps with the player and then implementing actions accordingly, it just seems too simple to be efficient. So I went off on a tangent thinking perhaps that I should get the player's position on the map, divide the x/y by the tile width/height (well, tiles are square, but hey O.o) respectively, and then assume the resulting int as the tile coordinates in the array, then check for collisions with that tile. The problem there is, to use that method, I already know that a collision is true,because that is where the player exists on the map.
http://nickgravelyn.com/archive/ - For nick's tutorials for anybody who is interested.
Programming a life simulation/farming game. Still a long way off completion. Follow me on twitter| or Send me an email | or Check out the Devblog!I'm Interested in your opinions/ideas/feedback/help.
|
|
-
|
|
Re: Object Collision with tiles
|
In my game I have static environment objects in a list separate from the player/enemies. Then I loop through the list of player/enemies and check them against eachother and then against the environment. While checking a player/enemy against another player/enemy I compare the positions and if they're equal then I know that I'm checking one object against itself and skip that check. And since the environment objects are separate from the player/enemies I never have the problem you are referring to. As for your tangent thought, that is exactly the kind of thinking you need to be doing. I would actually set it up to check if the player overlaps any nearby tiles and check them as well. In a worst case scenario(assuming your player is no bigger than a tile), you could overlap 4 separate tile at one time. The beauty of tiles is that the position of a tile in an array is directly related to its location in the game world. We don't need to check a player against every tile in the world, because we can find out the indexes the player is nearest and collision check against those.
|
|
-
|
|
Re: Object Collision with tiles
|
JustSudsX:The problem there is, to use that method, I already know that a collision is true,because that is where the player exists on the map.
Yes, if you check where the player is standing. What you want to check is however what's in front of the player. I did like this (pseudocoding):
map[,]=new int[mapW,mapH];
// First a function to check for tile collision. Send in a coordinate and get true/false back. tileWidth and tileHeight are pixel-size of tiles
public boolean checkCollision(int x, int y) {
if (map[(int)(x/tileWidth),(int)(y/tileHeight)]>0)
return true;
else
return false;
}
// Then, when handling movement
if ([movement==left] && !checkCollision(player.x-1,player.y))
x--;
if ([movement==up] && !checkCollision(player.x,player.y-1))
y--;
if ([movement==right] && !checkCollision(player.x+player.width,player.y))
x++;
if ([movement==down] && !checkCollision(player.x,player.y+player.height))
y++;
That is: if there is movement input and there are no tiles blocking the way, then move the player
|
|
-
|
|
Re: Object Collision with tiles
|
Demesta: JustSudsX:The problem there is, to use that method, I already know that a collision is true,because that is where the player exists on the map.
Yes, if you check where the player is standing. What you want to check is however what's in front of the player. I did like this (pseudocoding):
map[,]=new int[mapW,mapH];
// First a function to check for tile collision. Send in a coordinate and get true/false back. tileWidth and tileHeight are pixel-size of tiles
public boolean checkCollision(int x, int y) {
if (map[(int)(x/tileWidth),(int)(y/tileHeight)]>0)
return true;
else
return false;
}
// Then, when handling movement
if ([movement==left] && !checkCollision(player.x-1,player.y))
x--;
if ([movement==up] && !checkCollision(player.x,player.y-1))
y--;
if ([movement==right] && !checkCollision(player.x+player.width,player.y))
x++;
if ([movement==down] && !checkCollision(player.x,player.y+player.height))
y++;
That is: if there is movement input and there are no tiles blocking the way, then move the player
Thanks Demesta, that make a lot of sense. I'll have a go at implementing it with my variables, and I'll get back to you.
Programming a life simulation/farming game. Still a long way off completion. Follow me on twitter| or Send me an email | or Check out the Devblog!I'm Interested in your opinions/ideas/feedback/help.
|
|
-
|
|
Re: Object Collision with tiles
|
I'm actually having trouble understanding this part:
public boolean checkCollision(int x, int y) {
if (map[(int)(x/tileWidth),(int)(y/tileHeight)]>0)
return true;
else
return false;
}
where the int x and int y being passed are the players positionOnMap values, right? if so, am i wrong in thinking that all the checkCollision method does is check to see if the player is in the top left corner? That is, dividing x by tileWidth finds out the number of tiles across the screen the player is, and the same for y and down the screen, then checking that these numbers are greater than zero.
I'm not sure how this relates to individual unwalkwable objects (say, i dont want the player to be able to walk on top of a tree). I can picture the use of an object position vector variable (i have one of those) i just can't fathom the correct use of some intersects logic, although, i dont really want them to intersect, more "bump" off eachother, like your logic suggests.
Programming a life simulation/farming game. Still a long way off completion. Follow me on twitter| or Send me an email | or Check out the Devblog!I'm Interested in your opinions/ideas/feedback/help.
|
|
-
|
|
Re: Object Collision with tiles
|
It's a bit compact code I admit. Try this:
public boolean checkCollision(int x,int y) {
// Inparameters are the coordinates to check, in pixels. I assume that all tiles are of the same size (i.e. equal width and/or height) and that they begin tiling
// on screen coordinate (0,0). First, we convert the x and y to tile-equivalent coordinates:
int xTile= x / tileWidth;
int yTile = y / tileHeight;
// That is - in xTile and yTile, we now have the coordinates for the tiles in the 2-dimensional array that holds the map.
// Then we just check if there is a tile there. I assume you store the map as a 2-dimensional integer array here, where zero means no tile, i.e. walkable.
if (map[xTile,yTile]>0)
return true;
else
return false;
// If you want to have certain tiles walkable, let's say tile indices 0-7 are different types of ground, then you just check if the tile index is bigger than this.
// Or if you instead store tile objects in your array, you could have a boolean property - walkable - and then just check for that.
}
When you pass along the x and y coordinates of the player into the function, it thus converts them into tile-equivalent coordinates, depending on the size of your tiles. However, we don't use the players exact coordinates to check for would-be collisions: instead we check coordinates in the direction the player tries to go.
|
|
-
|
|
Re: Object Collision with tiles
|
Thanks, that clears it up, I hadn't clicked that in this line:
if (map[xTile,yTile]>0){}
the code was checking the value of the tile (as in, what the tile is; invisible, dirt, grass, tree, etc), not the location of it. That makes perfect sense, thanks for your help!
Edit: this really helped, lol, i just realised that i never even explained some of the key factors of my game; 2D, tiles are square and all the same size, stored as an object array that i access via their indexes, multiple tile-layers, etc. But it seems you guessed that pretty well. Next time I'll include at least some basic information, lol.
Thanks
Programming a life simulation/farming game. Still a long way off completion. Follow me on twitter| or Send me an email | or Check out the Devblog!I'm Interested in your opinions/ideas/feedback/help.
|
|
-
-
- (450)
-
premium membership
-
Posts
129
|
Re: Object Collision with tiles
|
Another trick is to assign each tile a code to tell you what type of tile it is (solid, water, deathy spikes, etc).
So tile 1 might be grass, tile 2 might be bricks, tile 3 might be rock. They are all solid, so you could have a tile type array that is indexed on the tile number and returns the type. So [1,1,1] would be 3 elements in the array where 1 means solid. You could index the three tiles I mentioned by their index and get the type. If the fourth tile was water, it could be [1,1,1,2] and so on. This way you can have many different looking tiles that do the same thing easily.
So in your code it would be like
if (tileType[map[x,y]] == 1) { //collision }
if (tileType[map[x,y]] == 2) { //swim }
if (tileType[map[x,y]] == 3) { //die horribly }
|
|
-
|
|
Re: Object Collision with tiles
|
Hi again. I know the thread is aging, and my problem was solved. But I have an issue that I didn't think warranted a new thread.
The system demesta gave me worked almost perfectly. But I have a ghost issue, I cant seem to track down the issue in my code. My player / object tile grids seem to be offset by about 2px. So, when I move my player against an object (heading either upwards or in the left direction) and try to change my axis of direction, the player sticks because their position overlaps objects on the other axis by the 2px. So, if my player walks left into a group of trees, he can walk back right, but not up or down (because of a collision with the objects on either side), I attempted to implement a sort of "snap to" effect when no keys are pressed on my keyboard, but it wouldn't work. I could make my method work when I press a key (i tested it with the Q key) but not when no keys are pressed.
So while I was thinking about how to get around the issue, I thought it might be best to implement like a larger scale snap-to effect. So when the player lets go of the directional key, the player's sprite continues to move till it snaps into a clean tile coord.
I can implement this to a degree, I can have the player jump straight to the coordinates I want it, but that looks terrible. Can anyone help with a bit of a generic algorithm for slowing to a stop at a specific point, regardless of when the key is let go.
I'm imagining something that calculates the distance from the player to the next tile, uses that number to work out how far to move each frame, before coming to a halt at the right position. I've been trying for about two days, I can't conceive a working algorithm to this tune for some reason. It seems simple enough.
Thanks for your help.
Programming a life simulation/farming game. Still a long way off completion. Follow me on twitter| or Send me an email | or Check out the Devblog!I'm Interested in your opinions/ideas/feedback/help.
|
|
-
|
|
Re: Object Collision with tiles
|
Glad I was of assistance!
Don't know if this will solve the issue, but perhaps.
In the code I gave you, it only checks one pixel coordinate in front of the player. Actually, you should check two coordinates. If you have a sprite size of 10x10, and if you are standing on coordinate 30,30 (upper left corner of sprite), the sprite will occupy coordinates 30-39 x 30-39.
If you want to move upwards, you should check collision for coordinates (30,29) as well as (39,29).
If you then want to move to the right, you should check collision for coordinates (40,30) as well as (40,39).
In short: you need to check both edges of the sprite area in the direction you want to move.
|
|
-
|
|
Re: Object Collision with tiles
|
Thanks, that fixes one of the bugs I was going to tackle next. I got a fairly solid snap-in system for when the player stops within 3px of a tile-grid border, this pretty much solves the issue I posted about. But I can see more arising.
Thanks for the help again Demesta
Programming a life simulation/farming game. Still a long way off completion. Follow me on twitter| or Send me an email | or Check out the Devblog!I'm Interested in your opinions/ideas/feedback/help.
|
|
|