Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

2D All the way! / need help with platfromer game

Author
Message
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 1st Mar 2005 23:36
i want to know how to make a land like say a sonic or mario game and how to make the character stay on there while walkin, not walkin through i would also like to know how to put a simple gravity system in so the charchetr can jump and land on the platfrom. Can anyone help please?
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 1st Mar 2005 23:53 Edited at: 3rd Mar 2005 05:31
1) Making land: Mostly 2D platformers are made up of a grid system - the screen is divided into small squares and each one is filled with a picture. One way of doing would be to make an array. Say you wanted to divide your 640*480 screen into 20*20 squares, make an array 32*24 like so:

DIM screen(31,23)

The array is actually 32*24 because you can use the array elements numbered 0. Then you change the values of each of the array elements to represent a different type of tile. So for example you might have drawn a tile representing underground, another representing the surface of the floor and one representing the sky, you could decide that underground is 1, surface is 2, and sky is 3. Then you'd change the values in the array to build up the map. Later when you have to make levels properly and changing these individually (in our array there are 32*24=768 tiles so that would take ages) you might come up with a cunning level editor, for example drawing a 32*24 bitmap with different colours representing the different tiles, and then writing code that opened the bitmap, read the colours one by one and filled the array in accordingly. That's for later.

For now we'll just make a really basic looking map with two layers of ground, and a flat floor on top, with the rest being sky. To do this use the following code - if you don't understand what it's doing, ask.



That code can actually be simplified quite a lot by replacing it with:



Next you need to actually draw the level, because this array is no use unless it leads to the level actually being shown on screen. First, you need to open the images you want:



The extra 1's at the end of each line tell DBPro to keep the images pixel perfect instead of preparing them for texture usage. Next you should make a subroutine which draws the screen using these images. A subroutine should be used instead of putting all this code in the main loop of your program because it makes your loop much easier to read through and debug and just generally looks better.



Note that the code above will only work if the image numbers of the images you loaded are the same as the numbers you chose for the tiles in the array. It's a good idea to make this the case.

Finally to make your level draw you need to actually call your subroutine. To speed your program up you should also tell DBPro to only update the screen when it's finished drawing the level, otherwise it'll run really slowly. To do this put "sync on" at the top of your code, and a sync at the end of your main loop. Your code should look a little something like this:




Try out that. If you have any problems, let me know. If I've made a stupid mistake, let me know. When you've got all that working, let me know (woh... deja vu) and I'll write up the next stage - character movement, and stopping your character from falling through the floor.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 2nd Mar 2005 05:40
I sorry i forget to say i have db classic but i think this will work fine i hope, im gonna make a bitmap on paint for the florr ect and try it out tommoro, Ill let u know if i get it working, thanks for the help!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 2nd Mar 2005 06:31
I'm not sure if the extra ones on the load image commands work with DBC, I don't remember. Give it a try anyway.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 2nd Mar 2005 23:21
ok i tried it with some simple bitmaps of the same size, change load iamge to bitmap and took the 1s of the end cause it doesnt work and everything else seems fine but i get an error when running on line 47 ( next y ) wheer it says images range from 1 to 66535 or something so i dont know whats wrong
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 3rd Mar 2005 01:34 Edited at: 3rd Mar 2005 02:06
EDIT - ok, I made a really basic mistake (ain't it always the way?) the for x=1 to 32 loop in the Make Level Data section should be for x=0 to 32

EDIT 2 - Also, the numbers there are wrong too. I've changed them in my first post to fix it - I had it putting the underground at the top instead of the bottom.

EDIT 3 - And I've been making unnecessary (indeed invisible) tiles because I've been using 0 as well as the rest of the array. Array and loops made smaller too.

I promise to actually test code before I give it to you from now on lol

Why do you sink I ave zees outRAGEOUS accente?!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 3rd Mar 2005 02:57
Ok, first you're going to have to make an image which will be cut up to provide the frames of animation for your player. Mine is just a really basic stickman because, well, this is only a tutorial so I couldn't be bothered to put the effort in. The sprite frames are 20*20, but this isn't important as long as you alter the code I'll be giving you accordingly. Everything in the tutorial can be changed, indeed I recommend you change just about everything. Play about with all the values, add features you think sound cool, maybe add some more varied graphics, whatever. That's the way to learn. You'll just have to get keep a copy where you don't change everything because your changes might make any extra code I add not work.

My stickman has 4 frames of animation showing him running to the right. The frames are arranged left to right so I have an 80*20 bitmap, which I've saved as guy.bmp. Your next step is to make the program take the image, cut it up into frames, animate the result, position it and still show the background in the bits of your image that aren't part of the stickman. Thank god then for the create animated sprite command, because otherwise this could take a while to do. Put the following code somewhere before your main loop:



The command takes 5 parameters. The first is the sprite number, which is just the number you're going to use to refer to your sprite from now on. We'll use 1 because there are no other sprites in the scene yet. The next is the filename of the image you want to use, in my case "guy.bmp". The third and fourth numbers are important; they give the layout of the grid of frames in the image you've loaded. The third is how many frames there are across, and the fourth is how many there are down. So if you had a 16 frame animation and you didn't want to have a 320*20 bmp, you could use a 4*4 grid instead of a 16*1, and your bmp would be 80*80 in size. The 5th number is an image number you give to "guy.bmp", which is being loaded as in image. If you ever wanted to paste that image, you could do, but it seems unlikely that you would. Just make sure it's not an image number you've used for anything else.

So far your sprite has been created, but not positioned or animated. Lets make a subroutine to do this seeing as our main loop is nice and neat at the moment and it would be a shame to spoil that. Put the following some place in your subroutines section



And call the gosub in your main loop. You should know how to do that yourself by now. A note on parameters: sprite takes 4, the first is the sprite number, the 2nd is the x position of the sprite (0 means left hand edge) and the third is the y position (400 should see the player put on top of the floor) and the 4th is the image number you want to use - when we made the sprite we decided on 4, so lets stick with it. Play sprite takes 4 as well, sprite number, start frame, end frame and a delay value in milliseconds. We want the whole animation of 4 frames to play so we use 1 and 4 for the frames, and 100 for the delay means one frame will play every 1/10th of a second. So, what do we have now? We have a rather random screen, with a guy running on the spot, and not actually moving at all. Clearly the next thing to do is to let the player start controlling your character. To do this we're going to have to change the x and y coordinates of your player (well, only the x coordinate at the moment as the floor is horizontal and we haven't added jumping commands, but bear with me), so we need to replace 0 and 400 with variables, say x# and y#.




