Braking light was easy, you can see me pressing the brake while stuck on top there, but that's just a car stuck as it would normally do in real life too, so no tunneling.
Probably not the prettiest nor preferred way but by far the easiest/fastest way was alternating between 2 images, for anybody who needs it:
and
I just added this to MoveVehicle()
[EDIT: showing all changes to be more clear]
In
LoadVehicle.agc :
type vehicle
chassis as integer
hit as integer
size as point
wheels as wheel[]
forward as integer
reverse as integer
right as integer
left as integer
wheelAngle as float
image as integer
imagebrakes as integer ////////////////// added
lastPos as point
camera1st as camera
camera3rd as camera
camera1stalligned as camera
camera as camera
ground as integer
vectV as integer
vectU as integer
suspension as float
flying as integer
delay as delay
velocity as velocity
brakes as integer
// off as integer
endtype
And..
function LoadVehicle(folder as string)
vehicle as vehicle
vehicle.image = LoadImage(folder+"/vehicle.png")
vehicle.imagebrakes = LoadImage(folder+"/vehiclelights.png") /////////////// added
vehicle.hit = LoadObject(folder+"/hit.obj") // Load the hit box (This does all the work)
SetObjectColor(vehicle.hit, 0, 0xff, 0, 0xff)
SetObjectVisible(vehicle.hit, 0)
vehicle.chassis = LoadObject(folder+"/chassis.obj") // Load the chassis
SetObjectImage(vehicle.chassis, vehicle.image, 1)
SetObjectVisible(vehicle.chassis, 1)
vehicle.forward = CreateObjectPlane(0.5, 0.5) // Direction object so we can get a vector
SetObjectPosition(vehicle.forward, GetObjectX(vehicle.chassis), GetObjectY(vehicle.chassis), GetObjectZ(vehicle.chassis) + 1)
SetObjectVisible(vehicle.forward, 0)
FixObjectToObject(vehicle.forward, vehicle.chassis)
vehicle.reverse = CreateObjectPlane(0.5, 0.5) // reverse object so we can get a vector
SetObjectPosition(vehicle.reverse, GetObjectX(vehicle.chassis), GetObjectY(vehicle.chassis), GetObjectZ(vehicle.chassis) - 1)
SetObjectVisible(vehicle.reverse, 0)
FixObjectToObject(vehicle.reverse, vehicle.chassis)
vehicle.right = CreateObjectPlane(0.5, 0.5) // right object so we can get a vector
RotateObjectLocalY(vehicle.right, 5)
SetObjectVisible(vehicle.right, 0)
FixObjectToObject(vehicle.right, vehicle.chassis)
vehicle.left = CreateObjectPlane(0.5, 0.5) // left object so we can get a vector
RotateObjectLocalY(vehicle.left, -5)
SetObjectVisible(vehicle.left, 0)
FixObjectToObject(vehicle.left, vehicle.chassis)
vehicle.suspension = 0.4
LoadWheel(folder, "fr.obj", vehicle) // Wheels
LoadWheel(folder, "fl.obj", vehicle)
LoadWheel(folder, "rr.obj", vehicle)
LoadWheel(folder, "rl.obj", vehicle)
if GetFileExists(folder+"/cam1.obj") = TRUE
SetupCameras(folder, vehicle) // Attach dolly and cameras
else
SetupCamera(folder, vehicle)
endif
FixObjectToObject(vehicle.chassis, vehicle.hit)
vehicle.vectU = CreateVector3()
vehicle.vectV = CreateVector3()
GetDimensions(vehicle)
endfunction vehicle
And in
MoveVehicle.agc
function MoveVehicle(vehicle ref as vehicle, env as environment)
t as point
i as integer
v as float
d as integer
turn as float
a as float
l as point
dot as float
if vehicle.delay.count > timer()
SetObjectColor(vehicle.chassis, 0, 0xff, 0xff, 0xff)
exitfunction
endif
SetObjectColor(vehicle.chassis, 0xff, 0xff, 0xff, 0xff)
turn = 0
if GetRawKeyState(39) = 1 // Turn right/left
turn = vehicle.velocity.angularUnit
endif
if GetRawKeyState(37) = 1
turn = -vehicle.velocity.angularUnit
endif
vehicle.wheelAngle = vehicle.wheelAngle * 0.8 // Dampen the wheel angle
for i=0 to vehicle.wheels.length // Check the wheels
inc d, CheckWheels(vehicle, i, env)
next
// If we have less than 3 wheels on the ground then we're in the air
// so turn everything off until we are in contact with the ground again
if vehicle.brakes = TRUE
SetObjectImage(vehicle.chassis, vehicle.imagebrakes, 1)
else
SetObjectImage(vehicle.chassis, vehicle.image, 1)
endif
if d < 3
if GetObject3DPhysicsLinearVelocityY(vehicle.hit) < -(25 * SCALE_3D) // Falling velocity too high, throttle it
a = DistancePoint(CreatePoint(GetObject3DPhysicsLinearVelocityX(vehicle.hit), GetObject3DPhysicsLinearVelocityY(vehicle.hit) * 0.999, GetObject3DPhysicsLinearVelocityZ(vehicle.hit)))
SetObject3DPhysicsLinearVelocity( vehicle.hit, GetObject3DPhysicsLinearVelocityX(vehicle.hit), GetObject3DPhysicsLinearVelocityY(vehicle.hit), GetObject3DPhysicsLinearVelocityZ(vehicle.hit), a * .9)
endif
if vehicle.ground = TRUE // Use colours to see if we are in the air or not
SetObjectColor(vehicle.chassis, 0xff, 0, 0, 0xff)
SetObjectColor(vehicle.hit, 0xff, 0, 0, 0xff)
endif
if vehicle.flying = FALSE // First time in the air damp down velocity
SetObject3DPhysicsDamping( vehicle.hit , 0.5, 0.99 )
endif
vehicle.flying = TRUE
exitfunction
endif
if vehicle.flying = TRUE // Just hit the ground, reset damping
SetObject3DPhysicsDamping( vehicle.hit , 0.2, 0.9 )
endif
vehicle.flying = FALSE
if vehicle.ground = TRUE
SetObjectColor(vehicle.hit, 0, 0xff, 0, 0xff)
SetObjectColor(vehicle.chassis, 0, 0xff, 0, 0xff) // Use colours to reort if we are in the air or not
endif
// Get the linear velocity
l = CreatePoint(GetObject3DPhysicsLinearVelocityX(vehicle.hit), GetObject3DPhysicsLinearVelocityY(vehicle.hit), GetObject3DPhysicsLinearVelocityZ(vehicle.hit))
// Get the angular velocity
a = DistancePoint(CreatePoint(GetObject3DPhysicsAngularVelocityX(vehicle.hit), GetObject3DPhysicsAngularVelocityY(vehicle.hit), GetObject3DPhysicsAngularVelocityZ(vehicle.hit)))
v = 0 // Acceleration
if GetRawKeyState(40) = 1 // down
v = -vehicle.velocity.linearUnit
SetObjectImage(vehicle.chassis, vehicle.imagebrakes, 1)
Elseif vehicle.brakes = TRUE
SetObjectImage(vehicle.chassis, vehicle.imagebrakes, 1)
Else
SetObjectImage(vehicle.chassis, vehicle.image, 1)
endif
if GetRawKeyState(38) = 1 // up
v = vehicle.velocity.linearUnit
endif
if vehicle.brakes = TRUE
v = v * 0.9
endif
if vehicle.velocity.current < 0
if abs( vehicle.velocity.current + v ) < ( vehicle.velocity.max * 0.5) // Reverse maximum is
inc vehicle.velocity.current, v
else
vehicle.velocity.current = ( vehicle.velocity.max * -0.5)
endif
else
if abs( vehicle.velocity.current + v ) < vehicle.velocity.max
inc vehicle.velocity.current, v
else
vehicle.velocity.current = vehicle.velocity.max * (vehicle.velocity.current / abs(vehicle.velocity.current))
endif
endif
t = GetVehicleDirectionGround(vehicle, MOVE_FORWARD) // Get the vector of the vehicle
if CheckWalls(vehicle, env, l) = TRUE
exitfunction
endif
SetVector3(vehicle.vectU, l.x, l.y, l.z) // Get the direction
SetVector3(vehicle.vectV, t.x, t.y, t.z)
dot = Round(GetVector3Dot(vehicle.vectU, vehicle.VectV))
if v <> 0
if vehicle.brakes = FALSE
SetObject3DPhysicsLinearVelocity( vehicle.hit, t.x, t.y, t.z, vehicle.velocity.current)
endif
else
if dot <> 0
vehicle.velocity.current = DistancePoint(l) * (dot / abs(dot))
SetObject3DPhysicsLinearVelocity( vehicle.hit, t.x, t.y, t.z, vehicle.velocity.current)
endif
endif
if abs(vehicle.wheelAngle) < 100 and vehicle.delay.count < timer() // turn the wheels
inc vehicle.wheelAngle, turn
SetObjectRotation(vehicle.wheels[0].pivot, 0, vehicle.wheelAngle, 0)
SetObjectRotation(vehicle.wheels[1].pivot, 0, vehicle.wheelAngle, 0)
endif
// Apply the turning force (Dampening is set in SetupVehicle())
// The reason we're checking velocity is because we want a
// tight turning circle when it's slow and a smooth one
// when it's fast
if turn <> 0 and abs(vehicle.velocity.current) > (0.7 * SCALE_3d)
if dot < 0
turn = -turn
endif
if dot <> 0
SetObject3DPhysicsAngularVelocity( vehicle.hit, 0, turn, 0, ((vehicle.velocity.max - vehicle.velocity.current) / (0.75 * scale_3d)) + (vehicle.velocity.current ) / (0.75 * scale_3d))
endif
endif
endfunction
Quote: "Thanks heaps for testing. I really, really appreciate it!"
Don't mention it. Glad to be of help. You've really done a marvelous job with this one. It's just so much fun to be able to do this in AGK.
Only thing that's a bit unnatural still is that the steering stops working completely once the car is upside down or stuck somewhere. In some games wiggling with the wheels can set you free.