N
NeZvers
Guest
GM Version: Should be universal
Target Platform: ALL
Download: N/A (all needed code is there)
Difficulty: Intermediate
Last Edited: 2018.08.10
Short version:
Rotation after dealing with movement collision. Classic while loop checking but this time rotate image_angle to previous position.
Off-topic:
There are plenty tutorials that show how to rotate image but they all doesn't rotate collision box and that's useless when you actually need it.
I tried to make my own top down 2D GTA car movement and I got pretty nice controlls with satisfying drifting, but as soon as I introduced solid walls... crash every time (actually freeze) since I used classic while loop movement collision and turning car into wall with no movement gives infinity while loop. I couldn't find any tutorials so I started to try box2d physics with somewhat ok movement but collisions felt wonky. I don't know why I couldn't think about this simple solution but now it's here.
Longer version:
I'll give SUPER bare bone basic car movement (no drift and and fancy things), but maybe I'll do part 2.
PS:
Sorry for my English and I hope it's useful for someone frustrated as I was when searched for a solution.
Target Platform: ALL
Download: N/A (all needed code is there)
Difficulty: Intermediate
Last Edited: 2018.08.10
Short version:
Rotation after dealing with movement collision. Classic while loop checking but this time rotate image_angle to previous position.
Off-topic:
There are plenty tutorials that show how to rotate image but they all doesn't rotate collision box and that's useless when you actually need it.
I tried to make my own top down 2D GTA car movement and I got pretty nice controlls with satisfying drifting, but as soon as I introduced solid walls... crash every time (actually freeze) since I used classic while loop movement collision and turning car into wall with no movement gives infinity while loop. I couldn't find any tutorials so I started to try box2d physics with somewhat ok movement but collisions felt wonky. I don't know why I couldn't think about this simple solution but now it's here.
Longer version:
I'll give SUPER bare bone basic car movement (no drift and and fancy things), but maybe I'll do part 2.
Code:
/// CREATE_EVENT
//for this basic car you can use var in step for hspd and vspd
hspd=0; // horizontal speed
vspd=0; // vertical speed
acc=0.2; // acceleration
spd=0; // car speed
mspd=18; // max speed
bspd=0.05; // breaking speed for lerp
rspd=2; // rotation speed for turning
Code:
/// STEP_EVENT
// input buttons
var gas = keyboard_check(ord("W")) - keyboard_check(ord("S"));
//left turn is positive since GML angles goes counterclockwise
var turn = keyboard_check(ord("A")) - keyboard_check(ord("D"));
if(gas!=0) // pressing one of directions
{
spd+=acc*gas; // adding acceleration to speed in direction of gas
spd=clamp(spd, -mspd/2, mspd); // can't go faster than max speed
}
else // gas buttons are released
{
spd=lerp(spd, 0, bspd); // stopping car
}
/*
Initialize variable for turning.
For drifting you"ll need to do things different there.
Since this is basic car movement, car angle is controlling
movement direction.
*/
var angle=image_angle;
if(turn!=0) // same as gas - turning button is held
{
angle+=rspd*turn; // adding turn in held direction
}
// for this example hspd & vspd could be var
hspd=lengthdir_x(spd, angle); // extracting horizontal movement
vspd=lengthdir_y(spd, angle); // extracting vertical movement
//classic collision, may not be the best and must be carefull since it can freeze the game
if(place_meeting(x+hspd, y, o_Solid)) // checking collision for next horizontal possition
{
while(!place_meeting(x+sign(hspd), y, o_Solid))
{ // do loop while no collision 1 pixel in our H direction
x+=sign(hspd); // move player by 1 pixel in H direction
}
hspd=0; // since we can't move anymore set to 0
}
x+=hspd; // move object by hspd amount
// exactly the same as hspd only done for vertical movement
if(place_meeting(x, y+vspd, o_Solid))
{
while(!place_meeting(x, y+sign(vspd), o_Solid))
{
y+=sign(vspd);
}
vspd=0;
}
y+=vspd;
/*
Since we can check collision only for angle we are now
we need to save value before rotation.
*/
var prev_angle = image_angle; // save current angle
image_angle = angle; // turn object according to controlls
if(place_meeting(x, y, o_Solid)) // check if we are colliding now
{
while(place_meeting(x, y, o_Solid)) // here we do opposite - loop while we are collided
{
image_angle+= sign(prev_angle - angle); // turn back by 1 degree in direction of previous angle
}
}
// Next is optional and not really worked on properly
// it's reducing car speed if we have collided
// and point_distance returns only positive number
/*
var dir = point_direction(0, 0, hspd, vspd); // we need direction and don't care from where
if(abs(angle_difference(image_angle, dir)) < 180) // moving same direction we are turned to
{
spd=point_distance(0, 0, hspd, vspd); // we need distance, don't care from where
}
else
{
spd=-point_distance(0, 0, hspd, vspd); // in case we are moving backwards need to turn distance negative
}
*/
PS:
Sorry for my English and I hope it's useful for someone frustrated as I was when searched for a solution.
Last edited: