Basics of a platformer

From Game Editor

Jump to: navigation, search

Game Editor is a good program to make platform games, which is another word for a jump'n run.

What is a platformer?

A platformer is a game, where you can move to the left and right. At the bottom there is the ground and the sky is in the top. In most platformers you can jump, in the view the player moves upwards in the sky. You can find an example for Game Editor called Caveman.

How to start

First of all you need your player, who you can move to the left and right. Add a new actor. The player should have at least four animations: two standing animations, left and right and two walking animations to the left and right. You can add many more animations later, such as jumping or running. Now you have to add two key down events for moving left and right. When moving left, the animation should be changed to moving left. You can make the moving either with reduce the actor's x position by each frame or you change the value of xvelocity to a negative number. Do the same with the inverted direction. Don't forget to set xvelocity back to 0 when releasing the moving keys. Your player should be able to walk now.

Now your player should be able to jump. Set yvelocity to a negative number (e.g. -10) when pressing the jumping key. The yvelocity should be bigger in the draw actor event to get a quite realistic gravity effect.

Your player will either fall down infinitely or you press the jump key to let him jumping. The ground is still missing.

You should make the ground and walls with tiles. Add a new actor and give him an animation for the tiles. Add the collision event for the player with the tiles. Use the function PhysicalResponse to let him stop at the ground.

Examples

There are several ways to make anything, not just one right way.

So here is a simple example and an intermediate example.

The intermediate example is a proper way to script movement so that you can make a complete game with it. There are other proper ways, this is just one of those.

There are simpler examples, and I know many of us, when we were new to programming, just wanted a simple way to make an actor move. If that's what you want, then here's the simple method:


Simple Example

KeyDown event -> left

xvelocity = -4;
ChangeAnimation("player", "walk_left", FORWARD);

KeyDown event -> right

xvelocity = 4;
ChangeAnimation("player", "walk_right", FORWARD);

KeyUp event -> left

xvelocity = 0;
ChangeAnimation("player", "stand_left", FORWARD);

KeyUp event -> right

xvelocity = 0;
ChangeAnimation("player", "stand_right", FORWARD);

KeyDown event -> space (jump)

yvelocity = -10;

DrawActor event

yvelocity += 0.5;


This will get your character moving, but is not much easier to input, and impossible to control or adapt later in the game creation. Simple things like adding attacks and hits or invincibility to these methods are incredibly difficult.

I urge you not to take that path; YOU WILL NOT BE ABLE TO MAKE A GAME WITH THE SIMPLE METHOD. At best, you will make a 1 level demo that doesn't really do much, and YOU WILL HAVE TO UNLEARN THAT METHOD SO THAT YOU CAN LEARN THE RIGHT ONE.

Proper Example

Using this example, you can make your character follow the basic rules of SuperMarioBrothers games.

For this example, first make a few actor variables using the variables tab.

  • speed (actor, real)
  • hdir (actor, int)
  • vdir (actor, int)
  • jump (actor, int)
  • canjump (actor, int)
  • run (actor, real)

Player>CreateActor>ScriptEditor>

speed=4; //you can adjust this anytime, player speed
hdir=0;  //horizontal dir 0 = facing right
vdir=1;  //0=duck,  1=stand, 2=jump
jump=-12;  //player's jump ability (in negative numbers)
canjump=0; //cannot jump yet
run=1;    //

Now we've set the starting variables, we'll capture the keys and output the character action based on them.

Player>Draw Actor>

char * key = GetKeyState();  // This allows you to use keys as variables 
float tspeed=0;          //tspeed is temporaryspeed.
run=1;                  //reset run (until pressed)
if(vdir==0){vdir=1;}         //ducking(vdir0) resets each frame (until pressed)
//get keys and set the variables
if(key[KEY_DOWN]==1){
 if(vdir<2){ //if we are not jumping
vdir=0;                      //duck!
tspeed=0;                  //cannot move while ducking!
}
else if(vdir==2){ //if we are already in a jump
vdir=0;                    //duck!(While jumping!)
tspeed=speed;            //speed as normal!
               } }
