I have been working on a two player racing car game in Pygame. When the cars cross the finish line the correct way, I have made it reset to the start position as to 'jump' the finish, rather than cross it smoothly (which is how I want it). If I were to remove this reset feature, my cars wouldn't be able to cross, as I have placed a barrier at the other side of the finish to prevent the line being crossed in the wrong direction. So, how can I make it so that the line can't be crossed in the wrong direction, but it can be crossed over from the other side smoothly? Note: I know my lap system is not exactly functional
Here is my code:
import pygame
import time
import math
from utils import scale_image, blit_rotate_center
GRASS = scale_image(pygame.image.load("imgs/grass.jpg"), 1.94)
TRACK = scale_image(pygame.image.load("imgs/track.png"), 0.7)
TRACK_BORDER = scale_image(pygame.image.load("imgs/track-border.png"), 0.7)
TRACK_BORDER_MASK = pygame.mask.from_surface(TRACK_BORDER)
FINISH = scale_image(pygame.image.load("imgs/finish.png"), 0.7)
FINISH_MASK = pygame.mask.from_surface(FINISH)
FINISH_POSITION = (101,194.44)
RED_CAR = scale_image(pygame.image.load("imgs/red-car.png"), 0.428)
GREEN_CAR = scale_image(pygame.image.load("imgs/green-car.png"), 0.428)
WIDTH, HEIGHT = TRACK.get_width(), TRACK.get_height()
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Racing Game!")
FPS = 60
class GameInfo:
LAPS = 5
def __init__(self, lap=1):
self.lap = lap
self.started = False
self.lap_start_time = 0
def next_lap(self):
self.lap += 1
self.started = False
def game_finished(self):
return self.lap > self.LAPS
def start_lap(self):
self.started = True
self.lap_start_time = time.time()
def get_lap_time(self):
if not self.started:
return 0
return round(time.time() - self.lap_start_time)
class AbstractCar:
def __init__(self, max_vel, rotation_vel):
self.img = self.IMG
self.max_vel = max_vel
self.vel = 0
self.rotation_vel = rotation_vel
self.angle = 0
self.x, self.y = self.START_POS
self.acceleration = 0.1
def rotate(self, left=False, right=False):
if left:
self.angle += self.rotation_vel
elif right:
self.angle -= self.rotation_vel
def draw(self, win):
blit_rotate_center(win, self.img, (self.x, self.y), self.angle)
def move_forward(self):
self.vel = min(self.vel + self.acceleration, self.max_vel)
self.move()
def move_backward(self):
self.vel = max(self.vel - self.acceleration, -self.max_vel/2)
self.move()
def move(self):
radians = math.radians(self.angle)
vertical = math.cos(radians) * self.vel
horizontal = math.sin(radians) * self.vel
self.y -= vertical
self.x -= horizontal
def collide(self, mask, x=0, y=0):
car_mask = pygame.mask.from_surface(self.img)
offset = (int(self.x - x), int(self.y - y))
poi = mask.overlap(car_mask, offset)
return poi
def reset(self):
self.x, self.y = self.START_POS
self.angle = 0
self.vel = 0
class PlayerCar1(AbstractCar):
IMG = RED_CAR
START_POS = (113, 150)
def reduce_speed(self):
self.vel = max(self.vel - self.acceleration / 2, 0)
self.move()
def bounce(self):
self.vel = -self.vel / 2
self.move()
class PlayerCar2(AbstractCar):
IMG = GREEN_CAR
START_POS = (138, 150)
def reduce_speed(self):
self.vel = max(self.vel - self.acceleration / 2, 0)
self.move()
def bounce(self):
self.vel = -self.vel / 2
self.move()
def draw(win, images, player_car1, player_car2):
for img, pos in images:
win.blit(img, pos)
player_car1.draw(win)
player_car2.draw(win)
pygame.display.update()
def move_player(player_car1, player_car2):
keys = pygame.key.get_pressed()
moved1 = False
moved2 = False
if keys[pygame.K_LEFT]:
player_car1.rotate(left=True)
if keys[pygame.K_RIGHT]:
player_car1.rotate(right=True)
if keys[pygame.K_UP]:
moved1 = True
player_car1.move_forward()
if keys[pygame.K_DOWN]:
moved1 = True
player_car1.move_backward()
if keys[pygame.K_a]:
player_car2.rotate(left=True)
if keys[pygame.K_d]:
player_car2.rotate(right=True)
if keys[pygame.K_w]:
moved2 = True
player_car2.move_forward()
if keys[pygame.K_s]:
moved2 = True
player_car2.move_backward()
if not moved1:
player_car1.reduce_speed()
if not moved2:
player_car2.reduce_speed()
def handle_collision(player_car1, player_car2):
if player_car1.collide(TRACK_BORDER_MASK) != None:
player_car1.bounce()
if player_car2.collide(TRACK_BORDER_MASK) != None:
player_car2.bounce()
finish_poi_collide1 = player_car1.collide(FINISH_MASK, *FINISH_POSITION)
finish_poi_collide2 = player_car2.collide(FINISH_MASK, *FINISH_POSITION)
if finish_poi_collide1 !=None:
if finish_poi_collide1[1] == 0:
player_car1.bounce()
else:
game_info.next_lap()
player_car1.reset()
print(game_info.lap)
if finish_poi_collide2 !=None:
if finish_poi_collide2[1] == 0:
player_car2.bounce()
else:
game_info.next_lap()
player_car2.reset()
print(game_info.lap)
run = True
clock = pygame.time.Clock()
images = [(GRASS, (0, 0)), (TRACK, (0, 0)), (FINISH, FINISH_POSITION), (TRACK_BORDER, (0,0))]
player_car1 = PlayerCar1(4, 4)
player_car2 = PlayerCar2(4, 4)
game_info = GameInfo()
while run:
clock.tick(FPS)
draw(WIN, images, player_car1, player_car2)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
break
move_player(player_car1, player_car2)
handle_collision(player_car1, player_car2)
if game_info.game_finished():
blit_text_center(WIN, MAIN_FONT, "You won the game!")
pygame.time.wait(5000)
game_info.reset()
player_car1.reset()
player_car2.reset()
pygame.quit()
Sorry I was unsure how I could shorten it so that it was still coherent, nevertheless please can you help me, thank you