Platformer Question

Blitz3D Forums/Blitz3D Beginners Area/Platformer Question

Crazy4Code(Posted 2005) [#1]
I'm trying to figure out if most platformer game's (i.e Mario) levels are made with a single image, or are they made up of individual "blocks" because it seems like the block thing would work better, but would be a bit more tedious maybe. I'm not quite sure why i think it would be tedious, but anyways... Is it even any of those two?


Who was John Galt?(Posted 2005) [#2]
The 2d marios definitely use the block method. A bit more effort, but gives you the ability to have big levels without loading images all the time.


Crazy4Code(Posted 2005) [#3]
So, I guess you would use arrays for those?


octothorpe(Posted 2005) [#4]
Yes, a 2d array ;)


Crazy4Code(Posted 2005) [#5]
Thanks


octothorpe(Posted 2005) [#6]
Few games use large images as backgrounds; even when backgrounds in games don't seem to be composed of tiles, they usually are. The NES, SNES, and GBA (and probably all consoles until 3d became the norm) have hardware accelleration for tiled backgrounds, and virtually no accelleration for full screen images. You'd probably run out of video memory trying to write a full-screen background platformer on these systems, and you certainly wouldn't have enough to achieve any cool parallax effects.

You probably want to use two 2d arrays so you can store a tile graphic index as well as physical information about the tile (e.g. whether it's solid and can be walked upon). An array of objects (types) would achieve the same effect, it's a matter of preference.

If your tiles ever need to do something crazy, replace them with an identical looking sprite. This is how the pushable tiles in Zelda worked; after they had finished sliding 16 pixels, they'd turn back into a background tile!


WolRon(Posted 2005) [#7]
It just so happens that I am writing some example 2D platformer code for my website. It's not finished but if you are interested in seeing it, I could put up what I've got so far and finish it up as I go...

Also, as octothorpe was hinting at, you will probably want to be able to assign certain values to each tile. Theres a great program that can save you a lot of time by using it called Universal Map Editor. Try it out.


Crazy4Code(Posted 2005) [#8]
WolRon- I'd like to see it.

"If your tiles ever need to do something crazy, replace them with an identical looking sprite." That brings up another thing. I thought sprites and 2d images were the same thing? What makes a sprite a sprite?


Who was John Galt?(Posted 2005) [#9]
Yeah sprites and 2d images are one and the same. What Octothorpe is getting at is that you have an array containing background blocks which are drawn side by side. The blocks may be pasted on a grid at intervals of say 16 pixels by 16 pixels. To make a boulder jump from one background position to the next, just delete its value from the background array and paste it in an adjacent one - it will then be displayed 16 pixels across next time you display the background tilemap. To make it move smoothly between the 2 positions rather than jumping, you would have to create a type that can display the boulder at intermediate positions.


WolRon(Posted 2005) [#10]
I put it up on my site. It's got some extra crap in there that doesn't belong there (like the screenshot code, the stats code, and the one line that ends the game). But it's there for now. Most likely parts of it will change. I often rewrite my examples until I'm happy with how it's presented. I TRY to make them as simple as possible to read, yet give the coder the best techniques. (I'm not yet satisfied if there's a better way to do it...)

You probably want to use two 2d arrays so you can store a tile graphic index as well as physical information about the tile (e.g. whether it's solid and can be walked upon).
You don't need two arrays. You can enter all of that information into one array actually. If you use the Universal Map Editor I suggested above, it would take care of this for you anyways.


octothorpe(Posted 2005) [#11]
Sprites are 2d images which can move freely around the screen. The montage of 2d images that comprise a tiled background are typically restricted to being adjacent to each other and would not be considered sprites.


Crazy4Code(Posted 2005) [#12]
Wow, Map Editor looks great. It makes me feel like I'm cheating, but, it'll save me a lot of frustration and time.


IPete2(Posted 2005) [#13]
No no no!

Using Map Editor or a similar product... i.e. being efficient is NOT cheating - it's following the true route to programming, being effiecient. Do not think you are cheating.

IPete2.


Crazy4Code(Posted 2005) [#14]
Okay. I was doing other things, but I've decided to work on this. I've started and so far it's gone great. Here's what it looks like so far:

My little guy needs some serious graphical work :)
But anyways, what I need to do now is get the collisions working correctly. I've got the player-to-ground collision part working, but I'm having trouble with the player running into the side of things. Also, I need to test for collisions with blocks like the question mark blocks which will eventually let out a power-up. I need them to only work if the player hits it from underneath with the guys head. What is the best way to test for collisions like this?


Damien Sturdy(Posted 2005) [#15]
my GOD mario games are getting common now :)


Crazy4Code(Posted 2005) [#16]
That's what I hear. Anyone know what the best way to do this is?


octothorpe(Posted 2005) [#17]
Your graphics look way better than mine ever do, and there's nothing wrong with a Mario clone for a learning project! Why I chose Castlevania instead I'll never know.

I'm not sure about the *best* way, but I'll describe my method - which has given me good results for both regularly- and irregularly-sized sprites in a sidescroller. It's not robust enough to handle sprites moving faster than the width or height of a map tile per frame.

First, I determine which map tiles the corners of the sprite land in, and which tiles they would land in if the sprite was able to move without collisions. This lets me know which tile boundaries the sprite will be crossing - north, south, east, and/or west. If the sprite won't be crossing a boundary, it can be safely moved - I'm assuming that once a sprite is able to occupy some tiles, it'll always be free to roam around inside them.

For each tile boundary that the sprite will be crossing (it might be crossing both northwards and westwards in the same update) I check for solidity all the map tiles along that side of the sprite on the other side of the tile boundary. If nothing solid is found, it gets to move the full amount. If something solid is found, I move the sprite right up to the tile boundary and stop it.

I only bother checking the leading edges of the sprite: if the sprite is moving westward, the eastern edge of the sprite crossing a tile boundary is no cause for concern - the sprite is already occupying that tile.

I'd post some code, but it's extremely crude (it was my first Blitz project, years ago) and it emulates Castlevania physics, which are more than a little quirky.


octothorpe(Posted 2005) [#18]
Also, I need to test for collisions with blocks like the question mark blocks which will eventually let out a power-up. I need them to only work if the player hits it from underneath with the guys head. What is the best way to test for collisions like this?


I would suggest having your tile physics system set a boolean field (e.g. bumped_north) when a sprite's upward movement is stopped by a collision. During your player update, after it's been moved by the physics system, check for the boolean. If it was set, figure out which block was hit: If your player is the width of a map tile, there are one or two tiles above him - check the one he's closest to first, but if it's empty use the other one - he may have struck a block with only the side of his head! Now you just need to cause the appropriate response to occur depending on what kind of block was hit!

select map_logic(bonked_tile_x, bonked_tile_y)
	case BLOCK_LOGIC_SOLID
		player\headache = player\headache + 1
	case BLOCK_LOGIC_BREAKABLE
		map_logic(bonked_tile_x, bonked_tile_y) = BLOCK_LOGIC_EMPTY
		map_graphic(bonked_tile_x, bonked_tile_y) = BLOCK_GRAPHIC_EMPTY
		create_object(bonked_pixel_x, bonked_pixel_y, "exploded block effect")
	case BLOCK_LOGIC_MUSHROOM
		map_logic(bonked_tile_x, bonked_tile_y) = BLOCK_LOGIC_SOLID
		map_graphic(bonked_tile_x, bonked_tile_y) = BLOCK_GRAPHIC_SOLID
		create_object(bonked_pixel_x, bonked_pixel_y - 32, "mushroom")
end select



Crazy4Code(Posted 2005) [#19]
Thanks! That helps a lot.
I'm going out of town in a few hours, so I probably won't be able to work on it or post questions, but I'll start up again when I come back in about a week.


BlackD(Posted 2005) [#20]
I'm going out of town in a few hours, so I probably won't be able to work on it or post questions, but I'll start up again when I come back in about a week.

Town must be a long way away..

Nice work so far. :)

+BlackD


Ross C(Posted 2005) [#21]
Why not just do a rectsoverlap on every tile on the screen?


octothorpe(Posted 2005) [#22]
Ross C: That would tell you *if* your object has collided, but not how the object should react. Even if you collide, you probably want to move the last few pixels up to the object you've collided with before stopping.