Jump to content
IGNORED

Physics model for car


Recommended Posts

Does anyone know of a simple 2D physics model for a car that supports skidding/drifting, where the car is steered using turn left/turn right/speeder/brake?

 

My first attempt was simply:

 

Turn left:

angle += turn_speed

 

Turn right:

angle += turn_speed

 

Accelerate:

speed += power

 

Brake:

speed -= power

 

And then:

 

velocity_x = speed * cos(angle)

velocity_y = speed * sin(angle)

 

position_x += velocity_x

position_y += velocity_y

 

This works OK, but you have to brake a lot before most turns, and it would be a more interesting gameplay to be able to brake a little to make the car drift and then speed up again. Also, being able to turn without the car moving is not very realistic.

 

I looked at this https://gamedev.stackexchange.com/questions/1796/vehicle-physics-with-skid which introduces an angular velocity, but for me that either under or over steers the car, making it impossible to control.

 

 

 

 

 

 

Edited by Asmusr
  • Like 1
Link to comment
Share on other sites

I would thing you will need to set a threshold for the angular velocity which when exceeded will cause the car to skid. You can play with the value until the desired balance between turning and skidding is achieved.

  • Like 2
Link to comment
Share on other sites

34 minutes ago, Vorticon said:

I would thing you will need to set a threshold for the angular velocity which when exceeded will cause the car to skid. You can play with the value until the desired balance between turning and skidding is achieved.

Right, but you're still only saying what you want the car to do, but not how to make it do it. What does it mean for the model that the car is skidding? There are no 'if' statements in the laws of Newton. 🙂

Link to comment
Share on other sites

You have to made a decision about the friction coefficient. The angular velocity should be a function of the steering angle and the car's velocity. That will take care of the problem that you can turn at standstill. The angular velocity can only be allowed to reach a certain level. If it exceeds it, the actual steering angle will be limited (capped) to keep the angular velocity under the limit imposed by the friction.

  • Like 3
Link to comment
Share on other sites

44 minutes ago, apersson850 said:

You have to made a decision about the friction coefficient. The angular velocity should be a function of the steering angle and the car's velocity. That will take care of the problem that you can turn at standstill. The angular velocity can only be allowed to reach a certain level. If it exceeds it, the actual steering angle will be limited (capped) to keep the angular velocity under the limit imposed by the friction.

You stole my reply  :)

Anyway it comes down to sliding friction

  • Like 1
  • Haha 1
Link to comment
Share on other sites

Thanks for the replies. I also asked ChatGPT, and it came up with the Python code below. Basically, the only difference from what I have now is that when you're not speeding or braking it's multiplying the speed by a car_drift_factor, which I guess is the same as applying a friction. Note that in this model the angular velocity is constant (car_turn_speed), but I think it's correct that this should be a function of the speed, instead of increasing and decreasing when you steer as in the link I posted above. 

 

I will try to turn this into an XB program later, unless somebody beats me to it. Note that it will need to use CALL LOCATE to position the sprite instead of auto motion. I'm not sure if it will be fast enough, but then we can run it in Classic 99 with CPU overdrive.

 

import pygame
import math

# Initialize Pygame
pygame.init()

# Constants
WIDTH, HEIGHT = 800, 600
FPS = 60

# Colors
WHITE = (255, 255, 255)
RED = (255, 0, 0)

# Car parameters
car_speed = 5
car_turn_speed = 5
car_drift_factor = 0.9

# Initialize the screen
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Drifting Car Example")
clock = pygame.time.Clock()

class Car:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.angle = 0
        self.speed = 0

    def update(self, throttle, brake, steer):
        # Update car angle based on steering
        self.angle += steer * car_turn_speed

        # Update car speed based on throttle and brake
        if throttle > 0:
            self.speed += throttle
        elif brake > 0:
            self.speed -= brake
        else:
            self.speed *= car_drift_factor

        # Update car position based on angle and speed
        radian_angle = math.radians(self.angle)
        self.x += self.speed * math.cos(radian_angle)
        self.y += self.speed * math.sin(radian_angle)

    def draw(self):
        pygame.draw.rect(screen, WHITE, (self.x, self.y, 20, 40))