At the moment though, x# and y# have no value, so if you started the program now the man would be positioned at 0,0 - the top left corner. We therefore need to setup those variables. Obviously we don't put this in the main loop, or in the gosub (which is called by the loop), as then the position would be reset every loop and our guy would never get anywhere. Put it by the code where we made the sprite.



Now we just need to move the guy about. We'll use the arrow keys for this. Whenever the player presses right we want to increase x#, and whenever they press left we want to decrease it. The following code does this if put in the updatePlayer sub. If it runs too fast, just decrease the value and vice versa.



Finally we have some interactivity, but two things stick out as being odd. One; your guy can run right off the edge of the screen. Two; the guy runs right even when he's running left. I'm not going to tell you how to fix these yet though; see if you can do it yourself, it shouldn't be too hard. I'll go through it with you next time.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 3rd Mar 2005 03:16
Ok with ur updated code it still doesnt work so its prbably dbClassic also create animated sprite isnt in classic but i made a walkin sprite program before i posted first so i'm okay with that, just to lazy to make it walkin left aswell lol


That was my code just not bothered to make him walk left properly, ill keep messin about with the landscape code to try and get it workin but if u get it 1st let me know, thanks!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 3rd Mar 2005 03:31
what i think is wrong is that when you use
paste image screen(x,y),x*20,y*20
the screen(x,y) is supposed to be the image number isnt it so the program thinks the image doesnt exist as whenever i run its either image does not exist or
images range from 1 to 66535
what do you think?
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 3rd Mar 2005 05:30 Edited at: 3rd Mar 2005 05:32
See edit 1 two posts above. I just neglected to change it in the final code of the first post. All fixed now though.

Why do you sink I ave zees outRAGEOUS accente?!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 3rd Mar 2005 06:15
Here is the corrected code as it stands so far. I've included corrections for DBC, although I haven't actually tested in DBC I think it ought to work. I've left in the DBPro stuff though because people using DBPro might find this useful too. I've also added in code to make the character stop at the edges and run left/stand still as well as running right. It should be fine, tell me if it's not. For DBPRo users out there, guyPRO.bmp is a 160*20 bitmaps with right running frames on the left and right running frames on the right. Frames 1 and 5 and included in run animations but look like the guys standing still, which means I don't need to add extra frames for that. The only bug I know about is DBPro specific, and is that the sprite will finish it's current play cycle (finish running 4 frames right for example) before changing when you stop or change direction. I can't find a stop sprite playing command so I'm not sure how to fix that.



Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 3rd Mar 2005 23:51
Ok i've edited a bit of your update player code because it wasnt working for me so here is the code i have up to now



But there are 2 problems with it
1. there is no background or floor
2. when turing left and walking it has to have to go the frames walking backwards

any ideas how to fix this?
Also if you want the walkinman.bmp ive attached it
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 4th Mar 2005 01:29
Probably the reason my code didn't work for you was that you're using a five frame bitmap and I'm using a four. Oh well, you're code looks fine too, if a little less compact.

