""" turretFire.py
Use vector projection
to add a shell to the turret"""
import pygame, math
from Tkinter import *
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((800,480))
pygame.display.set_caption ("Orbit Rider")
background = pygame.Surface(screen.get_size())
class Label(pygame.sprite.Sprite):
""" Label Class (simplest version)
Properties:
font: any pygame font object
text: text to display
center: desired position of label center (x, y)
"""
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.font = pygame.font.SysFont("None", 30)
self.text = ""
self.center = (320, 240)
def update(self):
self.image = self.font.render(self.text, 1, (255, 255, 0))
self.rect = self.image.get_rect()
self.rect.center = self.center
class Turret(pygame.sprite.Sprite):
def __init__(self, shell):
self.shell = shell
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("turret.gif")
self.image = self.image.convert()
self.rect = self.image.get_rect()
self.rect.center = (10, 480)
self.TURNRATE = 10
self.dir = 45
self.charge = 5
def update(self):
self.checkKeys()
self.rotate()
def checkKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.dir += self.TURNRATE
if self.dir > 360:
self.dir = self.TURNRATE
if keys[pygame.K_RIGHT]:
self.dir -= self.TURNRATE
if self.dir < 0:
self.dir = 360 - self.TURNRATE
if keys[pygame.K_UP]:
self.charge += 1
if self.charge > 20:
self.charge = 20
if keys[pygame.K_DOWN]:
self.charge -= 1
if self.charge < 0:
self.charge = 0
if keys[pygame.K_SPACE]:
self.shell.x = self.rect.centerx
self.shell.y = self.rect.centery
self.shell.speed = self.charge
self.shell.dir = self.dir
self.shell.calcVector()
def rotate(self):
oldCenter = self.rect.center
self.image = pygame.transform.rotate(self.image, self.dir)
self.rect = self.image.get_rect()
self.rect.center = oldCenter
class Shell(pygame.sprite.Sprite):
def __init__(self, screen, background):
pygame.sprite.Sprite.__init__(self)
self.screen = screen
self.background = background
self.boom = pygame.mixer.Sound("thunder.ogg")
self.image = pygame.Surface((10, 10))
self.image.fill((255, 255, 255))
self.image.set_colorkey((255, 255, 255))
pygame.draw.circle(self.image, (255, 255, 255), (5, 5), 5)
self.image = pygame.transform.scale(self.image, (5, 5))
self.rect = self.image.get_rect()
self.rect.center = (-100, -100)
self.x = -100
self.y = -100
self.dx = 0
self.dy = 0
self.speed = 0
self.dir = 0
self.gravity = 0
self.mass = 1
def update(self):
self.calcPos()
self.checkBounds()
self.rect.center = (self.x, self.y)
def calcVector(self):
radians = self.dir * math.pi / 180
self.dx = self.speed * math.cos(radians)
self.dy = self.speed * math.sin(radians)
self.dy *= -1
#clear the background
self.background.fill((0,0,0))
def calcPos(self):
#compensate for gravity
self.dy += self.gravity
#get old position for drawing
oldx = self.x
oldy = self.y
self.x += self.dx
self.y += self.dy
pygame.draw.line(self.background, (255,255,255), (oldx, oldy), (self.x, self.y))
def checkBounds(self):
screen = self.screen
if self.x > screen.get_width():
self.reset()
if self.x < 0:
self.reset()
if self.y > screen.get_height():
self.reset()
if self.y < 0:
self.reset()
def reset(self):
""" move off stage and stop"""
self.x = -100
self.y = -100
self.speed = 0
class Planet(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("pluto.gif")
self.image = self.image.convert()
self.image = pygame.transform.scale(self.image, (30, 30))
self.rect = self.image.get_rect()
self.mass = 500
self.x = 320
self.y = 240
self.rect.center = (self.x, self.y)
def gravitate(self, body):
""" calculates gravitational pull on
object """
(self.x, self.y) = self.rect.center
#get dx, dy, distance
dx = self.x - body.x
dy = self.y - body.y
distance = math.sqrt((dx * dx) + (dy * dy))
#normalize dx and dy
dx /= distance
dy /= distance
force = (body.mass * self.mass)/(math.pow(distance, 2))
dx *= force
dy *= force
body.dx += dx
body.dy += dy
def reset(self):
""" move off stage and stop"""
self.x = -100
self.y = -100
self.speed = 0
class Asteroid(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("asteroid01.png")
self.image = self.image.convert()
self.image = pygame.transform.scale(self.image, (30, 30))
self.rect = self.image.get_rect()
self.mass = 500
self.x = 320
self.y = 240
self.rect.center = (self.x, self.y)
def reset(self):
""" move off stage and stop"""
self.x = -100
self.y = -100
self.speed = 0
class Statboard(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.lives = 4
self.score = 0
self.font = pygame.font.SysFont("None", 50)
def update(self):
self.text = "Shells: %d, score: %d" % (self.lives, self.score)
self.image = self.font.render(self.text, 1, (255, 255, 0))
self.rect = self.image.get_rect()
def showInstructions(score):
shell = Shell(screen, background)
turret = Turret(shell)
allSprites = pygame.sprite.Group(shell,turret)
insFont = pygame.font.SysFont(None, 50)
insLabels = []
instructions = (
"Orbit Rider.",
"Instructions: You are a foreman for a ",
"space age demolition crew called Orbit Riders.",
"",
"shoot a shell with space bar at an asteroid ",
"in the orbit of planets.",
"but be careful not to miss,",
" we have limited ammo!",
"Control the turret with the left and right ",
" arrow keys and adjust speed with the",
" and adjust speed with the up and down arrow keys",
"Use the gravity of the planets to",
" bend the trajectory of the shell ",
"into the asteroids!",
"good luck!",
"click to start, escape to quit..."
)
for line in instructions:
tempLabel = insFont.render(line, 1, (255, 255, 0))
insLabels.append(tempLabel)
keepGoing = True
clock = pygame.time.Clock()
pygame.mouse.set_visible(False)
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
donePlaying = True
if event.type == pygame.MOUSEBUTTONDOWN:
keepGoing = False
donePlaying = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
keepGoing = False
donePlaying = True
allSprites.update()
allSprites.draw(screen)
for i in range(len(insLabels)):
screen.blit(insLabels[i], (50, 30*i))
pygame.display.flip()
pygame.mouse.set_visible(True)
return donePlaying
def game():
background.fill((0,0,0))
screen.blit(background, (0, 0))
shell = Shell(screen, background)
turret = Turret(shell)
planet = Planet()
planet.rect.center = (450,200)
asteroid = Asteroid()
asteroid.rect.center = (300,100)
statboard = Statboard()
friendSprites = pygame.sprite.Group(turret,shell)
targetSprites = pygame.sprite.Group(asteroid)
allySprites = pygame.sprite.Group(planet)
statSprites = pygame.sprite.Group(statboard)
clock = pygame.time.Clock()
keepGoing = True
while keepGoing:
clock.tick(30)
pygame.mouse.set_visible(True)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
#check collisions
Goodcollision = pygame.sprite.spritecollide(shell, targetSprites,False)
Badcollision = pygame.sprite.spritecollide(shell, allySprites,False)
planet.gravitate(shell)
if Goodcollision:
shell.boom.play()
shell.reset()
statboard.score += 1
elif Badcollision:
shell.reset()
statboard.lives -=1
if statboard.lives <= 0:
keepGoing = False
for theAsteroid in Goodcollision:
theAsteroid.reset()
statSprites.update()
friendSprites.update()
friendSprites.draw(screen)
targetSprites.draw(screen)
allySprites.draw(screen)
statSprites.draw(screen)
pygame.display.flip()
pygame.mouse.set_visible(True)
return statboard.score
def main():
donePlaying = False
score = 0
while not donePlaying:
donePlaying = showInstructions(score)
if not donePlaying:
score = game()
if __name__ == "__main__":
main()