Posted: Wed Jan 05, 2011 10:28 am Post subject: How can I create a platformer?
What is it you are trying to achieve?
Create a platformer similar to Mario Bros.
What is the problem you are having?
Side-scrolling and platforms.
Describe what you have tried to solve this problem
My program uses velocity and gravity to determine the movement of the character so for the platform I try to reset the y velocity to 0 when you're ontop of it but then it doesn't let you actually jump off it unless you walk off and fall. For the side-scrolling, I haven't thought of that yet.
Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
Turing:
var chars :arraycharofboolean var x1 :int:=1 var x2 :int:= x1 + 10 var y1 :int:=1 var y2 :int:= y1 + 10 var xv :real:=0 var yv :real:=0 var g :real:=1 var ground :boolean:=true
setscreen("graphics:1200;900,offscreenonly,nobuttonbar,title:Player Movement Tutorial")
Please specify what version of Turing you are using
The latest version.
If someone could give me some kind of general outline on how to make this game it would be MUCH appreciated! Thanks!
Sponsor Sponsor
TokenHerbz
Posted: Wed Jan 05, 2011 11:02 am Post subject: RE:How can I create a platformer?
okay well first, Lets have your "JUMP" be aloud if the "mario" isn't actually in the air. So this way if he's even on the platform thats like above the ground, he can jump off as if he was on the ground.
I want you to put this inside a function/proc and get it working first
We should also make it so that the "collision" actually works, Like i try your program out and the "mario" is above the ground and the platform i jump on.
EDIT: unless im color blind and looking at gray (looks like background tho lol i dont see gray at all in the program tho) -- i must got terrible eye sight.
DemonWasp
Posted: Wed Jan 05, 2011 11:05 am Post subject: RE:How can I create a platformer?
Well, your platform has four sides. One prevents your player from moving up (the bottom), another prevents them from moving down (the top). You can probably figure out the last two.
If a player runs into the bottom edge of a platform, then they should stop moving upwards (though they can move downwards). All you want to do is check whether their velocity is up (positive, I assume) and if so, set it to zero. If it's down (negative?) then let it be, so they can fall away from the platform. Similarly for the top edge, except that you want to check whether they're moving down before zeroing their vertical velocity.
The trickiest part will be determining when a player has contacted a given edge. Treat each edge like a line, and only worry about one edge at a time. You need to consider the following cases (my language here assumes the top edge, modify as needed for the others):
1. The player is completely above the edge. (No collision)
2. The player is completely below the edge. (No collision)
3. The player is completely to the left of the edge. (No collision)
4. The player is completely to the right of the edge. (No collision).
5. The player is between the left and right bounds of the edge, and is partially above the edge and partially below the edge. (Collision!)
Really, you actually only need to detect case 5, you just have to make sure that cases 1-4 behave as you expect.
You will probably want to look into records in the Turing help files or in the Turing Tutorials sections here. Doing so will let you describe a platform relatively easily: you just need an (x,y) coordinate for the lower-left and a (width,height) size. That automatically gives you the coordinates of the top, bottom, left and right sides.
Spend some time with a pen and paper thinking about your player: they have an (x,y) coordinate, plus they have some dimension (width, height). Make sure you account for their size in your collision calculations.
Snario
Posted: Thu Jan 06, 2011 10:36 am Post subject: RE:How can I create a platformer?
Thanks for the input guys! I've taken your advice and created two platforms but now I have a small (very small) issue. For some reason when I jump from platform 2 to platform 1, I fall right through platform 1. Not sure what's going on. Here's the code:
%%%%%%%%%%%Variables%%%%%%%%%%%%% var chars :arraycharofboolean var marioX :int:=0 var marioWidth :int:=10 var marioX2 := marioX + marioWidth
var marioY :int:=0 var marioHeight :int:=20 var marioY2 := marioY + marioHeight
var marioXVelocity :real:=0 var marioYVelocity :real:=0 var ground :boolean:=true var platform1 :boolean:=false var platform2 :boolean:=false var plat1X1 :int:=300 var plat1X2 :int:=450 var plat1Y1 :int:=150 var plat1Y2 :int:=160 var plat2X1 :int:=700 var plat2X2 :int:=850 var plat2Y1 :int:=255 var plat2Y2 :int:=265
Posted: Thu Jan 06, 2011 6:49 pm Post subject: RE:How can I create a platformer?
This is happening because during the larger fall, the velocity per frame of your person is greater than the depth of the platform, so your person is on the top one frame, then underneath the next, it is never in the middle, which your code uses as a test to see if the player hit the platform. If you limit the speed your person can fall, they will not go through the platform (I tried 15 pixels/frame, which worked fine).
Snario
Posted: Fri Jan 07, 2011 8:17 am Post subject: RE:How can I create a platformer?
Here is an updated version of the code, I've fixed a few bugs but would like advice on how I can make this more friendly (more organized code).
%%%%%%%%%%%Variables%%%%%%%%%%%%% var chars :arraycharofboolean var marioX :int:=0 var marioWidth :int:=10 var marioX2 := marioX + marioWidth
var marioY :int:=0 var marioHeight :int:=20 var marioY2 := marioY + marioHeight
var marioXVelocity :real:=0 var marioYVelocity :real:=0 var ground :boolean:=true var onPlatform1, onPlatform2, onPlatform3 :boolean:=false var platform1LeftBoundary :int:=300 var platform1RightBoundary :int:=450 var platform1BottomBoundary :int:=140 var platform1TopBoundary :int:=150 var platform2LeftBoundary :int:=700 var platform2RightBoundary :int:=850 var platform2BottomBoundary :int:=255 var platform2TopBoundary :int:=265 var platform3LeftBoundary :int:=300 var platform3RightBoundary :int:=450 var platform3BottomBoundary :int:=390 var platform3TopBoundary :int:=400 var unlocked1, unlocked2, unlocked3 :boolean:=false %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Posted: Fri Jan 07, 2011 9:55 am Post subject: RE:How can I create a platformer?
(Before you start on the below, SAVE A COPY of your program with the name "MyProgram_Revision1.t" or similar. You can easily break things when doing extensive work as below, and I don't want you to lose your working program. Now...
Types, arrays, methods, files.
First, realise that you have several similar (identical) object "types". There are platforms, which have a top, bottom, left and right. There are creatures, which have an X and Y and XV and YV (position, velocity).
If you represent those objects more directly, your code will become simpler. For example, let's make a type that describes a single platform:
Turing:
type platform : record
top, bottom, left, right :int endrecord
This tells Turing that you want a new type of variable called "platform", and that it has "fields" called "top", "bottom", "left" and "right", all of which are integers. Then instead of:
Turing:
var platform1LeftBoundary :int:=300 var platform1RightBoundary :int:=450 var platform1BottomBoundary :int:=140 var platform1TopBoundary :int:=150
The syntax (variableName).(fieldName) refers to the field identified by fieldName inside the variable identified by variableName. You use this both for setting and getting the values.
You will now never run into an issue where you spelled top wrong in one place, and it's easy to modify platforms to all have additional variables. For example, you might add a field called isPlayerOn, a boolean, to take the place of onPlatform1, onPlatform2, etc.
Second, realise that you have lots of objects, and potentially want lots more. You have three platforms now, but potentially a few dozen for even simple levels. Do you really want to write collision code for that many platforms? No! Of course not. That's where arrays come in. An array is a group of variables, kept in a given order and accessed by their number. Your platforms could be:
Turing:
var platforms :array1..3of platform
or it could be:
Turing:
var platforms :array1..1000of platform
The difference is minimal: a one-line change. In your existing program, changing the number of platforms to 1000 would involve at least 4 more lines per platform. We'll discuss how you initialize your platforms in a moment.
Third, realise that you do the same thing in code many times. You have code to check for collisions with platform1, then with platform2, then more for platform3. Wouldn't it be easier if you had code that just checked any platform you gave it? Yes, yes it would. For example (I have stripped your code down a little; depending on what you choose to do with the onPlatformN variables, you will want to modify this):
Turing:
proc checkPlatformCollision ( p : platform ) if marioX2 >= p.left and marioX <= p.left and marioY2 <= p.top + 21and marioY >= p.bottom and marioYVelocity <= 0then
marioY := p.top + 1
marioYVelocity :=0 endif end checkPlatformCollision
for i :1.. upper(platforms)
checkPlatformCollision ( platforms(i)) endfor
That last bit will check against all platforms, no matter how many of them you have.
See how easy that is?
Now, take what I've shown you above and apply it further. You should be able to make a type for creatures (Mario is a creature), with a position and velocity. You may even want to have a "nested type": if you make a type for "position", with fields "x" and "y", then creatures have a "pos" field which has type "position". You should be able to modify the checkPlatformCollision method above to take one creature and one platform and check whether they collide; for the moment, you'll only be passing Mario as the creature, but I suspect sooner or later you'll start wanting to put goombas in the game, right?
Finally, you'll have to learn a bit about loading from files. Doing so will make your life a lot easier, because you won't have to change your program to add or change platforms at all, just a text file that it reads. However, to do that nicely, you'll have to implement all of the above first. Post back here when you want further guidance, or if you run into any problems.
Snario
Posted: Fri Jan 07, 2011 11:30 am Post subject: Re: How can I create a platformer?
Thank you very very much sir! I have edited my program to include types, arrays and better collision detection but I've encountered a bit of an issue where the detection doesn't actually work.. lol.
Here's what I've got:
Spoiler:
Turing:
%%%%%%%%%%%%%%%%%%%% %%%Mario movement%%% %%%%%%%%%%%%%%%%%%%% setscreen("graphics:1268;956,offscreenonly,nobuttonbar,title:Mario") %%%%%%%%%TYPES%%%%%%%%%%%%%%%%%%%%%%%%% type platform : record
top, bottom, left, right :int endrecord %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%%%%%%%%%%%Variables%%%%%%%%%%%%% var chars :arraycharofboolean var marioX :int:=0 var marioWidth :int:=10 var marioX2 := marioX + marioWidth
var marioY :int:=0 var marioHeight :int:=20 var marioY2 := marioY + marioHeight
var marioXVelocity :real:=0 var marioYVelocity :real:=0 var ground :boolean:=true var onPlatform :boolean:=false var platforms :array1.. 3of platform
var unlocked :array1.. 3ofboolean:=init(false, false, false) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Posted: Fri Jan 07, 2011 1:31 pm Post subject: RE:How can I create a platformer?
That would be because the code in checkPlatformCollision is wrong.
The easiest way for you to solve this problem is to completely forget the code that you currently have. Comment it out and then ignore it. Starting from scratch, figure out how to check whether your player has collided with a given side (start with the top) of a platform.
You know that if the player collides with the platform, the following will ALL be true:
1. The player's bottom is below the platform's top.
2. The player's top is above the platform's bottom.
3. The player's right edge is to the left of the platform's left edge.
4. The player's left edge is to the right of the platform's right edge.
Once you've figured out the if statement(s) that represent that, you should set the player's vertical speed to zero and their vertical location to the top of the platform (and set the onPlatform flag).
Snario
Posted: Wed Jan 12, 2011 10:08 am Post subject: Re: How can I create a platformer?
Alright I've made a lot of changes and am very satisfied with how my game is looking right now. I do however have a question for you guys...
Posted: Wed Jan 12, 2011 10:18 am Post subject: RE:How can I create a platformer?
Why not store your platform coordinates in a text file and then initialize them by reading from the text file.
DemonWasp
Posted: Wed Jan 12, 2011 10:46 am Post subject: RE:How can I create a platformer?
2goto1 is exactly correct. Learn about file input, using open and get (and presumably, close. Read up on those, then continue to my next paragraph.
Your file will need to give you just a few key pieces of information. First, you will need a count of the number of platforms in the file. This will let you create the array of platforms to the correct size. Second, you will need groupings of numbers, four to a line. These will be (left) (right) (top) (bottom), in whichever order you prefer, though you only get to choose ONE ordering.
You should be able to load all the platforms from the file using just a counted for loop.
Snario
Posted: Thu Jan 13, 2011 11:25 am Post subject: Re: How can I create a platformer?
Alright, instead of turning them into a text file, I just put them all into their own turing files and then used include. Here is the updated version that works (nearly) perfectly. If anyone could give me some suggestions on how the program can be improved, please do so.
(All three files are needed to run the game properly)
Posted: Thu Jan 13, 2011 3:49 pm Post subject: RE:How can I create a platformer?
The reason using text files are better, is because you can create one procedure with a file name parameter, which can load any map whose file name you send it. This will also make it a lot easier for your program to generate a map file in case you want to implement user created levels.
As for suggestions:
Create a trigger entity, that has a string type mapName property (and a box in which the entity is triggered), that when triggered, will load the new map. That way you can have a series of maps together.
Create obstacles for the player (and maybe even new weapons or tools to get past such obstacles)
Create a Main Menu with user profiles, with options for window size, a way to load a previously played map, and a a way to continue playing from where you left off.
Create a way for a user to create a custom map.
Snario
Posted: Fri Jan 14, 2011 10:57 am Post subject: Re: RE:How can I create a platformer?
TerranceN @ Thu Jan 13, 2011 3:49 pm wrote:
The reason using text files are better, is because you can create one procedure with a file name parameter, which can load any map whose file name you send it. This will also make it a lot easier for your program to generate a map file in case you want to implement user created levels.
As for suggestions:
Create a trigger entity, that has a string type mapName property (and a box in which the entity is triggered), that when triggered, will load the new map. That way you can have a series of maps together.
Create obstacles for the player (and maybe even new weapons or tools to get past such obstacles)
Create a Main Menu with user profiles, with options for window size, a way to load a previously played map, and a a way to continue playing from where you left off.
Create a way for a user to create a custom map.
Alright I'm starting to do that but I'm having a few issues.
Here is just a simple example program that will take some dimensions from the file called "platforms.txt" and then put them on the screen.
Turing:
var fileNo :int var noA :int:=0
var a :array1.. 29ofint var b :array1.. 29ofint var c :array1.. 29ofint var d :array1.. 29ofint
open: fileNo, "platforms.txt",get loop exitwheneof
noA +=1 get: fileNo, a (noA), b (noA), c (noA), d (noA) endloop close: fileNo
put noA
for i :1.. noA
put a (i), b (i), c (i), d (i) endfor