Alien's Are Gonna Kill Me!

The game screen appears here if your browser supports the Canvas API.

Attribution

Essentials - Make Games with Python, pages 114 - 129.

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 __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
  soundEffect = 'sounds/player_laser.wav'
  pygame = None
  surface = None
  width = 0
  height = 0
  bullets = []
  bulletImage = "assets/you_pellet.png"
  bulletSpeed = -10
  health = 5

  def loadImages(self):
    self.image = self.pygame.image.load("assets/you_ship.png")

  def draw(self):
    self.surface.blit(self.image, (self.x, self.y))

  def setPosition(self, pos):
    self.x = pos[0] - self.width / 2
    # self.y = pos[1]

  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):
    self.health -= 1

  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)

    for usedBullet in bulletsToRemove:
      del self.bullets[usedBullet]

    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 = 2

  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

windowWidth = 1024
windowHeight = 614

pygame.init()
pygame.font.init()
clock = pygame.time.Clock()
surface = pygame.display.set_mode((windowWidth, windowHeight))

pygame.display.set_caption('Alien\'s Are Gonna Kill Me!')
textFont = pygame.font.SysFont("monospace", 50)

gameStarted = False
gameStartedTime = 0
gameFinishedTime = 0
gameOver = False

#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")

#Ships
ship = Player(windowWidth / 2, windowHeight, pygame, surface)
enemyShips = []

lastEnemyCreated = 0
enemyInterval = random.randint(1000, 2500)

#Sound Setup
pygame.mixer.init()

def updateGame():

  global mouseDown, gameOver

  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
        quitGame()

    else:
      enemiesToRemove.append(idx)

  for idx in enemiesToRemove:
    del enemyShips[idx]

def drawGame():
    surface.blit(background, (0, 0))
    ship.draw()
    ship.drawBullets()

    for enemy in enemyShips:
      enemy.draw()
      enemy.drawBullets()

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:

        gameStarted = True

    elif mouseStates[0] is 0 and mouseDown is True:
      mouseDown = False

  elif gameStarted is True and gameOver is True:
    surface.blit(startScreen, (0, 0))
    timeLasted = (gameFinishedTime - gameStartedTime) / 1000

  # Handle user and system events
  for event in GAME_EVENTS.get():

    if event.type == pygame.KEYDOWN:

      if event.key == pygame.K_ESCAPE:
        quitGame()

  if GAME_TIME.get_ticks() - lastEnemyCreated > enemyInterval and gameStarted is True:
    enemyShips.append(Enemy(random.randint(0, windowWidth), -60, pygame, surface, 1))
    lastEnemyCreated = GAME_TIME.get_ticks()

  if event.type == GAME_GLOBALS.QUIT:
    quitGame()

  clock.tick(60)
  pygame.display.update()