if(key[KEY_SPACE]==1 && vdir!=2){ //if we are not jumping
yvelocity=jump*canjump;           //jump! (if we have canjump!)
canjump=0;                        //prevents moonwalking
}
if(key[KEY_LEFT]==1){
hdir=1;                        //1=left, 0=right
if(vdir==0){ //ducking
 tspeed*=-1; //if jumpducking, tspeed already==speed, so just set the +-.
 //if we're normal ducking, tspeed is 0, so it will stay that way.
 }
else if(vdir>0){
tspeed=-speed;  //if not ducking, we have normal speed (left is-)
               }}
if(key[KEY_RIGHT]==1){
hdir=0;
if(vdir>0){      //for normal speed
 tspeed=speed;
 }
}
if(key[KEY_RSHIFT]==1){ //run button
tspeed*=run;        //make us go faster!
} 

//We now have all the variables we need to control the player! //So underneath that script, add this:

switch(hdir){        //first, we account for direction faced
case 0:               //facing right
 switch(vdir){          //now we nest the jump/stand/duck 
  case 0:                  //we are ducking;
   ChangeAnimation("Event Actor", "duckright", NO_CHANGE);
  break;
  case 1:                  //standing/walking
    if(tspeed==0){
     ChangeAnimation("Event Actor", "standright", NO_CHANGE);
    }  //if right and left aren't active, then stand still.
    else if(tspeed>0){
     ChangeAnimation("Event Actor", "walkright", NO_CHANGE);
    }   //otherwise, walk!
  break;
  case 2:                  //jumping
   ChangeAnimation("Event Actor", "jumpright", NO_CHANGE);
  break;
  }//end jump/duck/stand switch
 break;
 case 1:            //facing left
  switch(vdir){      //jumpduckstand again
   case 0:
    ChangeAnimation("Event Actor", "duckleft", NO_CHANGE);
   break;
   case 1:
    if(tspeed==0){
     ChangeAnimation("Event Actor", "standleft", NO_CHANGE); 
     }  //if right and left aren't active, then stand still.
    else if(tspeed>0){
     ChangeAnimation("Event Actor", "walkleft", NO_CHANGE);
    }   //otherwise, walk!
   break; 
   case 2:
    ChangeAnimation("Event Actor", "jumpleft", NO_CHANGE);
   break; 
   }//end duckjumpstand switch
  break;
 }//end facing direction switch;
 //
                  
 xvelocity=tspeed;  //move the player if right/left was pressed
 yvelocity+=1; //gravity


Then on Player>Collision>TopSide>Block>RepeatYes>Script Editor>

PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1,1,0,1);
canjump=1;      //we can now jump again!
if(vdir==2){ //if we were jumping
vdir=1;      //we are now standing/running (or ducking if you want)
}

And when player falls off a cliff, we need to turn off the canjump. Player>DrawActor>ScriptEditor (the same one we used above, not a new one):

if(yvelocity>2 && canjump==1){   //if player falls off a cliff and is 
//moving downward and has not jumped since leaving the cliff
canjump=0;       //player cannot jump now
vdir=2;        //falling is the same as jumping
}

Notice that you don't need any KeyDown or KeyUP events for this script to work!

The next step would be to create another variable to explain the user mode: normal, hurt, attack, invincible, and die, as an int (0-5). This would become yet another case switch nested inside the standjumpduck switch.

Still, this is not a perfect example, because the nested case switches make things complicated eventually, but it explains how to get things done the proper way. You CAN MAKE A GAME this way. And once the playerstate switch is nested inside the vdir switch, you shouldn't have to add any more switches. Basically, once you add the state switch, you have a complete player script for a platformer game.

If you want to create different sets of player animations, i.e. big mario, raccoon mario, then take the entire switch part of the draw actor and make it into a global function, then make a copy of it too and fill in the other animation names. Then you'd be calling the animation by function names, such as: bigplayer(vdir, hdir, pstate, tspeed); raccoonplayer(vdir, hdir, pstate, tspeed);

And you could choose that via a switch too.


And of course, we've got a complete interaction system going here already, which cannot be made from the simpler examples. Adding attacks to the simple methods and trying to synchronize them with jumping and running...is much harder than this method.

What would be even better is to take the hdir,vdir,and canjump variables and run them through an algorithm that can output the proper actions, probably using some stringwork to create new commands and animation cues, as some GE users have done, or simply choosing a state from a list of states. And if you were wondering, these other methods would be COMPLEX EXAMPLES, thus the method described here is Intermediate. (no string sprint stuff needed.)

If you have another example, please add it to this page as its own example.