• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM How 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
scr_quadrants()




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
 
Z

zendraw

Guest
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
 

samspade

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

//then add that to your speed as you would with gravity
speed += momentum;

//or
hsp += hsp_add;
vsp += vsp_add;
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.
 
Z

zendraw

Guest
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.
 
Top