# Legacy GMHow to have a character base his speed on the ground angle.

D

#### Dopaminestudios

##### Guest
Hello GMC!
So I've been working on a sonic-esque platforming engine. I have the player able to move in all 360 degrees without any hindrance. I'm having trouble with getting the player to slow down when going up the hill and speed up when going down a hill. My engine is based on having 2 sensor dots, one in front of the player and one behind the player. These dots ride along the ground and finds the angle between the front and the back dot. This is put into a global.angle variable that sets the players position.

obj_player_step_1
key_left = keyboard_check(vk_left)
key_right = keyboard_check(vk_right)
key_jump = keyboard_check(vk_space)

if (key_right){
x_speed = -3
}
if (key_left){
x_speed = 3
}
if (!key_right && !key_left) || (key_right && key_left){
x_speed = 0
}

if (global.state = 1){
if (place_free(x,y+1)){
y+= grav
}
}else{
if (global.state = 2){
if (place_free(x+1,y)){
x+= grav
}
}else{
if (global.state = 3){
if (place_free(x,y-1)){
y-= grav
}
}else{
if (global.state = 4){
if (place_free(x-1,y)){
x-= grav
}
}
}
}
}

x += cos( degtorad(global.angle)) * x_speed
y -= sin( degtorad(global.angle)) * x_speed

image_angle = global.angle

obj_sensorA_step_1

if (global.state = 1){
x = obj_player.x + 5
y = obj_player.y + 15
}

if (global.state = 2){
x = obj_player.x + 5
y = obj_player.y - 15
}

if (global.state = 3){
x = obj_player.x - 5
y = obj_player.y - 15
}

if (global.state = 4){
x = obj_player.x - 5
y = obj_player.y + 15
}

if (global.state = 1){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
y-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x,y+1,obj_solid)){
while (!place_meeting(x,y+1,obj_solid)){
y+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

if (global.state = 2){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
x-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x+1,y,obj_solid)){
while (!place_meeting(x+1,y,obj_solid)){
x+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

if (global.state = 3){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
y+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x,y-1,obj_solid)){
while (!place_meeting(x,y-1,obj_solid)){
y-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

if (global.state = 4){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
x+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x-1,y,obj_solid)){
while (!place_meeting(x-1,y,obj_solid)){
x-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

x += cos( degtorad(global.angle)) * x_speed
y -= sin( degtorad(global.angle)) * x_speed

obj_sensorB_step_1

if (global.state = 1){
x = obj_player.x - 5
y = obj_player.y + 15
}

if (global.state = 2){
x = obj_player.x + 5
y = obj_player.y + 15
}

if (global.state = 3){
x = obj_player.x + 5
y = obj_player.y - 15
}

if (global.state = 4){
x = obj_player.x - 5
y = obj_player.y - 15
}

if (global.state = 1){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
y-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x,y+1,obj_solid)){
while (!place_meeting(x,y+1,obj_solid)){
y+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

if (global.state = 2){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
x-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x+1,y,obj_solid)){
while (!place_meeting(x+1,y,obj_solid)){
x+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

if (global.state = 3){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
y+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x,y-1,obj_solid)){
while (!place_meeting(x,y-1,obj_solid)){
y-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

if (global.state = 4){
if (place_meeting(x,y,obj_solid)){
while (place_meeting(x,y,obj_solid)){
x+=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}

if (!place_meeting(x-1,y,obj_solid)){
while (!place_meeting(x-1,y,obj_solid)){
x-=1
}
global.angle = point_direction(obj_sensorA.x,obj_sensorA.y,obj_sensorB.x,obj_sensorB.y)
}
}

x += cos( degtorad(global.angle)) * x_speed
y -= sin( degtorad(global.angle)) * x_speed

#### zendraw

##### Member
first, how do you build the ground, second how do you take the ground`s angle, third make sure you get the angle of the ground, and lastly speed=angle_difference(90, ground angle)/180; you may need to shift 90 and ground angle but thats the basic idea for me

D

#### Dopaminestudios

##### Guest
I just draw the ground and make it have a precision mask. I take the difference in angle between the two sensor dots using point_direction function. I'm not sure about the last one

D

#### Dopaminestudios

##### Guest
I draw the ground in a sprite editor

##### Member
I draw the ground in a sprite editor
I haven't actually tried this, but one thing that might work is the following:

Code:
``````//one of the following two lines depending upon how you're doing your movement
//I know you posted the code but it was long and not in code brackets
//so I only skimmed it.

move_angle = point_direction(xprevious, yprevious, x, y);
move_angle = point_direction(0, 0, x_speed, y_speed);

//then get the momentum to add
if (move_angle != 0) && (move_angle != 180) {
if (move_angle < 180) {
var angle = abs(angle_difference(move_angle, 90));
var percent = angle / 90;
momentum = -max_momentum * percent;
} else {
var angle = abs(angle_difference(move_angle, 270));
var percent = angle / 90;
momentum = max_momentum * percent;
}
}

//if you need to return separate vertical and horizontal speeds then
hsp_add = lengthdir_x(momentum, move_angle); //I think
vsp_add = lengthdir_y(momentum, move_angle); //I think

speed += momentum;

//or
There may be errors in the above, but the basic principal is get the angle of movement by using either the objects current vertical and horizontal speed or it's relation to it's past self then add some momentum based upon that angle. The middle portion is fancier than probably needed but it translates the movement angle into a positive number less than 90 degrees and then uses that to get a percent of straight up and straight down to figure out a percent of momentum to apply and then applies that momentum.

#### zendraw

##### Member
if you have the angle, then your set to go.
this -> speed=angle_difference(90, ground angle)/180;
is just the logic you need to apply, speed is not nececerly speed variable in GM.
your code is a big mess and i dont have that much time to look up everything, get the logic, edit it and so on. the logic of the code i post is this. 90 is upwards, 270 is downwards, and difference betwean both is 180, this you divide by 180, and you check how close are you to 90, the closer you are to 90, the angle, the slower the lower the resault of angle_difference(90, ground angle)/180 is, the more you are to 270, the higher it is. but this code as it is will return only betwean 0 and 1, so you need to multiply it. like in helathbars, the formula is the same. so speed=(angle_difference(90, ground angle)/180)*move_speed;
now instead using = you can use += to add so to create the effect of momentum etc. but like i said, the formula is the basic health formule (hp/mhp)*healthbar. but here you calculate hp with angle difference. another thing thou, cus it returns also negative numbers, you must abs() the thing. so the final formula is
speed=(abs(angle_difference(90, ground angle))/180)*move_speed;
abs simply makes a negative value, positive.

D

#### Dopaminestudios

##### Guest
Thank you guys and yea sorry about the code i didn't have much time to clean it up.