232 lines
6.2 KiB
Python
232 lines
6.2 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import pygame
|
|
import random
|
|
|
|
# Parameters
|
|
WIDTH = 960
|
|
HEIGHT = 480
|
|
ROAD_COLOR = pygame.Color('#000000FF')
|
|
WALL_COLOR = pygame.Color('#FFFFFFFF')
|
|
FONT_COLOR = pygame.Color('#00FF00FF')
|
|
CAR_COLOR = [pygame.Color('#FF0000FF'), pygame.Color('#0000FFFF')]
|
|
OPPONENT_COLOR = pygame.Color('#AAAAAAFF')
|
|
WHEEL_COLOR = pygame.Color('#7F7F7FFF')
|
|
LEFT = [pygame.K_s, pygame.K_LEFT]
|
|
RIGHT = [pygame.K_f, pygame.K_RIGHT]
|
|
FONT = 'Monospace'
|
|
WAIT = 5000
|
|
|
|
# Secondary parameters
|
|
MID_WIDTH = WIDTH//2
|
|
TRACK_WIDTH = MID_WIDTH//3
|
|
CAR_SIZE = TRACK_WIDTH//10
|
|
SEGMENTS_PER_LINE = (HEIGHT//3)//CAR_SIZE
|
|
SEG_MIN_X = 0
|
|
SEG_MAX_X = MID_WIDTH-TRACK_WIDTH
|
|
ABS_MAX_DIR = TRACK_WIDTH//10
|
|
OFFSETS = [0, TRACK_WIDTH, MID_WIDTH, MID_WIDTH+TRACK_WIDTH]
|
|
|
|
curTopRow = 1
|
|
curPlayerX = [WIDTH//4, MID_WIDTH+WIDTH//4]
|
|
lastDir = 0
|
|
lastX = TRACK_WIDTH
|
|
lastRow = 0
|
|
segmentsUntilNewDir = SEGMENTS_PER_LINE
|
|
segments = []
|
|
players = []
|
|
opponents = []
|
|
proba_op = 0.05
|
|
scores = [0, 0]
|
|
|
|
class Segment:
|
|
def __init__(self):
|
|
global lastDir, lastX, lastRow, segmentsUntilNewDir
|
|
lastRow += 1
|
|
self.row = lastRow
|
|
self.top_x = lastX
|
|
if (lastX+lastDir < SEG_MIN_X) or (lastX+lastDir > SEG_MAX_X):
|
|
lastDir = -lastDir
|
|
self.dir = lastDir
|
|
lastX += lastDir
|
|
segmentsUntilNewDir -= 1
|
|
if segmentsUntilNewDir == 0:
|
|
segmentsUntilNewDir = SEGMENTS_PER_LINE
|
|
lastDir = random.randrange(0, 2*ABS_MAX_DIR)-ABS_MAX_DIR
|
|
def draw(self, scroll):
|
|
s = pygame.display.get_surface()
|
|
y = (self.row-curTopRow)*CAR_SIZE+scroll
|
|
s.lock()
|
|
for o in OFFSETS:
|
|
pygame.draw.line(s, WALL_COLOR, (o+self.top_x, y), (o+self.top_x+self.dir, y+CAR_SIZE))
|
|
s.unlock()
|
|
def delete(self, scroll):
|
|
s = pygame.display.get_surface()
|
|
if self.dir > 0:
|
|
x = self.top_x
|
|
else:
|
|
x = self.top_x+self.dir
|
|
y = (self.row-curTopRow)*CAR_SIZE+scroll
|
|
for o in OFFSETS:
|
|
s.fill(ROAD_COLOR, pygame.Rect(o+x, y, abs(self.dir)+1, CAR_SIZE+1))
|
|
def collides(self, rect, scroll):
|
|
if self.dir > 0:
|
|
x = self.top_x
|
|
else:
|
|
x = self.top_x+self.dir
|
|
y = (self.row-curTopRow)*CAR_SIZE+scroll
|
|
for o in OFFSETS:
|
|
if rect.colliderect(pygame.Rect(o+x, y, abs(self.dir)+1, CAR_SIZE+1)):
|
|
return True
|
|
return False
|
|
|
|
class Car:
|
|
def create_surface(self, color):
|
|
s = pygame.Surface((8, 8)).convert()
|
|
s.lock()
|
|
s.fill(ROAD_COLOR)
|
|
pygame.draw.rect(s, WHEEL_COLOR, pygame.Rect(0, 0, 2, 3), 1)
|
|
pygame.draw.rect(s, WHEEL_COLOR, pygame.Rect(0, 4, 2, 3), 1)
|
|
pygame.draw.rect(s, WHEEL_COLOR, pygame.Rect(6, 0, 2, 3), 1)
|
|
pygame.draw.rect(s, WHEEL_COLOR, pygame.Rect(6, 4, 2, 3), 1)
|
|
pygame.draw.rect(s, color, pygame.Rect(3, 0, 2, 8), 1)
|
|
pygame.draw.rect(s, color, pygame.Rect(2, 1, 4, 1), 1)
|
|
pygame.draw.rect(s, color, pygame.Rect(2, 5, 4, 1), 1)
|
|
pygame.draw.rect(s, color, pygame.Rect(1, 7, 6, 1), 1)
|
|
s.unlock()
|
|
self.surf = pygame.transform.scale(s, (CAR_SIZE, CAR_SIZE))
|
|
|
|
class Opponent(Car):
|
|
def __init__(self):
|
|
self.row = lastRow
|
|
self.top_x = random.randrange(lastX, lastX+TRACK_WIDTH-CAR_SIZE)
|
|
self.create_surface(OPPONENT_COLOR)
|
|
def draw(self, scroll):
|
|
for p in [0, 1]:
|
|
pygame.display.get_surface().blit(self.surf, self.rect(p, scroll))
|
|
def delete(self, scroll):
|
|
for p in [0, 1]:
|
|
pygame.display.get_surface().fill(ROAD_COLOR, self.rect(p, scroll))
|
|
def collides(self, rect, scroll):
|
|
for p in [0, 1]:
|
|
if rect.colliderect(self.rect(p, scroll)):
|
|
return True
|
|
return False
|
|
def rect(self, player, scroll):
|
|
y = (self.row-curTopRow)*CAR_SIZE+scroll
|
|
return pygame.Rect(self.top_x+player*MID_WIDTH, y, CAR_SIZE, CAR_SIZE)
|
|
|
|
class Player(Car):
|
|
def __init__(self, player):
|
|
self.player = player
|
|
self.ok = True
|
|
self.create_surface(CAR_COLOR[player])
|
|
def draw(self, scroll):
|
|
if self.ok:
|
|
pygame.display.get_surface().blit(self.surf, self.rect())
|
|
if scroll == CAR_SIZE-1:
|
|
scores[self.player] += 1
|
|
self.score = font.render(str(scores[self.player]), False, FONT_COLOR).convert()
|
|
pygame.display.get_surface().blit(self.score, self.score.get_rect().move((self.player*MID_WIDTH, HEIGHT-self.score.get_height())))
|
|
def delete(self):
|
|
if self.ok:
|
|
pygame.display.get_surface().fill(ROAD_COLOR, self.rect())
|
|
pygame.display.get_surface().fill(ROAD_COLOR, self.score.get_rect().move((self.player*MID_WIDTH, HEIGHT-self.score.get_height())))
|
|
def rect(self):
|
|
return pygame.Rect(curPlayerX[self.player], 0, CAR_SIZE, CAR_SIZE)
|
|
def crash(self):
|
|
self.ok = False
|
|
|
|
# Initialisation
|
|
pygame.init()
|
|
pygame.event.set_allowed([pygame.QUIT, pygame.KEYDOWN, pygame.KEYUP])
|
|
pygame.display.set_mode((WIDTH, HEIGHT))
|
|
pygame.display.set_caption('Course')
|
|
pygame.display.get_surface().fill(ROAD_COLOR)
|
|
pygame.mouse.set_visible(0)
|
|
dir = [0, 0]
|
|
font = pygame.font.SysFont(FONT, max(8, WIDTH//50))
|
|
|
|
for i in range(1, HEIGHT//CAR_SIZE):
|
|
segments.append(Segment())
|
|
opponents.append(None)
|
|
for i in [0, 1]:
|
|
players.append(Player(i))
|
|
|
|
# Main loop
|
|
run = True
|
|
scroll = CAR_SIZE-1
|
|
while run:
|
|
# collide?
|
|
run = False
|
|
for p in [0, 1]:
|
|
if players[p].ok:
|
|
if segments[0].collides(players[p].rect(), scroll) or (opponents[0] and opponents[0].collides(players[p].rect(), scroll)):
|
|
players[p].crash()
|
|
else:
|
|
run = True
|
|
# draw
|
|
for s in segments:
|
|
s.draw(scroll)
|
|
for o in opponents:
|
|
if o:
|
|
o.draw(scroll)
|
|
for p in players:
|
|
p.draw(scroll)
|
|
pygame.display.update()
|
|
# wait
|
|
pygame.time.wait(150//CAR_SIZE)
|
|
# clear & next
|
|
for s in segments:
|
|
s.delete(scroll)
|
|
for o in opponents:
|
|
if o:
|
|
o.delete(scroll)
|
|
for c in players:
|
|
c.delete()
|
|
scroll -= 1
|
|
if scroll < 0:
|
|
curTopRow += 1
|
|
scroll = CAR_SIZE-1
|
|
segments.pop(0)
|
|
opponents.pop(0)
|
|
segments.append(Segment())
|
|
if random.random() < proba_op:
|
|
opponents.append(Opponent())
|
|
else:
|
|
opponents.append(None)
|
|
proba_op += 0.001
|
|
# manage events
|
|
for evt in pygame.event.get():
|
|
if evt.type == pygame.QUIT:
|
|
run = False
|
|
WAIT = 0
|
|
elif evt.type == pygame.KEYUP:
|
|
for p in [0, 1]:
|
|
if evt.key == LEFT[p] and dir[p] < 0:
|
|
dir[p] = 0
|
|
break
|
|
if evt.key == RIGHT[p] and dir[p] > 0:
|
|
dir[p] = 0
|
|
break
|
|
elif evt.type == pygame.KEYDOWN:
|
|
if evt.key == pygame.K_ESCAPE:
|
|
run = False
|
|
WAIT = 0
|
|
else:
|
|
for p in [0, 1]:
|
|
if evt.key == LEFT[p]:
|
|
dir[p] = -1
|
|
break
|
|
elif evt.key == RIGHT[p]:
|
|
dir[p] = 1
|
|
break
|
|
for p in [0, 1]:
|
|
if dir[p] < 0:
|
|
curPlayerX[p] -= 1
|
|
elif dir[p] > 0:
|
|
curPlayerX[p] += 1
|
|
|
|
pygame.time.wait(WAIT)
|