master
Y 2017-11-03 15:07:22 +01:00
commit 07f1ae9b2e
2 changed files with 237 additions and 0 deletions

6
README.md Normal file
View File

@ -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.

231
course.py Normal file
View File

@ -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)