0

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()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • 2
    Welcome to Stack Overflow. We don't provide debugging services. You need to debug nyour code and isolate the problem, once that is done we will help as best we can. The following references give advice on debugging your code. [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/), [Six Debugging Techniques for Python Programmers](https://medium.com/techtofreedom/six-debugging-techniques-for-python-programmers-cb25a4baaf4b) – itprorh66 Mar 24 '23 at 19:15
  • When I run this, I just see a static picture, with nothing moving. One red and one blue car. Static. – ProfDFrancis Mar 24 '23 at 19:53
  • Yes, that’s the problem I have with the part of the program I add in the first case, if you remover what comes just after the English comment, you will have car moving but when they stop at the stop they are stopping one on another and not one behind the other but I don’t understand what’s wrong with my code – Romain Darde Mar 24 '23 at 22:04

0 Answers0