Advanced platformer - the proper method

Learn how to make certain types of games and use gameEditor.

Advanced platformer - the proper method

Postby Hares » Tue Dec 24, 2013 10:54 pm

Hi

I am new to game-editor.
First of all, thanks to the people that made the software. And thanks to all the contributors to this forum.

For my first game I am trying to make a platform game. So for moving the player around I started out using the simple method. But there was a moonwalking bug I couldn't get rid off.
So I turned to the help section on the website and found the advanced platformer tutorial: http://game-editor.com/Advanced_Platformers

In the tutorial the principle is explained well. But the code that goes along with it has a lot of bugs.
To get the code to work for me I tweaked it.

To check whether the player is jumping or not I find it easier to use the "canjump" variable, than the "vdir".

The animations were always repeating the first two frames, so I added a variable "prevanim" (Actor, String). Then I use this to check if the "anim" string has changed since the previous frame.

The whole animation bit in the tutorial I found confusing, and I didn't get it to work. Instead I just use an animation for walking, and single frame animations for standing, jumping and ducking. This way all the animations can keep the option FORWARD, no need to change to STOPPED or NO_CHANGE.

Here is the code:
player -> create actor
Code: Select all
speed=4; //player speed
hdir=0; //horizontal dir 0 = facing right
vdir=1; //0=duck 1=stand 2=jump
jump=-20; //players jump ability (in negative numbers)
canjump=1; //can jump already
run=1;
strcpy(facing, "right");
strcpy(jumping, "standing");


player -> draw actor
Code: Select all
char * key = GetKeyState();  // This allows you to use keys as variables
float tspeed=0;              //tspeed is temporaryspeed.
char anim[32];               //our animation string


//reset variables

run=1;                      //reset run(until pressed)

if(vdir==0)
    {
    vdir=1;                 //ducking (vdir0) defaults to standing each frame (untill pressed again)
    }

tspeed=0;                   //reset tspeed to 0


//get keys and set the variables

if (key[KEY_DOWN]==1 && key[KEY_SPACE]!=1) //pressing down, and not pressing jump at same time
{
    strcpy(jumping, "ducking");     //for our animation
 
    if (canjump==1)                 //if we are not jumping
    {
        tspeed=0;                   //cannot move while ducking
    }

    vdir=0;                         //duck
}

if (key[KEY_SPACE]==1 && vdir!=2 && canjump==1)
{
    if (vdir!=2)                    //if we are not jumping already
    {
        vdir=2;
        yvelocity=jump*canjump;     //jump (if we have canjump)
        canjump=0;                  //prevents moonwalking
    }
    strcpy(jumping, "jumping");    //for our animation
}

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
    }
    if (vdir>0)
    {
        tspeed=-speed;            //if not ducking, we have normal speed (left is -)
    }
    strcpy(facing, "left");       //our direction for animation
    if (vdir==1 && canjump==1)    //or walking animation
    {
        strcpy(jumping, "walking");
    }
    if (vdir==1 && canjump==0)    //or jumping animation
    {
        strcpy(jumping, "jumping");
    }
}

if (key[KEY_RIGHT]==1)
{
    hdir=0;
    if (vdir>0)                  //for normal speed
    {
        tspeed=speed;
    }
    strcpy(facing, "right");     //our direction for animation
    if (vdir==1 && canjump==1)   //or walking animation
    {
        strcpy(jumping, "walking");
    }
    if (vdir==1 && canjump==0)   //or jumping animation
    {
        strcpy(jumping, "jumping");
    }
}

if (key[KEY_RCTRL]==1 || key[KEY_RMETA]==1)   //run button = right CTRL or right command button
{
    run=2;
    tspeed*=run;                 //make us go faster
    if (canjump!=0)              //if not jumping
    {
        strcpy(jumping, "running"); //set running animation
    }
}

if (vdir==1 && tspeed==0)        //if standing, and not moving horizontal
{
        strcpy(jumping, "standing");
}

//set animation string


sprintf(anim, "%s%s%s", "player", jumping, facing);


//set animation

if (strcmp(anim, prevanim)!=0)
{
ChangeAnimation("player", anim, FORWARD);
}


//now apply all movement to the player
if (health>0)                         //if health is zero or less, the player doesn't move
{
    x+=tspeed;                        //move the player if right/left was pressed
    yvelocity+=1;                     //gravity
}


//and set our prevdir for the next frame
prevdir=hdir;