1) You're loading the images for the character as numbers 1-10, but the background images are numbers 1-3, so you ought to be using 4-13.

2) Yes it does. You just need to cut the image up backwards to fix this, it's because of the way the drawings work in animation.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 5th Mar 2005 03:35
Ok about wot i said before

1.Ive changed the code and image numbers to fit but still no background here's my code if you want to have a look



and
2. I meant that he doesnt walk backwards say i was on the last frame of the right walking stance then I turn left it has to walk backwards through the right stance before turing left and walking properly and i cant think of a way to fix this any ideas ?

Ill keep playing around with the code incase i figure out how to do it myself once again thanks for your help with this
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 7th Mar 2005 01:59
Hi, sorry I haven't replied in a while; I've been snowed under with school work and a new job. I don't know why you don't have a background but I'll look into it; I do know why he's not turning round right, and I'll try to fix it. It might be a few days before I get it all working though.

Same time as I post that lot I'll post the next phase of the tutorial; gravity.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 8th Mar 2005 23:48 Edited at: 9th Mar 2005 23:21
I managed to fix the walking problem, it was because when u turn around say when u was on frame 2 i just made it so it was frame + 1 so it had to get to the left walking sprite to get into the loop 1st, i changed this by putting a less than, if and then statement at the start of checking the left key

Im nobody, and nobody is perfect, therefore im perfect!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 11th Mar 2005 05:31
Good work. Did you fix the background thing too? I don't know what's causing that. I have to get some revision done tonight for a physics exam in the morning but tomorrow afternoon I should be able to add gravity to the game.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 11th Mar 2005 23:30 Edited at: 11th Mar 2005 23:32
Yes i somehow luckily found out how to fix the background all i did was delete bitmap 4 (the walkin sprite) after i loaded in the pics and it worked also i have made the drawScreen sub just part off the startup because it seemed to slow the man downso now everything seems to be working fine. I'm looking forward to the gravity thing when you do it, thanks again

Heres my code again


Im nobody, and nobody is perfect, therefore im perfect!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 12th Mar 2005 04:39 Edited at: 12th Mar 2005 04:40
Damn, I just finished typing up that gravity post, and managed to delete it by accident while I was editing some code. This next version may be shorter, terser and less well explained, sorry about that.

First an introduction to gravity:

Gravity is a force, and will be taken in our game to act with a constant magnitude and straight down. By Newton's second law,

Force = Mass * Acceleration

