Archived

This topic is now archived and is closed to further replies.

Ferinorius

walkability for a side scroller questions...

Recommended Posts

Ok, I have smooth scrolling, and I have certain tiles set up, and I have read through all the tuts on game dev, but nowwhere does it tell how to implement stuff like this. How can a person implement walkability. Think of it as a side scroller, and the routine needs to be able to tell if the next tile is walkable or not before the player is moved there. how is this done? at least show me a tutorial that HELPS inplement walkability.

Share this post


Link to post
Share on other sites
Since it''s a side-scroller I''m guessing that it''s also a platform type, yeah ?

Anyway, there are loads of methods, but here is one I used and It''s probably the fastest, or it doesn''t take too much processing. If you are using 256 colour (8-bit) then it''s handy.
Use your palete of colours and give them an order, say green (grass) is "walk", blue (water) is "nowalk", then...

if(player.position "nowalk")
{
if(player.going forward)
player.position--;
else
player.position++;
}


Hope this helps
djsomers

Share this post


Link to post
Share on other sites
Oops!

Just saw the ''Tile'' bit in your post.

That makes thinks more simple, Give each tile type a value..

  

struct tile
{
int width;
int height;
etc..
const char *walkability;
};




Now in your game loop:
do before blitting your sprite to mem/screen

  


