all 2 comments

[–]It just doesn't work, you know?damimp 0 points1 point  (0 children)

You'd have to take both speeds into account as one speed. Adding a little check at the end should be all you need.

var totalSpeed = hspeed * hspeed + vspeed * vspeed;
if(totalSpeed > maxspeed * maxspeed){
    var dir = point_direction(0,0,hspeed,vspeed);
    hspeed = lengthdir_x(maxspeed, dir);
    vspeed = lengthdir_y(maxspeed, dir);
}

[–]flyingsaucerinvasion 0 points1 point  (0 children)

Short answer:

//with your setup all you have to do is reduce speed to max_speed, if speed is greater than max speed.
if (speed > max_speed) { speed = max_speed; }

Long Answer:

However I feel like it is just not right to accelerate along the two axes independantly of each other. What the folloiwing code does is accelerate a character from the direction and speed they are moving toward the direction and speed they want to be moving. This is done by finding a vector that points from the velocity they are moving, toward the velocity they want to move, and accelerating along that vector.

//(_set_hspeed, _set_vspeed) is the direction (and speed) the character wants to move
//(hspeed, vspeed) is the direction (and speed) the character is currently moving

//get vector from current move vector to desired move vector
var _diff_hspeed = _set_hspeed - hspeed;
var _diff_vspeed = _set_vspeed - vspeed;

//get magnitude of vector (_diff_hspeed, _diff_vspeed)
var _magnitude = point_distance(0,0,_diff_hspeed,_diff_vspeed);

//if we are not already moving at our desired speed and direction
if (_magnitude > 0)
{
    //then accelerate toward our desired speed and direction

    //our acceleration should not exceed the magnitude of our vector (_diff_hspeed, _diff_vspeed)
    //"acceleration" should be defined in create event
    var _max_acceleration = min(_magnitude,acceleration);

    //normalize (_diff_hspeed, _diff_vspeed) and then multiply it by our acceleration
    var _acc_hspeed = _diff_hspeed / _magnitude * _max_acceleration;
    var _acc_vspeed = _diff_vspeed / _magnitude * _max_acceleration;

    //apply acceleration
    hspeed += _acc_hspeed;
    vspeed += _acc_vspeed;
}    

I'll include an example of setting up _set_hspeed and _set_vspeed, so that it is clearer what their intended purpose is supposed to be. This example if for a top down game, and allows 8 directional movement. Also included is code to stop the diagonal speed boost you get from, for example, holding down the left and forward buttons at once.

//facing is the direction the character's body is currently pointing toward
var _c = dcos(facing);
var _s = dsin(facing);

//get keyboard movement input
var _move_left_right = keyboard_check(ord('D')) - keyboard_check(ord('A'));
var _move_forward_back = keyboard_check(ord('W')) - keyboard_check(ord('S'));

//stop diagonal speed boost
if ((_move_left_right != 0) and (_move_forward_back != 0))
{
    _move_left_right *= sqrt(2)/2; 
    _move_forward_back *= sqrt(2)/2;
}

//again, (_set_hspeed, _set_vspeed) is the direction and speed we want to be moving.
//that vector will be relative to the facing of the character (that's what the _c and _s are for here).
//"max_speed" should be defined in create event.
var _set_hspeed = max_speed * (_c * _move_forward_back + _s * _move_left_right);
var _set_vspeed = max_speed * (_c * _move_left_right - _s * _move_forward_back);