YoYo Games Wiki

Slopes

From YoYoGames Wiki

Slopes

Many simple platform games just use square tiles for collisions, but more advanced games may want to use slopes. This is one way I have found that is very accurate and runs fast enough (though it does use many collision tests).


Code


  angle=270;   
  max_angle=60;
  cosine=cos(degtorad(angle));
  sine=sin(degtorad(angle));  
  i=0;
                                                                                                                                                           
  while( place_meeting( x+cosine*hspeed , y-sine*hspeed, solid ) && i < max_angle)
  {
     angle+=1;
     cosine=cos(degtorad(angle));
     sine=sin(degtorad(angle));
     i+=1;
  }
  return angle;

This basic code will return the angle of motion to move up or down any slope. First it sets a starting angle. I used 270 which is directly below the object. You could use something a little greater depending on when you wanted the object to stop following a slope downward. Next is finds the cosine and sine of the angle. The cosine multiplied by the speed tells us how far left or right to check and the sine times the speed tells us how far up or down to check. you subtract sine from y because the y axis is reversed on a computer. The code then checks if there is a collision with a solid object at the position, if there is then it adds one to the angle, updates the cosine and sine, and checks again, if not then it returns the current angle. The max_angle variable is used to set what the maximum degree of slope your player can traverse. Once you know the angle to move in you then update x and y by

x+=hspeed*cosine;

y-=vspeed*sine;

This will not work if you are using the normal hspeed and vspeed variables though.


Now the first thing you may notice is that this uses a lot of collision test. This can be avoided by changing the value you increment the angle by every time. This will lower accuracy but greatly improve the speed. If you change the increment from 1 to 12 you are checking at max 1/12 of the times as before. You would need to change the increment on the i variable as well so that max_angle still works.

The next problem you may find is that if the hspeed is less than 0 the code will cease to work. This is because when the hspeed is negative the angles are reversed, so 270 becomes 90, so you must reverse your starting angle and your increment. This is demonstrated in the following code.

Code


  if(hspeed>0)
  {
     angle=270;
  }
  else
  {
     angle=90;
  }
      
  max_angle=60;
  cosine=cos(degtorad(angle));
  sine=sin(degtorad(angle));  
  i=0;
                                                                                                                                                           
  while( place_meeting( x+cosine*hspeed , y-sine*hspeed, solid ) && i < max_angle)
  {
     if(hspeed>0)
     {
        angle+=1;
     }
     else
     {
        angle-=1;
     }
     cosine=cos(degtorad(angle));
     sine=sin(degtorad(angle));
     i+=1;
  }
  return angle;

Two more problems of this code is that if you are in the air then you must start off at angle 0 otherwise you will go straight down. Also sometimes this code will leave the play slightly off the ground this may or may not be a problem for you game. There are ways to fix both problems( i know i have fixed them) but i will let you decide what is best for your game.

On one final note you will probably want to put this code in a script because many objects will use it.

Hopefully this will help you.

--Sonicfreak 23:57, 23 September 2008 (UTC)