How stairs work in top down 2D game worlds
HTML-код
- Опубликовано: 20 сен 2024
- ⁍ Discord: / discord
⁍ Twitter: bit.ly/UnitOfT...
⁍ Play: unit.dev/mmo
⁍ Github: github.com/uni...
// Description
This is a brief overview of how stairs work in top down 2d game worlds. We can make the game look more 3D by simply adding a small Y bias as the player moves up and down stairs, making it look like they are climbing up, when in reality they are only moving diagonal.
what's really fun is making a fake z axis that just pushes the drawing up in the direction of the camera angle and making the character angle the same of the camera. then when you perform a jump keep drawing the shadow at the normal position, offset the character in the camera angle direction for the illusion of height off the ground.
Yeah I do that for the monsters that jump in my game. works really well!
Don’t forget, you can learn from early Zelda games, when you get to the top or bottom of the stairs you can make your character have a “elevated” or “second floor” variable so that the player can’t interact with things or enemies that are on a different floor
@pixels_per_minute trying to learn godot, thx for the tidbit
I never even thought about this thanks
But for example, what if you’re character was an archer? Wouldn’t you want to snipe enemies from there too
@@sazerae an easy solution is to have the arrows not be effected by elevation, so the “elevated” variable would only effect the player, so if the player wanted to interact with something it would first check “if not elevated you can press this button” but just make it so that the arrows don’t do that kind of check first, and just use normal collision boxes like normal
Your simplistic character gave me hope on being able to make my own.
Yea I wanna make a game but thought I wasn't good enough at art than saw this
Trash
Making a game is very time consuming.
@@Misty_Oceans you dont need to know art to make your game, there is hundreds maybe thousands of free assets that you can use. Just do it
I still wouldn’t be able to make something like that
I'd love to know how this works code-wise.
It basically looks like this (though the if statements have a few more possible states because of other inputs and other staircase types): Hoping that YT formats this in a somewhat okay way:
if playerInput.Left {
move.X -= speed // move left because we are moving left
if tile.Floor().Type == TileStairLeft {
move.Y += speed // move up because we are moving left up a leftward-staircase
}
}
Where playerInput is the player's input state and tile is the tile that the player is currently on
@@UnitOfTimeYTtq ah brather
@@UnitOfTimeYT Thank you!
@@UnitOfTimeYTwhat language do you use? Im new to coding and do not recognise your syntax. I have started GDScript on Godot and this is hard, holy hell.
@@theJadeTiger lol yeah it can definitely be tough when starting out learning to code. I'd recommend not focusing on trying to learn everything an engine or language has to offer, but instead just try to solve individual problems like: 1. How do I get my character to move? 2. How do I get my character to stop moving when they hit walls. 3. etc...
I'm using a programming language called "Go" (AKA Golang). It's not really a traditional "gamedev language" but I like it.
Yes and no. This visually works but youre going to hobble yourself later down the road. I would keep track of the z position (even though its 2d) and add the height to the y after movement. This way you can keep track of, say, when an enemy swings at you but they're at the bottom of a cliff, you can easily discard collision checks because theyre not on the same z axis
I used to do this, but quickly reverted. The problem with this is as the game map expands, it becomes increasingly difficult to debug at certain areas because you have to keep in mind z axis every time. Also placing enemies also becomes a pain for the same reason.
In the end, it's just more effort than for what it's worth. And if you really want to stop players being hit by enemies from a different layer, just have the hitboxes not affecting if there's a collision between the player and enemy.
@@Pie_Mastah Would you mind expanding on how you might have, say, hitbox x not affect hitbox y if it hits hitbox z first?
@@samellington8804 Sure. In Game Maker Studio 2 for example, there's a function that lets you check a line collision between two points.
So you would then write it as, "if there is no ledge collision on the line between player and enemy coordinates, apply hit box"
Not sure if there's a similar function for the physics system though.
@@Pie_Mastah Ahhh I see. I use Unity so I'm not sure if there's a similar system or not, but I'll look into it. Thank you!
It's the difference between zelda and alundra
You could go a step further and permanently increase/decrease the player size slightly when going up/down to sell the illusion of vertical movement.
Never thought about it but that makes perfect sense. It’s just an illusion.
That's kind of what I expected, but I wasn't sure. Thanks for explaining
ngl i think the slowdown on the stairs just looks sluggish. maybe if you toned it down a bit it would read better but when i saw it i thought it was a coding mistake
I still don't know a lick about coding, but I can tell I'm getting better at game design because I knew what you were gonna say before you said it, so that feels pretty good.
You don't have to be an amazing programmer in order to create a good game. If games like Undertale can exist and turn into a success, then why wouldn't you, why wouldn't anybody be able to create something that works out the same?
And usually games start off as something quite unattractive, then turn into something more attractive as time goes by.
You can definitely do it mate.
@@iamyourgreatgreatgreatgrea6291 Thanks for saying that.
I've actually made a clone of Pong in Godot since making that comment, so I'm getting there.
@@Sabbalab92 You're welcome, and awesome! As long as you keep making stuff, even if it's clones of other games, you're doing something fun and learn lots of cool stuff! :)
Very interesting. Wanted to become a Game Dev once, but knew it was difficult so I gave up, but this is pretty nice to watch and learn. 😊
Thanks! Glad you enjoyed!
It's never too late to learn. I watched Lazy Dev's Academy and made a basic shmup game in my spare time, and you can, too. You will always become who you believe yourself to be.
@@TheZetaKai True, true. Thanks for the Encouraging Words. 🥰👌
DELTARUNE completely ignores the existence of stairs and just treats them as flat ground lol
i like making them go slightly faster when going down the stairs for realism.
Omg thank you. I have been trying to figure this out for days now😂 keep falling through the tile map
Glad I could help!
The other way that is apparently pretty popular is to fake 2d faking 3d. I.e., use a 3d game engine, but use tricks to make it look like it's 2d. E.g., static camera angle, flat textures, and only a few distinct vertical "levels" that the player can travel between. It's sometimes easier to fake 2d with 3d than it is to fake 3d with. Then, when you want to make it look like you are fak8ng 3d woth 2d, it is almost trivial.
something i noticed is that ur player is going faster when going upstairs and downstairs, i’d normalice that velocity and even multiply it by a slowness factor cuz when going up or downstairs u usually go slower
Next please: how do collisions work in top-doen 2d game?
I'd do it all graphically - having XY coordinates of the floor one is on and different screen elevations tied to each floor so when the character walks along a transition cell (with certain axis defined as the connection points to specefic floors) it lerps the character's screen position - just because I'd like the possibility of overlapping floors even if it thought the game wasn't going to need them.
Do not forget that a 45° diagonal path forces characters to run about 1.4 times faster ( Almost one and a half times).
Very helpful to show what it looks like without the y bias
enter the gungeon has perfect jumping examples :D
Fun fact, gungeon is actually a 3d game designed to look 2d
Would have been nice to have a quick showcase of the code too.
Moving the character up and down on the 2D plane? No this character is stationary, it's the world moving up and down underneath him.
He is him. The center of the universe. All matter moves relative to him
Never wondered until this video but that was interesting nonetheless.
I hadn't thought about it until i saw this
Now, walk behind the stairs and show us how the immersion breaks
Love these shorts
this is useful thanks
Even simpler is to just have position represented by 3 axes. Your renderer can still be 2D.
the game paper lily also does this really well
yk, id never wondered, but its cool to know for sure
Thats very interesting thanks
I wish tutorials like this showed example code or more practical information beyond "this is something people can do"
Thanks for the feedback!
If only the developers of Zombies Ate My Neighbors could've learned from this
" Zombies ate my neighbors"
had vertically facing escalators .
thank you! ❤ :)
I think you got your positives and negatives mixed up.
Negative Y moves up, positive Y moves down.
As long as the meaning is understandable though, I suppose it doesn't matter.
Not in literally every other game engine than the one you use
@@froxdoggaming3385 Sure, bud. If I'm the odd one out, name 3 engines where positive Y values go UP on the screen.
Coordinate 0,0 is always in the top-left.
Please provide examples of 0,0 at the bottom-left.
Now do a jump in top down perspective
omg im stealing that speed adjustment. TY
Go for it! :)
Yeah I just saw you walking it without the y and I understand it
This helped a lot thx for posting!
please do a tutorial for it, also how to add collisions with Ysort when player move around the stairs, it's really confusing
Waiting for the jump tutorial
Haha aight I'll try and make one once I implement something that jumps or floats in my game
Very useful explanation, thanks!
Glad it was helpful! Thanks for watching!
this is really well made video!
... I just unserstood that I think way too much in 3d and 3d games. Thanks for explaining this 🙂
Supet useful thanks! Gonna try this tomorrow
this would be if the game doesnt recognize things like being underneath or next to things. you would want to keep track of the floor level that the character is so they can walk under the upper floor and go behind thenstairs
Ah yes. Very true! Thanks for mentioning!
thx dude Im new at this and this is awesome information
Cool! Glad to hear it helped!
In the same case I've always been wondering how you would jump off in this situation
Should there be like an Imaginary Z Axis that calculates the Y Axis while there's also a second Y Axis that actually calculates the jump.
Yeah you can definitely have an imaginary Z axis. Some of my monsters will jump and for that I just move them along a fake z axis. But you can do it that way on your tilemap if you want!
i thought that they just added a z variable witch you'd add to the y axis when rendering.
Yeah, It's definitely possible to do it that way. In some cases (like jumping) I just use a fake Z variable, but its convenient to have my tilemap all at one depth (tho it does cause some weird edge cases in some situations)
I still dont know but i love it!
hey this helped a lot thanks!
my brain is expanding thanks
So you would make your moving commands into functions and then call those functions in the stairs object so that if a person is both on the stairs and moving they will get a bias in either direction?
Learning game dev rn and this seems useful to do
In my case, I have a movement function on the character. Then inside that function, I check the tilemap to see if the floor tile is a stair. And if the floor is a stair, then I simply add a small bias in the Y-direction to move the player up in the tilmap. Hope that makes sense!
@@UnitOfTimeYT thank you! That does help
Just like I would have guessed.
Thank you
Ok how about occlusion though? How would you make it so you can walk around the back of the stairs there?
The way I did it you wouldn't be able to walk behind the stair tiles, but I have walls on either side that you can walk behind which kind of hide the fact that the stairs are fake. Definitely a tradeoff.
So we can replace a stais with like idk a wind tunnel and it will look the same
Or rather idk like floor walk thread thibgs like in airport
Pixel tribe styled character :D
Is this how it works in A Link to the Past too with multiple levels?
I'm can't guarantee they did it the same exact way. But if I had to guess they probably did something similar
What if you have stairs where you go right to climb them? Check if player is colliding with "right or left" stairs?
Yeah I just have an if statement depending on if the stairs are "left stairs" or "right stairs"
A simple solution is to do what the 2D Zelda games did. All stairs are oriented north and south and the game keeps track of what "floor" the player is on.
Im thinking about adding this into my game. Do you use some kind of rectangle to represent the stairs, then check if the player is colliding with the stairs and moving? then you could check the x direction and add or minus the y depending which direction?
Yeah that's exactly what I do. I use a tilemap, so I just check the tile type of the tile the player is currently on. Then if it is a "stair-left" (like the one in the video), I check if they are going left or right. If they go left I add a little "y-bias", else I subtract the "y-bias"
I'm learning to program in gamemaker, I really want to do this, could you help me in any way?@@UnitOfTimeYT
Whats a simple Explanation for 2-D FPS Racers ?
for ex. F-Zero ,Pole Position etc.
Sorry I'm not super familiar with how those were done!
Great video! Do you know how to config a rain in isometric view with the rain falling on water pounds for exemple, with that animation of water drops that generate small waves in the water?
Thanks. I haven't had to do that yet, so I'm not sure how good this advice is, but you could probably do something like it with world space rain particles falling in the game, then maybe have a second particle system for the small waves in the ponds. You might even be able to get away leaving the two particle systems uncoordinated, I wonder if people would even notice.
Great idea, Thanks :))@@UnitOfTimeYT
But can you please explain the first part were when it going up the stairs it turns slightly up and when it going down it turns slightly down
Yeah basically: If the player is going up the stairs, then they are pushing left on their keyboard. Then we basically detect that they are on top of the stairs, and we want to "fake them out" a bit to make it look like they are walking upwards on every stair step. So we move them "up" (kinda like they were pressing left and up on their keyboard at the same time. making them go diagonally). Hope that helps!
@@UnitOfTimeYT yeah thanks
What if you have one staircase going up by going right and one by going left, how do you handle this? are you just creating multiple conditions based on types of tile?
Yeah I have multiple conditions. One for stair left and one for stair right
How wpuld it be if im going up to down on the stairs but also going up on the y axis
Yeah in that case it looks like they are walking straight right (deepending on how much Y bias you give the stairs), but it still feels normal because it feels like your trying to walk in that direction
Hi! Is this rule going to work in a normal 2d platformer too? I mean a side scroller, not a top down... seems like it.
In that case the y axis is probably upwards anyway. So I imagine it would. But in that case you might have some downward physics and colliders that you do instead
Makes sense
I wanted to know what that one 2d physics thing with people making particle accelerators is called
Please anyone tell me
How'd you do that tile.floor().Type? as an object or did you do something with the tileset?
For my game I did multiple layers on each tile, so a tile has a floor layer inside of it. Then it possible layers above and below (mostly for decorating the tile). So I just do tile.Floor() to get the floor layer of the tile. Alternatively, you could do multiple tilemaps, one for each layer. I just did it with a single tilemap, so to have layers each tile needs to maintain that info internally.
What about projectiles hitting the stairs??
You can basically either have the projectile get destroyed when it collides with a stair, or you can make it go up the stairs like a normal player
But ehat about the y direction stairs (the one that face south or north)?
Yeah for that case I just slow the player movement down to make it feel like they are climbing something. But other than that they just keep walking in the same direction.
How did you get the sword to be animated like that?
I just place the sword on a circle around the player and rotate it based on the direction the player is aiming. Not super tough, but takes a bit of tweaking to make it look decent.
How do you check if player is going up or down the stairs because sometimes there could be stairs on left to move upward amd sometimes stairs are on right to move upward
So the trick there is to have two types of stairs: StairsLeft and StairsRight. Moving left on a StairsLeft would move you upwards, and moving left on a StairsRight would move you downward.
@@UnitOfTimeYT but player can change a direction. Also you can make this velocity.y +/- in the script of stairs and it will be working for a player, enemies and NPCs. You must only one check a collision in Area2D, get a node (player/enemy/NPC) and in every frame checking his direction or make a new signals for this. Core scripts like for open world game logic are the best. This one object must working for all types characters
@@DamianCentkiewicz My game is written in "Go" (the language) not "Godot" (the engine). But every entity that moves on the floor uses the same movement function, so they will all use the same logic of checking the floor they are on before moving.
how does the jump works in a top down 2d game?
You can kinda do something similar for jumping. but usually its easier to track a separate Z variable (which would be the jump height) then offset the Y based on the Z amount. Adding a shadow below the character on the ground helps a lot for that too!
I have a question. How do you make it like the player sprite is standing behind the banisters, because the player sprite is jn the front and the stairs (and the banisters) are in the background. But how do videogames make it like the banisters are in the front so you cant see the player? Are the banisters a different sprite that is put in the foreground?
Hey, yeah you are exactly right. I have two layers: one background layer which represents the floor tiles everywhere, and one foreground layer which represents all of the objects in the game (walls, people, etc). So the background layer is always drawn below the foreground layer, then when I draw the foreground layer I sort the objects based on where they are positioned in the world. So if you imagine the world is a 2D plane, where the X axis is horizontal and the Y axis is vertical, then I sort them based on where they exist in the Y axis: Essentially you just want to draw things that have a lower Y value in front of the things that have a higher Y value. This is sometimes called depth sorting, you can probably google that term (depth sorting) to get some more detailed information. Good Luck!
@@UnitOfTimeYT Thank you for your help
What if they walk diagonally on the stairs, then?
If they walk diagonally (based on the keyboard presses) then in this system they'd walk diagonally on the stairs.
What language is This codes in?
The whole game is written in golang. (Aka Go)
@@UnitOfTimeYTgoolag???
I swear i remember seeing this exact comment and video a month ago and i knew i was gonna see this exact comment wtf💀
Wow😮
Bro perfect ❤️.Please Download link please 🙏🙏🥺
The game is called Mythfall. You can play an early demo here (The game is currently heavily in development, so there may be bugs): mythfall.com/
Thank you 😊
Tutorial for scratch pls
Collision
This can be done with a boolean also
so basically, when the character moving up the stairs, the character is moving in the diagonal, right?
Yep! Basically if the character is moving left on a stair like the one on the video you just change the movement to be diagonal instead of directly left.
Would you consider partnering up for an isometric mobile and laptop mmo?
Appreciate the offer, but I'm currently working on my own game. Best of luck with yours though!
What engine or coding language is this in?
This is a homemade engine on top of opengl/webgl2 written in golang!
I have no clue about coding. How do I do it?
Are you using a game engine?
Mind
2d just sounds more complicated than 3d
What if I am already moving diagonally ?
Iirc it looks fine when I tested it. I just apply the y bias on top of the regular movement. The slowdown effect when walking up stairs might make it look a bit more normal
What is a x,y bias?
I basically mean to add a little extra movement in the upwards direction (the Y axis)
@@UnitOfTimeYT Thanks!
No idea what "y bias" means
Y meaning: On the Y axis
Bias meaning: Just add a little bit extra.
Wait what this game name
This is a game I'm making called Mythfall. you can play a demo at: mythfall.com/
The game name at the start?
This is a game called Mythfall that I'm developing. You can play the prealpha at mythfall.com
Yoo u actually replied thanks I'll try it!
HOOW
I know how this works but i you are trying to teach people you cant just say 'add a bias', nobody knows what that means
Or dont add stairs at all
Ok now do jumping.
haha - don't tempt me!
@@UnitOfTimeYT I’ve been working on a method to emulate depth from a top down perspective without relying on the illusion of animation
It’s a tough one 😅😅
Yeah that does sound challenging! In the past, to make things look like they're jumping/floating, I've always just placed a drop-shadow at the location of the game object. Then if I want the game object to be jumping/floating, I just move the main sprite upwards, above the shadow. Shadows seem to really help with the human perception of depth. Best of luck!