Mass (the man's) is constant, so if force is too then acceleration must also be. So we can decide a single value for acceleration due to gravity and leave it alone. This also means that in order to model gravity fairly realistically, all we have to do is add that constant value to the man's vertical speed each loop, and add that vertical speed to his vertical position. So: in the "setup player" section we add



And in "update player" we add this:



0.05 is just a value that works well on my computer; you may need to adjust it. vs# is 0 at the moment because we don't want the guy to start off falling. Try running the code now. The man should fall straight through the floor. While this allows you to gauge the strength of gravity that using 0.05 gives you and allows you to fiddle it till you have the right value, clearly it's not something we want to keep, so our next step is to add code checking that all squares underneath the guy's feet are sky squares, and stopping him from falling if any of them are. The square directly beneath his left hand edge is given by screen(int(x#/20),int(y#/20)+1) as x# and y# are in pixels which are 1/20 * as big as the squares, and the square below has the same x-coordinate and a y-coordinate one greater than the guy. The int()'s are there because we can't ask for the 12 and a halfth box in an array; only whole numbers are defined. However, this isn't good enough. For one thing, there may be no part of the man's foot region touching that bottom left hand edge - in my stick-drawing there are 8 pixesl before the first foot appears, so I need to add 8 to x#. screen(int((x#+8)/20,int(y#/20)+1). For another, the square underneath that edge isn't necessarily the only one we need to check. If he was standing between two squares then having ground on either side of him would be enough to make him stop. Therefore we need to check the right edge too (there is no need to check in his middle because he is only as wide as one square). In my drawing there are 17 pixels from the left edge to his right foot, so the code referencing this square is screen(int((x#+16)/20,int(y#/20)+1).

The code we want then, looks like this (in the "update player" section)



This asks if both of the two possible squares is sky, and if it gets the answer no, reduces y# by the amount it was previously increased by so that the man doesn't move overall, and instantly cuts vertical speed to 0. So far so good, but running the program now would be pretty boring. Nothing would have changed at all since the version I posted last week, because the guy's not falling anymore, and there's no way to make him jump yet. So, here's the jump code (in "update player")



Again, you might have to fiddle with the value vs# is set to to make it work well on your computer. vs# is negative because increasing the y-coordinate indicates a move down, not up. I added "and vs#=0" so you can't jump while in midair. The use of the new variable 'space' means that you can only jump once per spacebar-press.

And that's gravity just about finished. Now we need to test the jump code with a bit of a playground. Add the following to the "make level data" section, after the loop that sets up the level how we've had it so far.



This'll make some hills and a floating platform to play on. Run it, and you should quickly notice a stupid problem - we can run straight through walls, and jump into them too. This is because so far we never check, anywhere in our code, whether we have run into a wall, or jumped into one from below. This is understandable - until we added those extra features to the level this was never a risk, so it never occurred to us. We do need to fix it though, with another block of code in the "update player" section. You can either just add the code below, or you can try to work it out yourself, and use the code below if you get stuck. Up to you. Again, some of the numbers will have to be adjusted to make them fit your guy graphic.





My code is still a bit bug-ridden. Depending on which way you're running it may or may not be possible to jump when you're touching a wall. If you jump into a wall you can hang there by walking towards the wall, stuff like that. I'll work on them sometime later and get them fixed. You may be able to fix them for your code yourself.

After that I'm not sure what to add to this little tutorial... you can probably work out code for scoring systems and collecting items yourself, AI/enemies sounds rather too much like hard work, although I could do it if you'd like me to. I could make you a bitmap based level editor if you like... dunno.

Anyhow, here's my code so far. Yours will look somewhat different obviously, but if you don't know where bits of code go or I've missed out some crucial step that's in my code but I forgot to write into this post you should be able to work it out from there.



Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 14th Mar 2005 01:40 Edited at: 14th Mar 2005 01:41
Hmm i cant get this gravity thing working well the thing is my persons graphic is as tall as 4 squares so he can walk through the squares that are 1-3 squares tall (probably because I cant fuigure out my guys graphic to this part of code)


Also for some reason my man doesnt jump when I press space so theres no point in there being any gravity at the moment.
Heres my code



could you please go over the 1st code snippet i put up so i can get it working for my guys graphic plz?

Im nobody, and nobody is perfect, therefore im perfect!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 15th Mar 2005 05:18
Ok, with the 1st snippet you just need to add lines that will check all the other squares that need to be checked, not just the one that I did. It's all rather slow and boring to work out though, so I think I'm going to leave you to try it for a while if that's ok. Try to work out how I did my squares, and then apply it to the rest.

I think one of the problems with your code that's not letting you jump is that you've used g# in the update player code, but gravity# in the make character data bit. On the other hand, looking through your code quickly I think at the moment it should be making your character fly off the screen at a steady pace when you press spacebar, not just doing nothing, so I must have missed something.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 15th Mar 2005 23:48
could i use the sprite hit() command to make him not walk though walls and the fall? if i could somehow change the level maker so it builds the level with sprites instead of images would that work?

Im nobody, and nobody is perfect, therefore im perfect!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 16th Mar 2005 05:28
You sure could, and it sure would.

Why do you sink I ave zees outRAGEOUS accente?!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 16th Mar 2005 23:03
thanks ill try that now or soon or later lol

Im nobody, and nobody is perfect, therefore im perfect!
Matrix Man
21
Years of Service
User Offline
Joined: 27th Jul 2004
Location:
Posted: 18th Mar 2005 23:30 Edited at: 18th Mar 2005 23:32
i cant get it to make the level with sprites it says bob does not exist highlighting the sprite hit() command

i havent chnaged much so i dont see why it doesnt work it also doesnt work without the sprite hit() command



any help please?

Im nobody, and nobody is perfect, therefore im perfect!
Monsieur Mort
21
Years of Service
User Offline
Joined: 12th Feb 2005
Location:
Posted: 19th Mar 2005 02:08
Well you're trying to place a sprite numbered (screen(x,y)). That means you'll have one sprite for each type of square which will move through all the positions each loop, which is not what you want. In addition, where screen(x,y)=1 you'll be moving the player sprite not the sprite you want.

if sprite hit(4,2)

That line is wrong, because it's asking if the sprites numbered 4 and 2 are touching. There are two problems with this: one: one of the numbers should be the number of the person sprite, because you're trying to check if the person is touching the ground or not. Secondly, you don't just want to check if he's hit a particular sprite with number 4 or 2, you want to make sure he's not touching any sprite which is representing a square representing the ground.

You're going to have to come up with a system of assigning each square a sprite number (all 768 of them) and then where you want to position sprites or check if they're touching you'll have to use for loops to check all relevant squares. Sprite hit doesn't really help you at all to be honest, personally I would stick with the old way.

Why do you sink I ave zees outRAGEOUS accente?!

Login to post a reply

Server time is: 2026-07-14 08:22:33
Your offset time is: 2026-07-14 08:22:33