Skip to main content
GameDev.net gamedev.net
🔒 Locked

Vehicle movement?

Started by Leo28C Jul 29, 2007 at 7:04 AM 4 replies 1.4k views
Original Post
Leo28C
Leo28C
Hello everyone! I posted a while ago here about how to make a tank's turret turn... Well, now I'm having another issue with that tank - how do I make it move in a real-life fashion? Up until now I had it like, one sprite for west, one for northeast, one for south, etc. Now I want to make it so that the Up key will move it forward, Down for backward, and Left and Right to turn. Can anyone explain to me how to do this? Thanks in advance! [grin] (P.S, if you need to know, I'm on C# with SDL.NET)
fpsgamer
fpsgamer
Assuming this is a top down view:

Define a 2d vector vector to represent the tank's position. Define another 2d vector to represent the tanks direction (ie. the direction the tank is facing).

When the left or right key is pressed you want to rotate the direction vector and your sprite in the range 0-360 degrees.

When the up key is pressed you want to modify the tank's position by adding the tank's direction and position vectors like this:

position + ( k * direction )

Where k is a scalar representing how fast you want the tank to move.
Leo28C
Leo28C
Could you explain how to modify the position? Like, what about the X and Y values? :-P

Thanks!
XXX_Andrew_XXX
XXX_Andrew_XXX
A tank has two independent inputs, an input to the left tank tread and the right tank tread. You can combine these two inputs to generate a forward velocity and a rotational velocity. The two inputs (left and right velocity), need to be clamped to ensure that the vehicle can't do something it isn't capable of (it should respect a maximum speed).

A tank has three state variables (x,y and heading).

If we use Euler integration to predict forward from the current timestep to the next timestep we get equations in the form

state[t+1] = state[t] + derivative(state[t])*dt

In the case of the rotation of the vehicle, derivative(state[t]) is the rotational velocity of the vehicle at time t (which is an input).

In the case of the derivative(state[t]) for the position variables, we need to convert the forward velocity of the vehicle into the body frame. The forward velocity input is a scalar, multiplied by direction the vector of the vehicle, which can be found from the heading at time t.

So a simple implementation in python might look like this.

def updateTankState( state, inputs, timestep ):    # extract states    x = state[0]    y = state[1]    psi = state[2]    # extract and clamp raw inputs    leftTreadVel  = clamp( inputs[0], -minTreadVel, maxTreadVel )    rightTreadVel = clamp( inputs[1], -minTreadVel, maxTreadVel )    # calculate inputs in desired form    fwdVel = (leftTreadVel + rightTreadVel) / 2.0    rotVel = (rightTreadVel - leftTreadVel) / 2.0    # calculate derivatives    x_dot = fwdVel*math.cos(psi)    y_dot = fwdVel*math.sin(psi)    psi_dot = rotVel    # integrate    x_next = x + x_dot*dt    y_next = y + y_dot*dt    psi_next = psi + rotVel*dt    # return results    return (xnext,ynext,psi_next)
Leo28C
Leo28C
Hmm... Sorry for the hassle, but the tank doesn't move. :-(

I don't know Python, but the code was pretty straight-forward. Here's my implementation in Lua:

		-- Move with arrow keys		if Keyboard:IsKeyPressed(Key.LeftArrow) then			LeftTread = LeftTread + 1		else			LeftTread = LeftTread - 1		end				if Keyboard:IsKeyPressed(Key.RightArrow) then			RightTread = RightTread + 1		else			RightTread = RightTread - 1		end				-- extract states		local x = Position.X		local y = Position.Y		local psi = Angle		-- extract and clamp raw inputs		local leftTreadVel  = x		local rightTreadVel = y		-- calculate inputs in desired form		local fwdVel = (leftTreadVel + rightTreadVel) / 2.0		local rotVel = (rightTreadVel - leftTreadVel) / 2.0		-- calculate derivatives		local x_dot = fwdVel*math.cos(psi)		local y_dot = fwdVel*math.sin(psi)		local psi_dot = rotVel		-- integrate		Position.X = x + x_dot*dt		Position.Y = y + y_dot*dt		Angle = psi + rotVel*dt


Thanks for helping!
XXX_Andrew_XXX
XXX_Andrew_XXX
You're close now.

The input to the vehicle is a described by a combination of the inputs from the keyboard.

-- extract and clamp raw inputslocal leftTreadVel  = xlocal rightTreadVel = y


Should really be something like:

-- extract and clamp raw inputslocal leftTreadVel  = LeftThreadlocal rightTreadVel = RightTread 


Be aware that this approach to driving a tank might not be easy for a human to use. you may want to work directly in forward velocity and rotational velocity inputs from the keyboard, rather than directly setting the speeds of the treads.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.