thank you to whoever is taking time to help me. I'm trying to code a small car traffic simulation in python. But I'm stuck with the collision system. Indeed, I try to add a stop where the car would stop. The cars stop but one on top of the other and not one behind the other. I can't understand why my code doesn't work and detects the collisions right after running the simulation when clearly at the beginning they are far from each other.
So I try to get cars to decelerate and stop if necessary when they are too close to another car. Here is the part of my code which doesn't work: this loop is in a pygame while game loop: It is line 154 in the complete code.
t = 0
for car in cars:
if pygame.time.get_ticks() >= t * 1000:
if not car.started and car.color == BLUE:
car.started = True
start_timeH.append(pygame.time.get_ticks())
if not car.started and car.color == GREEN:
car.started = True
start_timeV.append(pygame.time.get_ticks())
car.draw(win)
car.move()
t += 1
if distance(car.x, car.y, 550, 390) < 40:
car.speed -= 1
if car.speed < 0:
car.speed = 0
if distance(car.x, car.y, ENDX, ENDY) < 30 and not car.arrived and car.color == BLUE:
car.arrived = True
end_timeH.append(pygame.time.get_ticks()) # ajout du temps d'arrivée de chaque voiture dans end_time
if distance(car.x, car.y, ENDX, ENDY) < 30 and not car.arrived and car.color == RED:
car.arrived = True
end_timeV.append(pygame.time.get_ticks()) # ajout du temps d'arrivée de chaque voiture dans end_time
#Make cars stop when they are too close to another car
for other_car in cars:
if other_car != car:# ne pas comparer avec la voiture elle même
if distance(car.x, car.y, other_car.x, other_car.y) < 40:
#print(car.x, car.y ,other_car.x, other_car.y)
car.speed -= 1
if car.speed < 0:
car.speed = 0
Here is my complete code:
import pygame
import math
import random
import time
import matplotlib.pyplot as plt
# Initialisation de Pygame
pygame.init()
# Dimensions de la fenêtre
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
# Dimensions de la voie
ROAD1_WIDTH = 650
ROAD1_HEIGHT = 100
# Dimensions de la seconde voie
ROAD2_WIDTH = 400
ROAD2_HEIGHT = 100
# Dimensions de la voie à sens unique
ROAD3_WIDTH = 50
ROAD3_HEIGHT = 800
# Création de la fenêtre
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
# Définition des couleurs
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
GARDEN = (58 , 157 , 35)
RED = (255, 0, 0)
# Classe pour représenter la voiture
class Car:
def __init__(self, x, y, speed, acceleration, direction, color):
self.x = x
self.y = y
self.position = position = (x,y)
self.speed = speed
self.acceleration = acceleration
self.direction = direction
self.change_direction = False
self.reached_460 = False
self.color = color
self.started = False
self.arrived = False
def move(self):
if self.direction == "horizontal":
self.x += self.speed
if self.x >= 600 and not self.change_direction:
self.direction = random.choices(["horizontal", "vertical"], weights=[1, 0])[0]
self.change_direction = True
if self.direction == "vertical":
self.speed = -self.speed
elif self.y > 410 and self.direction == "horizontal" and self.speed < 0:
self.y = 410
elif self.y > 410 and self.direction == "horizontal" and not self.reached_460:
if self.y > 460:
self.y = 460
self.reached_460 = True
else:
self.y += self.speed
elif self.direction == "vertical":
self.y += self.speed
if self.y >= 410 and not self.change_direction:
self.direction = "horizontal"
self.change_direction = True
self.speed = random.choices([self.speed, -self.speed], weights=[1, 0])[0]
def draw(self, surface):
pygame.draw.rect(surface, self.color, (self.x, self.y, 30, 30))
ENDX = 650 #position où l'on considère la voiture comme étant arrivée à destination
ENDY = 460
def distance(x, y, X, Y):
return math.sqrt((x-X)**2+(y-Y)**2)
# Création de la voiture
nb_voiture = 10
start_timeV = [] #stock les temps de départ de chaque voiture qui partent verticalement
start_timeH = [] #stock les temps de départ de chaque voiture
end_timeV = [] #stock les temps d'arrivée de chaque voiture qui partent verticalement
end_timeH = [] #stock les temps d'arrivée de chaque voiture
cars = []
for i in range(nb_voiture):
car1 = Car(0, 460, 3, 0, "horizontal", BLUE)
car2 = Car(560, 0, 3, 0, "vertical", RED)
cars.append(car1)
cars.append(car2)
# Boucle principale
running = True
clock = pygame.time.Clock()
while running:
#pygame.time.delay(1000) # 50ms entre chaque tours de boucles
# Gestion des événements
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Effacer l'écran
win.fill(GARDEN)
# Dessiner la voie
pygame.draw.rect(win, BLACK, (0, 400, ROAD1_WIDTH, ROAD1_HEIGHT))
pygame.draw.rect(win, BLACK, (550, 0, ROAD2_HEIGHT, ROAD2_WIDTH))
pygame.draw.rect(win, BLACK, (0, 450, ROAD3_HEIGHT, ROAD3_WIDTH))
#pygame.draw.rect(win, RED, (650, 450, 10, 50))
pygame.draw.rect(win, WHITE, (550, 390, 50, 10))
#pygame.draw.rect(win, RED, (100, 450, 10, 50))
#pygame.draw.rect(win, RED, (550, 100, 50, 10))
# Dessiner et déplacer les voitures
t = 0
for car in cars:
if pygame.time.get_ticks() >= t * 1000:
if not car.started and car.color == BLUE:
car.started = True
start_timeH.append(pygame.time.get_ticks())
if not car.started and car.color == GREEN:
car.started = True
start_timeV.append(pygame.time.get_ticks())
car.draw(win)
car.move()
t += 1
if distance(car.x, car.y, 550, 390) < 40:
car.speed -= 1
if car.speed < 0:
car.speed = 0
if distance(car.x, car.y, ENDX, ENDY) < 30 and not car.arrived and car.color == BLUE:
car.arrived = True
end_timeH.append(pygame.time.get_ticks()) # ajout du temps d'arrivée de chaque voiture dans end_time
if distance(car.x, car.y, ENDX, ENDY) < 30 and not car.arrived and car.color == RED:
car.arrived = True
end_timeV.append(pygame.time.get_ticks()) # ajout du temps d'arrivée de chaque voiture dans end_time
#Make cars stop when they are too close to another car
for other_car in cars:
if other_car != car:# ne pas comparer avec la voiture elle même
if distance(car.x, car.y, other_car.x, other_car.y) < 40:
#print(car.x, car.y ,other_car.x, other_car.y)
car.speed -= 1
if car.speed < 0:
car.speed = 0
# Mettre à jour l'affichage
pygame.display.update()
# Limiter la vitesse de la boucle
clock.tick(60)
# Quitter Pygame
pygame.quit()
print(start_timeH)
print(len(start_timeH))
print(end_timeH)
print(len(end_timeH))
print(start_timeV)
print(len(start_timeV))
print(end_timeV)
print(len(end_timeV))
def tempstrajet(start_time, end_time):
temps_trajet = []
for i in range(len(start_time)):
temps_trajet.append(end_time[i] - start_time[i])
return temps_trajet
temps_trajetH = tempstrajet(start_timeH, end_timeH)
temps_trajetV = tempstrajet(start_timeV, end_timeV)
plt.hist([temps_trajetH, temps_trajetV], 10, label = ['car horizontal', 'car vertical'], color=['blue', 'green'], alpha=0.7)
plt.xlabel('Temps (s)')
plt.ylabel('Nombre de voitures')
plt.show()