Help - Search - Members - Calendar
Full Version: Vector-based Movement Causing Player Speed Issues?
Game Maker Community > Working with Game Maker > Advanced Users Only
bluesy_92
So, i started work on a TDS, and I've made (so far) a movement and shooting system. The problem is, since I wanted to include strafing, I couldn't use direction and speed, so I used vectors. If you press more than one key, the vectors add together, which any mathematician will tell you gets a different length than either of the original vectors, so basically, if the player is strafing while walking forward(or backwards), his speed is FASTER than when he walks straight, not equal or slightly slower, like it should be. I tried using "else" statements, so the player could only hit one direction at a time, but that ruined the fluid feel. I basically need a way to use multiple keys at once, without speeding up my player. Here is the source for my player object (step event)


CODE
//player movement
if keyboard_check (68) direction -=1.5
if keyboard_check (65) direction +=1.5
{
if keyboard_check (87)
{
x += lengthdir_x(2, direction)
y += lengthdir_y(2, direction)
}
if keyboard_check (83)
{
x += lengthdir_x(1.5, direction + 180)
y += lengthdir_y(1.5, direction + 180)
}
if keyboard_check (69)
{
x += lengthdir_x(1.5, direction-90)
y += lengthdir_y(1.5, direction-90)
}
if keyboard_check (81)
{
x += lengthdir_x(1.5, direction+90)
y += lengthdir_y(1.5, direction+90)
}
}
//shooting
if weapon = 1
{
if keyboard_check_pressed(74) and pistol_timer = 0
{
instance_create(x, y, obj_bullet_pistol)
pistol_timer = 20
}
}
if weapon = 2
{
if keyboard_check(74) and mg_timer = 0
{
instance_create(x, y, obj_bullet_mg)
mg_timer = 6
}
}
//weapon timers
if pistol_timer > 0
{
pistol_timer -= 1
}
if mg_timer > 0
{
mg_timer -= 1
}
//weapon switching
if keyboard_check_pressed(90)
{
weapon += 1
}
if weapon = 3
{
weapon = 1
}


Also, I did not implement wall objects, and I never used vectors before, so if collision detection is going to be an issue, or anyone has a better idea for the movement system, I'm open to suggestions.
Obj_Control
Misunderstood.
bluesy_92
QUOTE (Obj_Control @ Nov 3 2009, 03:08 AM) *
Nothing in this code should slow your game down, the way I see it. Is there anything else of relevance you could show?


It's not slowing the game, it's speeding up the player. Basically, when 2 vectors are added, the value of the original vectors changes, so if I walk forward while strafing, the player moves faster than if he was just walking forward. I would need to find a way to make it the same speed, or slightly slower, if they player strafe-walks instead of strafing/walking by itself.
RandomBlackMage
The thing that's going on here is that for each case of the key presses, the x and y variables are being updated immediately for each key. If you want to set a maximum speed, you should have each key allocate a certain amount to temporary x and y values. Then, after all the updates from the controls, check to see if your values exceed the maximum speed and set them accordingly.

Example:
CODE
//player movement
xtemp=0 //Reset for each update.
ytemp=0

if keyboard_check (68) direction -=1.5
if keyboard_check (65) direction +=1.5
{
if keyboard_check (87)
{
xtemp += lengthdir_x(2, direction)
ytemp += lengthdir_y(2, direction)
}
if keyboard_check (83)
{
xtemp += lengthdir_x(1.5, direction + 180)
ytemp += lengthdir_y(1.5, direction + 180)
}
if keyboard_check (69)
{
xtemp += lengthdir_x(1.5, direction-90)
ytemp += lengthdir_y(1.5, direction-90)
}
if keyboard_check (81)
{
xtemp += lengthdir_x(1.5, direction+90)
ytemp += lengthdir_y(1.5, direction+90)
}
}

while sqr(xtemp)+sqr(ytemp)>sqr(maxspeed){ //Pythagorean theorem to check the vector's length doesn't exceed the maximum allowed.
xtemp*=0.9 //Decrease to improve speed, increase to improve accuracy (keep below 1).
ytemp*=0.9 //Not the most efficient method, but the simplest that comes to mind.
}

x+=xtemp
y+=ytemp


That should work for you while maintaining for the most part the degree and partial magnitude of the original vector. Definitely not the most efficient nor the most accurate method, but it should work.

Another simple enough method would be to rewrite the keyboard checks for combination presses (making sure to put the and not's in the single key presses), which would be a lot more accurate for what you're looking for, but the coding will be a bit longer and will take some effort to write.
icuurd12b42
step event... 2 version, diffrent movement as I could not tell from your code (I tried it, weird) which one you wanted...
CODE
//up down, rotation does not affect movement
spd = 4;
rotspd = 5;
image_angle+=(keyboard_check(ord('A')) - keyboard_check(ord('D'))) * rotspd;
direction = image_angle;
dx = (keyboard_check(vk_right) - keyboard_check(vk_left));
dy = (keyboard_check(vk_down) - keyboard_check(vk_up));
if(dx<>0 or dy <>0)
{
    a = point_direction(0,0,dx,dy)
    x+=lengthdir_x(spd,a);
    y+=lengthdir_y(spd,a);
}

exit;
//for rotating and moving to pointing direction
//and straffing... Confusing
spd = 4;
rotspd = 5;
image_angle+=(keyboard_check(ord('A')) - keyboard_check(ord('D'))) * rotspd;
direction = image_angle;
dx = (keyboard_check(vk_up) - keyboard_check(vk_down));
dy = (keyboard_check(vk_right) - keyboard_check(vk_left));
if(dx<>0 or dy <>0)
{
    a = point_direction(0,0,dx,dy)
    x+=lengthdir_x(spd,image_angle+a);
    y+=lengthdir_y(spd,image_angle+a);
}
Tepi
This is a good example that you can't simplify human movement like this. The forces and therefore accelerations are not even near to being 0, so just simple vector addition to the position (i.e. constant velocity) is not the correct system. If it was, this vector adition would be expected. But here it's not.

The most simple way of doing this is indeed to limit the speed at which the person moves. But that makes using directions and speeds easier than using vectors. So if you insist to stick with the vector movement, normalize the movement vector after the addition. Copy the RandomBlackMage's code but replace the while loop with:
CODE
var D;
D = sp / point_distance(0,0,xtemp,ytemp);
xtemp *= D;
ytemp *= D;
where sp is the speed in which you want the movement to happen.
bluesy_92
QUOTE (Tepi @ Nov 3 2009, 02:32 PM) *
This is a good example that you can't simplify human movement like this. The forces and therefore accelerations are not even near to being 0, so just simple vector addition to the position (i.e. constant velocity) is not the correct system. If it was, this vector adition would be expected. But here it's not.

The most simple way of doing this is indeed to limit the speed at which the person moves. But that makes using directions and speeds easier than using vectors. So if you insist to stick with the vector movement, normalize the movement vector after the addition. Copy the RandomBlackMage's code but replace the while loop with:
CODE
var D;
D = sp / point_distance(0,0,xtemp,ytemp);
xtemp *= D;
ytemp *= D;
where sp is the speed in which you want the movement to happen.


If I was to use direction and speed (which I prefer) how would I use strafing? I tried several direction and speed methods before, and several ways of using variables, to get strafing....it never worked, which is why I used a vector-based method.
slayer 64
i don't know what you mean by strafing. this is a top down shooter so maybe you want to do this.
CODE
x+=(keyboard_check(ord("A"))-keyboard_check(ord("D")))*4;
y+=(keyboard_check(ord("W"))-keyboard_check(ord("S")))*4;

but from looking at the other posts you are doing something slightly more complicated. maybe you are trying to strafe according to the direction your facing? i'm not really sure what your long term goal is.
CODE
var dx,dy;

dx=keyboard_check(ord("A"))-keyboard_check(ord("D"));
dy=keyboard_check(ord("W"))-keyboard_check(ord("S"));
        
if dx!=0
or dy!=0
{
    a=point_direction(0,0,dy,dx)+image_angle;
    x+=lengthdir_x(4,a);
    y+=lengthdir_y(4,a);
}
bluesy_92
QUOTE (slayer 64 @ Nov 3 2009, 05:09 PM) *
i don't know what you mean by strafing. this is a top down shooter so maybe you want to do this.
CODE
x+=(keyboard_check(ord("A"))-keyboard_check(ord("D")))*4;
y+=(keyboard_check(ord("W"))-keyboard_check(ord("S")))*4;

but from looking at the other posts you are doing something slightly more complicated. maybe you are trying to strafe according to the direction your facing? i'm not really sure what your long term goal is.
CODE
var dx,dy;

dx=keyboard_check(ord("A"))-keyboard_check(ord("D"));
dy=keyboard_check(ord("W"))-keyboard_check(ord("S"));
        
if dx!=0
or dy!=0
{
    a=point_direction(0,0,dy,dx)+image_angle;
    x+=lengthdir_x(4,a);
    y+=lengthdir_y(4,a);
}


By "strafe", I mean like an FPS strafing. I have WASD movement, but I use Q and E to strafe left and right, while looking forward. It is all based on vectors, you can see the code in my original post.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.