//set our prevanim for the next frame
strcpy(prevanim, anim);


For the collisions I have to use 3 different collision events:

To prevent the player from falling through the ground & to reactive the canjump.
player -> collision top side of land -> repeat yes:
Code: Select all
PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1.0, 1.0, 0.0, 0.0);


if (canjump!=1)
{
    canjump=1;       //we can now jump again
}

if (vdir==2)    //if we were jumping
{
    vdir=1;     //we are now staning/running (or ducking)
}



To prevent the player from going through walls (left & right)
player -> collision any side of land -> repeat yes:
new variable: "player_yvel" (Actor, Integer)
Code: Select all
player_yvel=yvelocity;
PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1, 1, 0, 0);
yvelocity=player_yvel;


To prevent player from flying throught the bottom of land
player -> collision bottom side of land -> repeat no:
Code: Select all
yvelocity=1;


As it says in the original tutorial, all you need to add is the player animations with the names:
playerstandingright
playerstandingleft
playerwalkingright
playerwalkingleft
playerduckingright
playerduckingleft
playerjumpingright
playerjumpingleft
playerrunningright
playerrunningleft
Last edited by Hares on Sun Jan 12, 2014 7:04 pm, edited 1 time in total.
User avatar
Hares
 
Posts: 105
Joined: Fri Dec 20, 2013 8:39 pm
Location: Belgium
Score: 14 Give a positive score

Re: Advanced platformer - the proper method

Postby Hares » Wed Jan 08, 2014 10:03 pm

The key to make the player run is the right shift key.

But on a windows computer, if you hold the right shift for 8 seconds there is the accessibility option "filter keys" that gets activated.
This filter makes the keyboard ignore brief or repeated keystrokes. Not cool when you're playing a game ... :?

Turns out that the left shift key also has an accessibility shortcut. If you tap it 5 times "sticky keys" switches on.

Then I am thinking to change the run button to the right ctrl key.

But my question is this: does the KEY_RCTRL KeyState also look for the "command" button on mac?
User avatar
Hares
 
Posts: 105
Joined: Fri Dec 20, 2013 8:39 pm
Location: Belgium
Score: 14 Give a positive score

Re: Advanced platformer - the proper method

Postby skydereign » Sun Jan 12, 2014 11:55 am

Hares wrote:But my question is this: does the KEY_RCTRL KeyState also look for the "command" button on mac?

The right command key on a mac is bound to KEY_RMETA.
User avatar
skydereign
 
Posts: 3510
Joined: Mon Jul 28, 2008 8:29 am
Score: 589 Give a positive score

Re: Advanced platformer - the proper method

Postby Hares » Sun Jan 12, 2014 7:08 pm

Thanks skydereign

I changed the code in the original post for the running. Now it takes both the right contral and the right command button.
Also added an animation for the running.

Code: Select all
if (key[KEY_RCTRL]==1 || key[KEY_RMETA]==1)   //run button = right CTRL or right command button
{
    run=2;
    tspeed*=run;                 //make us go faster
    if (canjump!=0)              //if not jumping
    {
        strcpy(jumping, "running"); //set running animation
    }
}
User avatar
Hares
 
Posts: 105
Joined: Fri Dec 20, 2013 8:39 pm
Location: Belgium
Score: 14 Give a positive score

Re: Advanced platformer - the proper method

Postby Hammerit » Thu Feb 06, 2014 8:57 pm

Hares wrote:To prevent the player from falling through the ground & to reactive the canjump.
player -> collision top side of land -> repeat yes:
Code: Select all
PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1.0, 1.0, 0.0, 0.0);


if (canjump!=1)
{
    canjump=1;       //we can now jump again
}

if (vdir==2)    //if we were jumping
{
    vdir=1;     //we are now staning/running (or ducking)
}



To prevent hero to move on the ledge of block use this code.(suicide walking)
Just save actor X coordinate before collision with top side of land, because PhysicalResponse will reposition you character after collision.
Code: Select all
double tempXcoordinate = x; // saves x coordinate of player
PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1.0, 1.0, 0.0, 0.0);
x = tempXcoordinate;

if (canjump!=1)
{
    canjump=1;       //we can now jump again
}

if (vdir==2)    //if we were jumping
{
    vdir=1;     //we are now staning/running (or ducking)
}
Hammerit
 
Posts: 12
Joined: Sun Feb 02, 2014 9:52 pm
Score: 2 Give a positive score


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest