commit 07f1ae9b2e42278d7f86343c26380b95de82795b Author: Y Date: Fri Nov 3 15:07:22 2017 +0100 init diff --git a/README.md b/README.md new file mode 100644 index 0000000..72c848a --- /dev/null +++ b/README.md @@ -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. + diff --git a/course.py b/course.py new file mode 100644 index 0000000..8927e73 --- /dev/null +++ b/course.py @@ -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)