if(player.pos==tile[x][y] && tile[x][y[y].walkability="nowalk")
{
don''t move player sprite;
}




This is better and relly just as fast in tile games.

djsomers

Share this post


Link to post
Share on other sites
ok, i do something like that, check my player''s positoin versus that and then I get this:



I think I have to tweak it a lot more, and experiment with some things.

As you can see, my color isn''t 8 bit unfortunately.



Neo-Toshi - The City That Never Sleeps

Share this post


Link to post
Share on other sites
when you check for walkability, you need to make sure that the player''s position is set to the top pixel of the tile they are walking on. that''s what your problem is in the screenshot. if i had time, i would pull up my engine code and give you some calculations on how to do that, but it really isn''t all that hard anyway. just set the player''s position to where his feet are touching the top of the tile he''s standing on.

sorry i couldn''t explain more...

dave

--
david@neonstar.net
neonstar entertainment

Share this post


Link to post
Share on other sites
Hey neonstar, its been a long time since i have heard from you...oh well. it is probably harder than it seems, but ill keep scraping my brains for it. see, i had a really crappy calculation

if (map[player.posx + world_camerax / TILE_SIZE][player.posy + world_cameray / TILE_SIZE] == 0) {

player isn''t standing on something keep falling
}
else {
player is standing,
}

and that is how it got me to where i am in the picture



Neo-Toshi - The City That Never Sleeps

Share this post


Link to post
Share on other sites
If your character is "below" where he/she/it should be standing, then you have a problem with which tile your comparing to be "solid". Play with the y (or x, whichever is the "up/down") and see how it needs to be offset to check the tile.
    
if (map[player.posx + world_camerax / TILE_SIZE][player.posy + TILE_SIZE + world_cameray / TILE_SIZE] == 0)
{
//player isn''t standing on something keep falling

}
else {
//player is standing

}

Note the +TILE_SIZE in the y dimension of the map array. This shifts our view to UNDER the player, instead of the map[][] your player was being drawn at.

Another really nice thing is that you have blank space set to 0- do you have any other "background/walkthrough" tiles in mind? If so, excellent! Try numbering them so that the first few (0-10 for example) are the walkable ones, and the others (11+) are the "solid/impassable" ones. Then change your "== 0" to a test for "walkable" things "< 11" and you can walk/fall through coins, illusionary walls, fake ground, et cet.

-Tok


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Feel free to email me HERE
*Howdy Kids, Do /YOU/ know what time it is? It''s tangent time* -Baldor the Bold

Share this post


Link to post
Share on other sites
Ok, switched some things around, changed a few states and still have nothing. I even but debugging junk up all over the screen to show me what tiles were what. I think my problem now lies in the fact that my collision detection isnt scrolling, but still I am not entirely positive about that for sure.

after changing that bit of code, the numbers are all haywire, and spark (the sprite) stops in mid air for no reason. What a bug this has turned out to be.



Neo-Toshi - The City That Never Sleeps

Share this post


Link to post
Share on other sites
well heres how I do it. Don''t know if it helps or not.
all tiles are 32x32 pixels.
Each tile has a blocking byte which is or''d to various constants I''ve defined.
so bit one is block up, bit two block east.
#define TILE_BLOCK_UP 1
#define TILE_BLOCK_RIGHT 2
#define TILE_BLOCK_BOTTOM 4
#define TILE_BLOCK_LEFT 8
#define TILE_BLOCK_ALL (TILE_BLOCK_UP | TILE_BLOCK_RIGHT TILE_BLOCK_BOTTOM | TILE_BLOCK_LEFT)

my character has a velocity x and a velocity y, in pixels.
To handle falling, _every_ frame we add gravity to the y velocity (see why later).
Characters have a width (in tiles) and a height(in tiles)
I the character''s position is tracked by the bottom left corner of it''s bounding rect.
I have a function to convert screen pixels into world coordinates.
A world coordinate is given by tilex, tiley, subtilex, subtiley;
The camera maintains a camera x, y and sub x, y to allow for smooth scrolling.
So I first calculate the world coordinates of the current tile I''m in.
I then calculate the world coordinates of the tile I''m travelling to. Based on the velocity of course.
I also calculate the world coordinates of all four bounding points of the character. East from the bottom left, I just add the character''s width and height.
Then depending on the direction of the velocity I do some checks.
example:
if(velocity.x < 0) //moving left
(
//check if the left edge has crossed a tile boundary
if(bottomleft.starttile.x != bottomleft.endtile.x)
{
if(World.GetTile(bottomleft.x,bottomleft.y)->GetBlocking()
&& TILE_BLOCK_RIGHT)
{
SetXVelocity(0) //stop moving in the x direction
SetXPosition(bottomleft.starttile, 0) //far left of start tile
}
else
{
//add x velocity to current x
}
}
)
else //moving right etc...

So that handles left and right motion pretty simply.
Y motion is pretty much the same
if(velocity.y < 0) // we''re falling. we should _always_ be falling
{
if(bottomleft.starttile.x != bottomleft.starttile.y)


}
























Share this post


Link to post
Share on other sites
Stand back from the problem now!!!

Get a piece of paper and look at the problem. As mentioned
you need to look ahead rather than where you are.

I am not going to give code. Code is the process of thinking
it through and no matter how many times you tweak the values
you are only putting off what you don''t understand.

Your sprite, from the looks of it , is getting stuck.

Let''s say your sprite just dropped out of the air onto that
platform. He had an original Y and a movement. So in essence
you have Y0 and Y1. Where Y1 was the target.

Now from Y0 through to Y1 you could have hit something. Now
you need to determine what Y0 through to Y1 would have hit.

Your map is regular and constrained within a 2D array. You
need to loop through X0,Y0 to X1,Y1 in incremental steps.

When you get a hit you snap your sprite (minus it''s height) to
the tile.

Now this is really robust because no matter how fast you move
your sprite will always have determined what it COULD have
gone through.

Example.

Sprite_X0 = 0

Sprite_X1 = Sprite_X0 + 64;

Let''s say your tiles width is 32. Your sprite now has passed
right through. You could argue that you restrict movemment to
less than the dimensions of a tile. But this restricts you big
time.

If you don''t want to be this robust then look at whether you
need to snap to the nearest tile.



Share this post


Link to post
Share on other sites
Question:
Will snapping to the next tile create jerky movement?

If so, is there a better way?

Let me explain a little more about the program:

Spark (the sprite) has different states; when a key is pressed left or right, or when the space (jump button) bar is hit, or when the sprite is falling.

Before, the code where the picture was taken, was horribly slow because I checked to see (using that equation) if the sprite is on the tiles each key press. I took that out in search of a better way. I know that the sprite needs to always be falling.

No one seems to be elaborating, and I know im not being clear enough.

When the space bar is pressed, spark''s velocity is set to something like 35. then, it is decreased each frame by gravity, which is 3. this is a nice quick and low jump.

but the problem is that spark doesnt jump from a paltform, he jumps from some y coords. if spark''s y position less than a certain point, i reset it. this is one problem. Now, when i take that out, its like the program doenst know its falling over tiles, but its falling across the screen.

Here is where i need the help. I need more elaboration. As I said once before, there is no tutorials that fully explain it, I am having to learn this from the start....I know you all know what you are talking about, so let''s pretend I dont.



Neo-Toshi - The City That Never Sleeps

Share this post


Link to post
Share on other sites
When you say that Spark does not jump from a platform are you
saying that if he is in mid air you can still jump ?

Please do the following it will help I promise you. I am not
preaching but rather trying to get your mind into a different
mode

Forget code right now. Get a piece of paper and draw a rectangle
now put this rectangle through a series of states.

You know what you want from the code. Move away from the code
look at the problem and come back.

I am not saying this is the best way. But I spend days drawing
the permutations before even going near code.

At the end of the day this is a collision problem. You have a
vector from X0,Y0 through to X1,Y1. Knowing that fact you have
to project what would have been hit.

It could be that other code in your logic is getting in the
way of solving the problem. Isolate the problem. Set Spark to
a known state for example making him fall and process the
collsion rather than test him in the game environment.

Isolate the problem if you can , other code could be the
culprit.





Share this post


Link to post
Share on other sites
I took your advice and looked at the problem, and then i hurridly removed ALL the tile checking and collision stuff from the program so that I can have a clean start.

I appreciate this ancientcoder, by the way, for being patient with me on this.

Now that I have a clean start, I have all these things to draw out:

akwardly shaped sprite 96 tall by 79 wide, and 64x64 sized tiles.

Now, to look at it from this different perspective, am I trying to check tile by tile, or point to point?
It might be easier tile by tile, but I get all confuddeled doing a switch from tile coords to point coords urgh.

I also want to mention, I wasn't getting stuck, I meant that Spark just jumps from the y position at 290. then he jumps, the velocity decreases, he falls, and only stops when he reaches 290 again. so spark didnt know if he was on a tile or not, just that he was getting told to jump


Ya see, I am more hands on so I learn slowly this way, but I am so eager to learn this.

Neo-Toshi - The City That Never Sleeps

Edited by - Ferinorius on November 7, 2001 2:21:39 PM

Share this post


Link to post
Share on other sites
Ok, new post.

I have all these state:
falling, jumping, pressing right, pressing left, dying and so on.

the states pressing right, left and jumping should all be included under the falling state. then, if a key is pressed, check the tile NEXT to spark. if it is ok, then increase position to the next tile. now check to see if there is a valid tile BELOW spark. if there isn''t a valid tile, decrease y value, else, dont decrease, dont fall.

or at start of loop check tile below spark, if it is valid, dont decrease the y, it there is no tile, or it is a fall through tile, then fall and decrease y value. If y value is more than the height of the screen, Spark has fallen, all bow.

am I getting on the right track now?

Share this post


Link to post
Share on other sites
Sorry for my previous post, got a little muddled and this machine crashed in the middle. What I was trying to illustrate/convey I suppose is that it is a problem of rectangular collisions.
Most of the movement is within the same tile, you only do collision detection when any corner of your bounding rect crosses a tile boundary. But you have to check every corner. If the bottom right corner is over a valid tile, you can''t fall.
If the bottom left corner is over a valid tile you can''t fall. etc...
If you maintain the always falling concept, then this collision detection will be occuring every frame as you try and move through the tile beneath it.
I think you may be getting mixed up, or maybe I am , with states versus input reaction. Unless you''re dying, the only state you''re in "moving" (whether you are or not ) The users input should do something like if the right key is press send message to object to add to right velocity. The the object does something like do I have traction and if so then if I''m at less than maximum velocity to the right, then add so much that velocity. It doesn''t really change state, just sends a message to the object which changes the velocity vector. Traction would be defined as having my foot on the ground, i.e. I was stopped from falling in the last frame.
Then later in your update loop the object then says, ok I''m moving right, so I need to be in the run animation to the right. Every successful motion then updates the current frame. The the only real "state" is the kind of the animation sequence I''m in. When you get an input message you check and respond to it by setting the various parameters (velocity, animation state, etc...) But you don''t do anything until the update segment when you validate it all/process any change.
blah, hope that helps focus,
cheers,
-m








mat williams
Lead Programmer, Designer
Zero Sum Software
www.zero-sum.com

Share this post


Link to post
Share on other sites
From what I understand is that Spark can be steered when
he is falling ?

He commits to a jump but you can manipulate his movement during
the jump ? Is this what you mean?

Write down what you want your character to do.

For instance....

When I press the jump key my character will move in an arc
he will move X units in a positive direction and Y units in
a negative direction. When the character reaches the top of
the arc his X and Y will increase according to gravity.

During the course of this jump the user may press the left
arrow to steer the character back from the jump. By pressing
left the user will be allowed to correct the jump and decide
that he does not want to commit. However if he presses right
the jump will continue.

Do you have access to any good platform games? Have a look at
Mario / Jazz Jackrabbit and see what they do.

Press the spacebar for a short while and you get a lesser jump,
press it a bit longer and you get more height.

Most good platform games allow you to correct a mistake. It is
very important that you understand the functionality you require.

Sorry for sounding so vague but please write down what you require. Forget the code , forget the code!!!!


Share this post


Link to post
Share on other sites
FOR THE LOVE OF GOD STOP LOOKING AT CODE!!!!!!!!!!!!!!!!!!

You have got a problem in design, throwing codes only gonna make the problem mad. Often times (and this is a prome example) you keep trying to alter code when that will get you nowhere and shoot your morale to hell. You haven''t thought this through enough (niether have i, thats why i offer no help). Go through each possible step, think how your program should deal with it. DRAW DIAGRAMS! Transitive state and Class relationships diagrams are good here. Once you have a course of clear action take a break, sit down and mothodically write code.

The code is minor, deeply understanding the design is MAJOR.

RELIGION IS THE ROOT OF ALL EVIL

Share this post


Link to post
Share on other sites
Im getting the picture that I am going about this problem all wrong!

I understand why I have to do this, so I put the code down, in fact, C++ hasn''t even been opened since I wrote my last reply, and I am THINKING this through.

For my game, I want spark to be able to jump off the ground, or jump off of any platform in the game that he can reach from a jump. spark also has the ability to run or walk. runing in the same direction for a while enables him to run, and vice versa.

Spark cannot jump while in midair.

Spark will eventually collect coins, and destroy baddies in a zelda-esque manner. Sword in hand, attacking like an adventure game.

Its quite a take on the side scroller, with action game battling, and platformer jumping.

The tiles i know, are 64x64. Spark has a big area to jump around on.

Now that I know what I want, how do I implement this?

Spark will need to detect which tile is in front and behind him. If to the side is something other than a fallthrough tile, Spark cannot move. Otherwise, jumping, moving, or any other action is permitted. This goes the same with the one below him. If it is a fallthrough he falls, otherwise, no restriction.

That is what I have written down, among other little arrows, squares, sparks, and other things. Now I feel more comfortable because I have more of an objective. I have a goal to work towards.

Implementing all this is something entirely different.

Share this post


Link to post
Share on other sites