#!/usr/bin/python
import pygame
import math
import os
WIDTH = 800
HEIGHT = 600
os.environ['SDL_VIDEO_WINDOW_POS'] = "100,50"
roadW = 2000
segL = 200 # segment length
camD = 0.84 # camera depth
class Line:
def __init__(self):
self.x = 0 # 3d center of line
self.y = 0
self.z = 0
self.X = 0 # screen coord
self.Y = 0
self.W = 0
self.scale = 0
self.curve = 0
def setz(self, a):
self.z = a
def setcurve(self, a):
self.curve = a
# from world to screen coordinates
def project(self, camX, camY, camZ):
self.scale = camD / (self.z - camZ)
self.X = (1 + self.scale * (self.x - camX)) * WIDTH / 2.
self.Y = (1 - self.scale * (self.y - camY)) * HEIGHT / 2.
self.W = self.scale * roadW * WIDTH / 2.
def drawQuad(window, color, x1, y1, w1, x2, y2, w2):
pygame.draw.polygon(window,
color,
((x1 - w1, y1),
(x2 - w2, y2),
(x2 + w2, y2),
(x1 + w1, y1)))
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Outrun Racing!")
pygame.mouse.set_visible(1)
pygame.key.set_repeat(1, 30)
clock = pygame.time.Clock()
running = True
try:
bg = pygame.image.load("images/bge.png")
# bg = pygame.transform.scale(bg, (WIDTH, HEIGHT))
except:
bg = None
lines = []
for i in range(1, 1600, 1):
line = Line()
line.setz(i * segL)
if i > 300 and i < 700:
line.setcurve(0.5)
if i > 750:
line.y = math.sin(i / 30.0) * 1500
lines.append(line)
N = len(lines)
pos = 0
playerX = 0
flying = 0
while running:
clock.tick(50)
x = 0
dx = 0
maxy = HEIGHT
pygame.event.pump()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
playerX -= 200
if keys[pygame.K_RIGHT]:
playerX += 200
if keys[pygame.K_UP]:
pos += 200
if keys[pygame.K_DOWN]:
pos -= 200
if keys[pygame.K_q]:
flying += 200
if keys[pygame.K_a]:
flying -= 200
if keys[pygame.K_ESCAPE]:
running = False
continue
while pos >= N * segL:
pos -= N * segL
while pos < 0:
pos += N * segL
startPos = pos / segL
if flying < 0:
flying = 0
camH = 1500 + lines[startPos].y + flying
if bg:
screen.blit(bg, (0,0))
else:
screen.fill((0, 0, 0))
# draw road
for n in range(startPos, startPos + 300, 1):
l = lines[n % N]
if n >= N:
n2 = N * segL
else:
n2 = 0
l.project(playerX - x, camH, pos)
x += dx
dx += l.curve
if l.Y >= maxy:
continue
maxy = l.Y
if (n / 3) % 2:
grass = (16, 200, 16)
rumble = (255, 255, 255)
road = (107, 107, 107)
else:
grass = (0, 154, 0)
rumble = (0, 0, 0)
road = (105, 105, 105)
p = lines[(n - 1) % N] # previous line
drawQuad(screen, grass, 0, p.Y, WIDTH, 0, l.Y, WIDTH)
drawQuad(screen, rumble, p.X, p.Y, p.W * 1.2, l.X, l.Y, l.W * 1.2)
drawQuad(screen, road, p.X, p.Y, p.W, l.X, l.Y, l.W)
pygame.display.flip()