Alien's Are Gonna Kill Me!
Attribution
Essentials - Make Games with Python, pages 130 - 152.
Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.
Original Python code
import pygame, sys, random, math
import pygame.locals as GAME_GLOBALS
import pygame.event as GAME_EVENTS
import pygame.time as GAME_TIME
class Bullet():
x = 0
y = 0
image = None
pygame = None
surface = None
width = 0
height = 0
speed = 0.0
def loadImages(self):
self.image = self.pygame.image.load(self.image)
def draw(self):
self.surface.blit(self.image, (self.x, self.y))
def move(self):
self.y += self.speed
def checkForHit(self, thingToCheckAgainst):
if self.x > thingToCheckAgainst.x and self.x < thingToCheckAgainst.x + thingToCheckAgainst.width:
if self.y > thingToCheckAgainst.y and self.y < thingToCheckAgainst.y + thingToCheckAgainst.height:
thingToCheckAgainst.registerHit()
return True
return False
def __init__(self, x, y, pygame, surface, speed, image):
self.x = x
self.y = y
self.pygame = pygame
self.surface = surface
self.image = image
self.loadImages()
self.speed = speed
dimensions = self.image.get_rect().size
self.width = dimensions[0]
self.height = dimensions[1]
self.x -= self.width / 2
class Player():
x = 0
y = 0
firing = False
image = None
shieldImage = None
drawShield = False
soundEffect = 'sounds/player_laser.wav'
pygame = None
surface = None
width = 0
height = 0
bullets = []
bulletImage = "assets/you_pellet.png"
bulletSpeed = -10
health = 5
maxHealth = health
shields = 3
maxShields = shields
def loadImages(self):
self.image = self.pygame.image.load("assets/you_ship.png")
self.shieldImage = self.pygame.image.load("assets/shield2.png")
def draw(self):
self.surface.blit(self.image, (self.x, self.y))
if self.drawShield == True:
self.surface.blit(self.shieldImage, (self.x - 3, self.y - 2))
self.drawShield = False
def setPosition(self, pos):
self.x = pos[0] - self.width / 2
def fire(self):
self.bullets.append(Bullet(self.x + self.width / 2, self.y, self.pygame, self.surface, self.bulletSpeed, self.bulletImage))
a = self.pygame.mixer.Sound(self.soundEffect)
a.set_volume(0.2)
a.play()
def drawBullets(self):
for b in self.bullets:
b.move()
b.draw()
def registerHit(self):
if self.shields == 0:
self.health -= 1
else :
self.shields -= 1
self.drawShield = True
def checkForHit(self, thingToCheckAgainst):
bulletsToRemove = []
for idx, b in enumerate(self.bullets):
if b.x > thingToCheckAgainst.x and b.x < thingToCheckAgainst.x + thingToCheckAgainst.width:
if b.y > thingToCheckAgainst.y and b.y < thingToCheckAgainst.y + thingToCheckAgainst.height:
thingToCheckAgainst.registerHit()
bulletsToRemove.append(idx)
bC = 0
for usedBullet in bulletsToRemove:
del self.bullets[usedBullet - bC]
bC += 1
if thingToCheckAgainst.health <= 0:
return True
def __init__(self, x, y, pygame, surface):
self.x = x
self.y = y
self.pygame = pygame
self.surface = surface
self.loadImages()
dimensions = self.image.get_rect().size
self.width = dimensions[0]
self.height = dimensions[1]
self.x -= self.width / 2
self.y -= self.height + 10
class Enemy(Player):
x = 0
y = 0
firing = False
image = None
soundEffect = 'sounds/enemy_laser.wav'
bulletImage = "assets/them_pellet.png"
bulletSpeed = 10
speed = 4
shields = 0
def move(self):
self.y += self.speed
def tryToFire(self):
shouldFire = random.random()
if shouldFire <= 0.01:
self.fire()
def loadImages(self):
self.image = self.pygame.image.load("assets/them_ship.png")
def __init__(self, x, y, pygame, surface, health):
self.x = x
self.y = y
self.pygame = pygame
self.surface = surface
self.loadImages()
self.bullets = []
self.health = health
dimensions = self.image.get_rect().size
self.width = dimensions[0]
self.height = dimensions[1]
self.x += self.width / 2
level = [
{
"structure" :[ [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
],
"interval" : 4
},
{
"structure" :[ [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
],
"interval" : 5
},
{
"structure" :[ [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
],
"interval" : 4
},
{
"structure" :[ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
],
"interval" : 4
},
{
"structure" :[ [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0]
],
"interval" : 3
}
]
windowWidth = 1024
windowHeight = 614
timeTick = 0
pygame.init()
pygame.font.init()
clock = pygame.time.Clock()
surface = pygame.display.set_mode((windowWidth, windowHeight), pygame.FULLSCREEN|pygame.HWSURFACE|pygame.DOUBLEBUF)
pygame.display.set_caption('Alien\'s Are Gonna Kill Me!')
textFont = pygame.font.SysFont("monospace", 50)
gameStarted = False
gameStartedTime = 0
gameFinishedTime = 0
gameOver = False
gameWon = False
currentLevel = 0
currentWave = 0
lastSpawn = 0
nextLevelTS = 0
#Mouse Variables
mousePosition = (0,0)
mouseStates = None
mouseDown = False
#Image Variables
startScreen = pygame.image.load("assets/start_screen.png")
background = pygame.image.load("assets/background.png")
loseScreen = pygame.image.load("assets/lose_screen.png")
winScreen = pygame.image.load("assets/win_screen.png")
nextWave = pygame.image.load("assets/next_level.png")
finalWave = pygame.image.load("assets/final_level.png")
#Ships
ship = Player(windowWidth / 2, windowHeight, pygame, surface)
enemyShips = []
leftOverBullets = []
#Sound Setup
pygame.mixer.init()
def launchWave():
global lastSpawn, currentWave, currentLevel, gameOver, gameWon, nextLevelTS
thisLevel = level[currentLevel]["structure"]
if currentWave < len(thisLevel):
thisWave = thisLevel[currentWave]
for idx, enemyAtThisPosition in enumerate(thisWave):
if enemyAtThisPosition is 1:
enemyShips.append(Enemy(((windowWidth / len(thisWave)) * idx), -60, pygame, surface, 1))
elif currentLevel + 1 < len(level) :
currentLevel += 1
currentWave = 0
ship.shields = ship.maxShields
nextLevelTS = timeTick + 5000
else:
gameWon = True
lastSpawn = timeTick
currentWave += 1
def updateGame():
global mouseDown, gameOver, gameWon, leftOverBullets
if mouseStates[0] is 1 and mouseDown is False:
ship.fire()
mouseDown = True
elif mouseStates[0] is 0 and mouseDown is True:
mouseDown = False
ship.setPosition(mousePosition)
enemiesToRemove = []
for idx, enemy in enumerate(enemyShips):
if enemy.y < windowHeight:
enemy.move()
enemy.tryToFire()
shipIsDestroyed = enemy.checkForHit(ship)
enemyIsDestroyed = ship.checkForHit(enemy)
if enemyIsDestroyed is True:
enemiesToRemove.append(idx)
if shipIsDestroyed is True:
gameOver = True
gameWon = False
return
else:
enemiesToRemove.append(idx)
oC = 0
for idx in enemiesToRemove:
for remainingBullets in enemyShips[idx - oC].bullets:
leftOverBullets.append(remainingBullets)
del enemyShips[idx - oC]
oC += 1
oC = 0
for idx, aBullet in enumerate(leftOverBullets):
aBullet.move()
hitShip = aBullet.checkForHit(ship)
if hitShip is True or aBullet.y > windowHeight:
del leftOverBullets[idx - oC]
oC += 1
def drawGame():
global leftOverBullets, nextLevelTS, timeTick, gameWon
surface.blit(background, (0, 0))
ship.draw()
ship.drawBullets()
for aBullet in leftOverBullets:
aBullet.draw()
healthColor = [(62, 180, 76), (180, 62, 62)]
whichColor = 0
if(ship.health <= 1):
whichColor = 1
for enemy in enemyShips:
enemy.draw()
enemy.drawBullets()
pygame.draw.rect(surface, healthColor[whichColor], (0, windowHeight - 5, (windowWidth / ship.maxHealth) * ship.health, 5))
pygame.draw.rect(surface, (62, 145, 180), (0, windowHeight - 10, (windowWidth / ship.maxShields) * ship.shields, 5))
if timeTick < nextLevelTS:
if gameWon is True:
surface.blit(finalWave, (250, 150))
else:
surface.blit(nextWave, (250, 150))
def restartGame():
global gameOver, gameStart, currentLevel, currentWave, lastSpawn, nextLevelTS, leftOverBullets, gameWon, enemyShips, ship
gameOver = False
gameWon = False
currentLevel = 0
currentWave = 0
lastSpawn = 0
nextLevelTS = 0
leftOverBullets = []
enemyShips = []
ship.health = ship.maxHealth
ship.shields = ship.maxShields
ship.bullets = []
def quitGame():
pygame.quit()
sys.exit()
# 'main' loop
while True:
timeTick = GAME_TIME.get_ticks()
mousePosition = pygame.mouse.get_pos()
mouseStates = pygame.mouse.get_pressed()
if gameStarted is True and gameOver is False:
updateGame()
drawGame()
elif gameStarted is False and gameOver is False:
surface.blit(startScreen, (0, 0))
if mouseStates[0] is 1:
if mousePosition[0] > 445 and mousePosition[0] < 580 and mousePosition[1] > 450 and mousePosition[1] < 510:
pygame.mouse.set_visible(False)
gameStarted = True
elif mouseStates[0] is 0 and mouseDown is True:
mouseDown = False
elif gameStarted is True and gameOver is True and gameWon is False:
surface.blit(loseScreen, (0, 0))
timeLasted = (gameFinishedTime - gameStartedTime) / 1000
if gameStarted is True and gameWon is True and len(enemyShips) is 0:
surface.blit(winScreen, (0, 0))
# Handle user and system events
for event in GAME_EVENTS.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quitGame()
if event.key == pygame.K_SPACE:
if gameStarted is True and gameOver is True or gameStarted is True and gameWon is True:
restartGame()
if timeTick - lastSpawn > level[currentLevel]["interval"] * 1000 and gameStarted is True and gameOver is False:
launchWave()
if event.type == GAME_GLOBALS.QUIT:
quitGame()
clock.tick(60)
pygame.display.update()