I am trying to program TopDown Car using python and Box2D (similar to this tutorial: http://www.iforce2d.net/b2dtut/top-down-car ) The steering is so far limited to thres states of wheel rotation, that I will need to solve later, now I have problem with controlling the car velocity.
The problem is that the vehicle moves rather uncontrollably, I press "W" to move forward, "A" or "D" to steer, but then I ofttimes need to press "S" key to keep going in forward direction (which is of course counter-intuitive).
EDIT: I tried to convert world/object coordinates, it helped partially because now my car is moving from the beginning in straight line (it was always going slightly obliquely to the right, but now it has problems with turning, it turns uncontrollably and there is still the problem with messed-up directions (when I need the car to go forward after turning i have to press S
This is the main game loop: it should be updating PyGame frame 60 times per second, in Every frame I am cancelling lateral velocity of a body and then I am trying to controll the body
while running:
# Check the event queue
screen.fill((255, 255, 255,0))
for body in world.bodies:
for fixture in body.fixtures:
fixture.shape.draw(body, fixture)
# Cancelling lateral velocity
for wheel in Wheels:
if wheel in range(2):
continue # Rear wheels are not powered
else:
Current_Normal = wheel.GetWorldVector((0,1))
Current_N_Squared = b2Dot(Current_Normal, wheel.linearVelocity) * Current_Normal
Right_Normal = wheel.GetWorldVector((1,0))
Right_Normal_Squared = b2Dot(Right_Normal, wheel.linearVelocity) * Right_Normal
Impulse = -Right_Normal_Squared * wheel.mass
if Impulse.length >max_lateral_impulse:
Impulse *= max_lateral_impulse/Impulse.length
wheel.ApplyLinearImpulse(Impulse, wheel.worldCenter, True)
# Allowing skidding
aimp = 0.05 * wheel.inertia * -wheel.angularVelocity
wheel.ApplyAngularImpulse(aimp, True)
current_forward_speed = Current_N_Squared.Normalize()
drag_force_magnitude = -2 * current_forward_speed
wheel.ApplyForce(drag_force_magnitude * Current_N_Squared,
wheel.worldCenter, True)
# Moving forward/backward
if event.type == KEYDOWN and event.key == K_w:
Left_Wheel.ApplyLinearImpulse(impulse=Left_Wheel.GetWorldVector((0, 10)), point =Left_Wheel.GetWorldVector((Left_Wheel.position)),wake = True)
Right_Wheel.ApplyLinearImpulse(impulse=Right_Wheel.GetWorldVector((0, 10)),point = Right_Wheel.GetWorldVector((Right_Wheel.position)),wake = True)
elif event.type == KEYDOWN and event.key == K_s:
Left_Wheel.ApplyLinearImpulse(impulse=Left_Wheel.GetWorldVector((0, -10)), point =Left_Wheel.GetWorldVector((Left_Wheel.position)),wake = True)
Right_Wheel.ApplyLinearImpulse(impulse=Right_Wheel.GetWorldVector((0, -10)),point = Right_Wheel.GetWorldVector((Right_Wheel.position)),wake = True)
If you want to play with my code in order to better see where the problem is I can give you the whole script (270 lines in total)
I know that to move more realistically I need to play with the aimp or max_lateral_velocity values. But first I need the car to be controlled better
EDIT 2: I am sorry, I was probably able to solve this problem by applying this:
Left_Wheel.ApplyLinearImpulse(b2Vec2(Left_Wheel.GetWorldVector((0, 10))), Left_Wheel.position,True)
Right_Wheel.ApplyLinearImpulse(b2Vec2(Right_Wheel.GetWorldVector((0, 10))), Right_Wheel.position,True)
This seems to be working, many thanks to Aleš Koblížek for patience Now my problem seems to be solved