# Create a car object
car = Car(WIDTH // 2, HEIGHT // 2)

# Game loop
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()

    # Control the car
    throttle = keys[pygame.K_UP] * car_speed
    brake = keys[pygame.K_DOWN] * car_speed
    steer_left = keys[pygame.K_LEFT]
    steer_right = keys[pygame.K_RIGHT]

    steer = steer_right - steer_left

    # Update the car
    car.update(throttle, brake, steer)

    # Clear the screen
    screen.fill(RED)

    # Draw the car
    car.draw()

    # Update the display
    pygame.display.flip()

    # Cap the frame rate
    clock.tick(FPS)

# Quit Pygame
pygame.quit()

 

  • Like 3
Link to comment
Share on other sites

13 hours ago, Asmusr said:

Right, but you're still only saying what you want the car to do, but not how to make it do it. What does it mean for the model that the car is skidding? There are no 'if' statements in the laws of Newton. 🙂

if "moving" then "sliding friction" else "static friction" ?

  • Like 1
Link to comment
Share on other sites

4 hours ago, Asmusr said:

Note that in this model the angular velocity is constant (car_turn_speed), but I think it's correct that this should be a function of the speed, instead of increasing and decreasing when you steer as in the link I posted above. 

The angular velocity is the amount of steering multiplied by the vechicle's speed. Think about a real car: If you stand still and turn the steering wheel nothing happens (to the angular velocity). If you drive very fast and don't steer, nothing happens. If you steer a lot and drive slowly, the car turns in ten seconds. If you drive fast and just steer a little, you turn around in ten seconds.

Now if you both drive fast and steer a lot, then the angular velocity is limited by the available friction. The car starts sliding (drifting). But exactly how depends on complex functions of the car's dynamics. A front wheel drive tend to understeer when accelerating and oversteer when coasting. What happens when you use the brakes depends on the brake distribution front/rear. For a rear wheel drive it's different, and again for an all wheel drive, where it also depends on the torque distribution.

 

I could go on for several screens full, but that's not beneficiary. You have to make your mind up about something simple and still reasonably realistic to happen when the angular velocity is too high:

  • If accelerating, drift and increase angular velocity somewhat (oversteer).
  • At constant speed, drift with no change in angular velocity.
  • If braking, drift and reduce angular velocity (understeer).

Sliding in general is less efficient than rolling along the direction of the wheels (it takes power to produce tire squeal), so you should probably reduce speed slightly if you are drifting.

Edited by apersson850
  • Like 4
Link to comment
Share on other sites

14 hours ago, Asmusr said:

Right, but you're still only saying what you want the car to do, but not how to make it do it. What does it mean for the model that the car is skidding? There are no 'if' statements in the laws of Newton. 🙂

As @apersson850 stated, this could get complicated very quickly. Skidding can be faked by rotating the back of the car a certain amount and translating the whole car in the direction of the original movement vector proportional to your angular velocity which already incorporates your speed and steering values. Yes it's not physics-accurate by any means, but it will generally look the part. Here's how I would try it.

 

  1. CAR TURNS
  2. CALCULATE ANGULAR VELOCITY
  3. IS THE ARBITRARY  SKIDDING THRESHOLD EXCEEDED?
  • NO --> NORMAL TURN
  • YES -->  - ROTATE CAR PROPORTIONAL TO DELTA ANGULAR VELOCITY ABOVE SKIDDING THRESHOLD 

               - TRANSLATE WHOLE CAR IN DIRECTION OF ORIGINAL MOVEMENT VECTOR PROPORTIONAL TO THAT DELTA VALUE

      4. RESUME LINEAR MOTION IN DIRECTION OF TURN

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...