init
commit
07f1ae9b2e
|
@ -0,0 +1,6 @@
|
|||
# course.py
|
||||
|
||||
This is a simple game, that I wrote when I was 10-to-12 year old, using Basic on a [TO7/70](https://en.wikipedia.org/wiki/Thomson_TO7).
|
||||
|
||||
This version has simply been ported to the [Pygame](http://www.pygame.org/) framework. There used to be chip music when you won, but I did not bother to keep that.
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
#!/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)
|
Loading…
Reference in New Issue