Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Invasion!
- # Originally created for Ludum Dare 25
- # Theme: "You are the villian"
- # Code: GNU Genral Public License 3.0
- # Images: All Rights Reserved (At artist's request)
- # LethalWare.co.uk
- # Post Compo re-release
- #Changelog:
- # Vastly improved graphics and sound
- # New menu screen
- # Code refactored
- # Upgrades now have a base cost of 80 rather than 100
- # Bullet "physics" overhauled.
- # Pausing
- # 'Splosions!
- #To do:
- # More / unique upgrades
- # Animate tank
- # coding = UTF-8
- #Imports
- import pygame
- import sys
- import os
- import random
- import math
- import pickle
- import sprite
- from time import sleep
- from pygame.locals import *
- pygame.init()
- clock = pygame.time.Clock()
- WIDTH = 800
- HEIGHT = 600
- screen = pygame.display.set_mode((WIDTH, HEIGHT))
- gamename = "Invasion!"
- pygame.display.set_caption(gamename)
- pygame.mouse.set_visible(False)
- SCREENRECT = pygame.Rect((0, 0), screen.get_size())
- red = (255, 0, 0)
- green = (0, 255, 0)
- black = (0, 0, 0)
- explosionFrames = [pygame.image.load("Images\explosion frames\explosion {0}.png".format(str(i))) for i in range(1, 8)]
- def isNegative(num):
- try:
- math.sqrt(num)
- return False
- except:
- return True
- def deNegate(num):
- if isNegative(num):
- return -num
- else:
- return num
- def end():
- pygame.quit()
- sys.exit(0)
- def pause(pauseimg = "Images/pause.png", unpause = K_ESCAPE, framerate = 30):
- sleeptime = 1 / framerate #Unpause on-frame with maximum efficiency
- paused = True
- img = pygame.image.load(pauseimg).convert_alpha()
- screen.blit(img, (0, 0))
- pygame.display.update()
- pygame.event.clear()
- while paused:
- sleep(sleeptime)
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- sys.exit(0)
- elif event.type == KEYDOWN:
- if event.key == unpause:
- paused = False
- class Cursor():
- def __init__(self, img = "Images/cursor.png"):
- self.img = pygame.image.load(img).convert_alpha()
- def draw(self):
- pos = [pygame.mouse.get_pos()[i] - self.img.get_size()[i] / 2
- for i in range(2)]
- screen.blit(self.img, pos)
- class menuOption():
- def __init__(self, img, pos, clickedImg = None, startState = False):
- if isinstance(img, pygame.Surface):
- self.img = img
- else:
- self.img = pygame.image.load(img).convert_alpha()
- self.pos = pos
- self.rect = pygame.Rect(self.pos, self.img.get_size())
- self.clickedImg = clickedImg
- if startState:
- self.img, self.clickedImg = self.clickedImg, self.img
- def draw(self):
- screen.blit(self.img, self.pos)
- def checkClick(self):
- if self.rect.collidepoint(pygame.mouse.get_pos()):
- if self.clickedImg:
- self.img, self.clickedImg = self.clickedImg, self.img # Swap
- return True
- else:
- return False
- class playerInputBox():
- def __init__(self, font, colour, pos = None, maxlen = None):
- self.text = ""
- self.font = font
- if pos is None:
- self.pos = (WIDTH / 2, HEIGHT / 2)
- self.central = True
- else:
- self.pos = pos
- self.central = False
- self.colour = colour
- self.maxlen = maxlen
- self.textImg = self.font.render(self.text, True, self.colour).convert_alpha()
- alphabet = "abcdefghigklmnopqrstuvwxyz1234567890"
- self.key2char = {eval("K_" + char) : char for char in alphabet}
- self.key2upperchar = {eval("K_" + char) : char.upper() for char in alphabet}
- self.upperCase = False
- self.shift = False
- def draw(self):
- screen.blit(self.textImg, self.pos)
- def recentralise(self):
- self.pos = (WIDTH / 2 - self.textImg.get_width() / 2,
- HEIGHT / 2 - self.textImg.get_height() / 2)
- def key_input(self, key, boolean):
- if boolean:
- if key in self.key2char and (self.maxlen is None or len(self.text) < self.maxlen):
- if (self.upperCase and not self.shift) or (self.shift and not self.upperCase):
- self.text += self.key2upperchar[key]
- else:
- self.text += self.key2char[key]
- self.textImg = self.font.render(self.text, True, self.colour).convert_alpha()
- if self.central:
- self.recentralise()
- elif key == K_BACKSPACE:
- self.text = self.text[:len(self.text) - 1]
- self.textImg = self.font.render(self.text, True, self.colour).convert_alpha()
- if self.central:
- self.recentralise()
- elif key == K_CAPSLOCK:
- if self.upperCase:
- self.upperCase = False
- else:
- self.upperCase = True
- elif key == K_SPACE:
- self.text += " "
- self.textImg = self.font.render(self.text, True, self.colour).convert_alpha()
- if self.central:
- self.recentralise()
- if key == K_LSHIFT or key == K_RSHIFT:
- self.shift = boolean
- class GUIManager():
- def __init__(self, font = "Lucida Console, Trebuchet MS, Verdana", size = 24,
- medSize = 48, largeSize = 72, menuColour = (0, 50, 255)):
- self.font = pygame.font.SysFont(font, size)
- self.medFont = pygame.font.SysFont(font, medSize)
- self.largeFont = pygame.font.SysFont(font, largeSize)
- self.menuColour = menuColour
- self.menuimg = pygame.image.load("Images/menu.png")
- def drawHUD(self, ship):
- texts = (self.font.render("Score: " + str(ship.score),
- True, black).convert_alpha(),
- self.font.render("", True, black).convert(),
- self.font.render("Scrap:" + str(ship.scrap),
- True, black).convert_alpha(),
- self.font.render("1: Laser Power ({0}): ".format(str(ship.laserPower * ship.upgradeCost)) + str(ship.laserPower),
- True, black).convert_alpha(),
- self.font.render("2: Armour ({0}): ".format(str(ship.armour * ship.upgradeCost)) + str(ship.armour),
- True, black).convert_alpha(),
- self.font.render("3: Speed ({0}): ".format(str(ship.speed * ship.upgradeCost)) + str(ship.speed),
- True, black).convert_alpha())
- cumulativeHeight = 0
- for text in texts:
- screen.blit(text, (0, cumulativeHeight))
- cumulativeHeight += text.get_height()
- def instructions(self):
- title = self.largeFont.render("Instructions", True, self.menuColour).convert_alpha()
- text = self.font.render("Press any key to return to the main menu", True, self.menuColour).convert_alpha()
- instructions = ("WASD: Movement",
- "ESC to pause",
- "Click: Fire the laser",
- "1: Upgrade laser power with scrap",
- "2: Upgrade ship armour with scrap",
- "3: Upgrade ship speed with scrap",
- "4: hold to use scrap to repair the ship",
- "",
- "While the laser is firing",
- "the ship cannot be repaired as the crew is busy",
- "",
- "Scrap is accumulated by killing enemies",
- "Upgrade cost is listed beside the upgrade in the HUD")
- txtInstructions = []
- for line in instructions:
- txtInstructions.append(self.font.render(line, True, self.menuColour).convert_alpha())
- screen.fill(black)
- screen.blit(title, (WIDTH / 2 - title.get_width() / 2 , 0))
- screen.blit(text, (WIDTH / 2 - text.get_width() / 2, HEIGHT - text.get_height()))
- y = sum(line.get_height() for line in txtInstructions) / 2
- for line in txtInstructions:
- screen.blit(line, (WIDTH / 2 - line.get_width() / 2, HEIGHT / 2 + line.get_height() / 2 - y))
- y -= line.get_height()
- pygame.display.update()
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- elif event.type == KEYDOWN:
- return True
- def menu(self, cursor, sm, hsm):
- playRect = pygame.Rect((277, 173), (245, 73))
- instructionsRect = pygame.Rect((277, 260), (245, 73))
- highScoresRect = pygame.Rect((277, 347), (245, 73))
- creditsRect = pygame.Rect((277, 434), (245, 73))
- endRect = pygame.Rect((713, 15), (72, 21))
- audioButtonText = pygame.image.load("Images/note_green.png").convert_alpha()
- audioButtonClickedText = pygame.image.load("Images/note_red.png").convert_alpha()
- audioButton = menuOption(audioButtonText,
- (0, 0),
- audioButtonClickedText)
- while True:
- screen.fill(black)
- screen.blit(self.menuimg, (0, 0))
- audioButton.draw()
- cursor.draw()
- pygame.display.update()
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- elif event.type == MOUSEBUTTONDOWN:
- if audioButton.checkClick():
- sm.mute()
- elif playRect.collidepoint(pygame.mouse.get_pos()):
- return True
- elif instructionsRect.collidepoint(pygame.mouse.get_pos()):
- self.instructions()
- elif highScoresRect.collidepoint(pygame.mouse.get_pos()):
- self.highScoreBoard(hsm)
- elif creditsRect.collidepoint(pygame.mouse.get_pos()):
- self.credits()
- elif endRect.collidepoint(pygame.mouse.get_pos()):
- end()
- def credits(self):
- strCredits = ("Code and menu music",
- "xGeovanni",
- "",
- "Art",
- "BloodStalker",
- "",
- '"Battle In The Winter"',
- "Johan Brodd",
- "",
- "LethalWare.co.uk")
- txtCredits = [self.medFont.render(credit , True, self.menuColour).convert_alpha() for credit in strCredits]
- text = self.font.render("Press any key to return to the main menu", True, self.menuColour).convert_alpha()
- screen.fill(black)
- y = sum(line.get_height() for line in txtCredits) / 2
- for line in txtCredits:
- screen.blit(line, (WIDTH / 2 - line.get_width() / 2, HEIGHT / 2 + line.get_height() / 2 - y))
- y -= line.get_height()
- screen.blit(text, (WIDTH / 2 - text.get_width() / 2,
- HEIGHT - text.get_height()))
- pygame.display.update()
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- sys.exit(0)
- elif event.type == KEYDOWN:
- return True
- def lose(self):
- youLose = self.largeFont.render("You Lose!", True, self.menuColour).convert_alpha()
- text = self.font.render("Press any key to return to the main menu", True, self.menuColour).convert_alpha()
- screen.fill(black)
- screen.blit(youLose, (WIDTH / 2 - youLose.get_width() / 2,
- HEIGHT / 2 - youLose.get_height() / 2))
- screen.blit(text, (WIDTH / 2 - text.get_width() / 2,
- HEIGHT - text.get_height()))
- pygame.display.update()
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- sys.exit(0)
- elif event.type == KEYDOWN:
- return True
- def highScoreBoard(self, hsm):
- title = self.largeFont.render("High Scores", True, self.menuColour).convert_alpha()
- text = self.font.render("Press any key to return to the main menu", True, self.menuColour).convert_alpha()
- highScores = []
- for highscore in hsm.highscores:
- highScores.append(self.largeFont.render(highscore[0] + ": " + str(highscore[1]), True, self.menuColour).convert_alpha())
- screen.fill(black)
- screen.blit(title, (WIDTH / 2 - title.get_width() / 2, 0))
- screen.blit(text, (WIDTH / 2 - text.get_width() / 2, HEIGHT - text.get_height()))
- y = sum(line.get_height() for line in highScores) / 2
- for line in highScores:
- screen.blit(line, (WIDTH / 2 - line.get_width() / 2, HEIGHT / 2 + line.get_height() / 2 - y))
- y -= line.get_height()
- pygame.display.update()
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- elif event.type == KEYDOWN:
- return True
- def newHighScore(self):
- title = self.largeFont.render("New High Score!", True, self.menuColour).convert_alpha()
- text = self.font.render("Enter your name", True, self.menuColour).convert_alpha()
- inputBox = playerInputBox(self.largeFont, self.menuColour, maxlen = 10)
- while True:
- clock.tick(10)
- screen.fill(black)
- screen.blit(title, (WIDTH / 2 - title.get_width() / 2, 0))
- screen.blit(text, (WIDTH / 2 - text.get_width() / 2, HEIGHT - text.get_height()))
- inputBox.draw()
- pygame.display.update()
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- elif event.type == KEYDOWN:
- if event.key == K_RETURN:
- return inputBox.text
- else:
- inputBox.key_input(event.key, True)
- elif event.type == KEYUP:
- inputBox.key_input(event.key, False)
- class SoundManager():
- def __init__(self):
- self.sounds = {"bullet" : pygame.mixer.Sound("Sounds/bullet.wav"),
- "laserstart" : pygame.mixer.Sound("Sounds/laserstart.wav"),
- "laserstop" : pygame.mixer.Sound("Sounds/laserstop.wav"),
- "explosion" : pygame.mixer.Sound("Sounds/explosion.wav")}
- self.music = {"menu" : "Sounds/Music/menu.ogg",
- "battle" : "Sounds/Music/Battle in the winter.ogg"}
- self.isMuted = False
- def play(self, sound, loops = 0, fadems = 0):
- self.sounds[sound].play(loops, 0, fadems)
- def loadSong(self, song):
- pygame.mixer.music.load(self.music[song])
- if not self.isMuted:
- pygame.mixer.music.play(-1)
- def stop(self, sound):
- self.sounds[sound].stop()
- def stopSong(self, fadeout = 0):
- if not self.isMuted:
- if fadeout == 0:
- pygame.mixer.music.stop()
- else:
- pygame.mixer.music.fadeout(fadeout)
- def mute(self):
- if self.isMuted:
- for sound in self.sounds:
- self.sounds[sound].set_volume(1)
- self.isMuted = False
- pygame.mixer.music.unpause()
- else:
- for sound in self.sounds:
- self.sounds[sound].set_volume(0)
- self.isMuted = True
- pygame.mixer.music.pause()
- class HighScoreManager():
- def __init__(self):
- self.filename = "highscores.dat"
- self.numScores = 5
- if not os.path.isfile(self.filename):
- self.setup()
- else:
- file = open(self.filename, "rb")
- try:
- self.highscores = pickle.load(file)
- except EOFError:
- self.setup()
- file.close()
- self.file = open(self.filename, "wb")
- self.names = [highscore[0] for highscore in self.highscores]
- self.scores = [highscore[1] for highscore in self.highscores]
- self.updateFile()
- def __del__(self):
- self.file.close()
- def setup(self):
- self.file = open(self.filename, "wb")
- baseScore = 100
- self.scores = [baseScore for i in range(self.numScores)]
- self.names = ["A", "B", "C", "D", "E"]
- self.highscores = [(self.names[i], self.scores[i]) for i in range(self.numScores)]
- self.updateFile()
- def checkScore(self, score):
- tempScores = self.scores[:] # Copy
- tempScores.append(score)
- tempScores.sort(reverse = True)
- tempScores = tempScores[:self.numScores]
- return (score in tempScores) # True if score is in tempScores
- def addScore(self, name, score):
- self.scores.append(score) #Add new score
- self.scores.sort(reverse = True) #Sort
- self.names.insert(self.scores.index(score), name)
- self.names = self.names[:self.numScores] # Top 5
- self.scores = self.scores[:self.numScores]
- self.highscores = [(self.names[i], self.scores[i]) for i in range(self.numScores)]
- self.updateFile()
- def updateFile(self):
- self.file.close()
- self.file = open(self.filename, "wb")
- pickle.dump(self.highscores, self.file)
- class UnitManager():
- def __init__(self, sm):
- self.units = []
- self.explosions = []
- self.sm = sm
- self.baseSpawnRate = 80
- self.explosionDelay = 2
- self.explosionFrames = [pygame.image.load("Images\explosion frames\explosion {0}.png".format(str(i))).convert_alpha() for i in range(1, 8)]
- def spawn(self, unitclass):
- self.units.append(unitclass())
- def kill(self, unit):
- self.units.remove(unit)
- def explode(self, unit):
- self.explosions.append(sprite.Sprite(screen, self.explosionFrames, unit.x, unit.y, self.explosionDelay))
- self.sm.play("explosion")
- def updateExplosions(self):
- for explosion in self.explosions:
- explosion.animatedDraw()
- if explosion.cycles >= 1:
- self.explosions.remove(explosion)
- def update(self, beam, bm, ship, sm):
- self.updateExplosions()
- for unit in self.units:
- unit.draw()
- unit.move()
- unit.HPBar.draw()
- if beam:
- for point in beam:
- if unit.rect.collidepoint(point):
- unit.remHP(ship.laserDamage)
- break
- if unit.shoots and random.randint(1, unit.fireRate) == 1:
- sm.play("bullet")
- bm.add(unit.fire(ship))
- if unit.HP <= 0:
- self.kill(unit)
- if unit.explodes:
- self.explode(unit)
- ship.addScrap(unit.scrapValue)
- if unit.delete:
- self.kill(unit)
- if random.randint(1, int((self.baseSpawnRate / ship.upgradeLevel) * len(self.units) + 1)) == 1:
- choice = random.randrange(1, 20)
- if choice in range(1, 6):
- self.spawn(Person)
- elif choice in range(6, 12):
- self.spawn(Soldier)
- elif choice == 13:
- self.spawn(StealthPlane)
- elif choice in range(13, 18):
- self.spawn(Helicopter)
- elif choice in range(19, 20):
- self.spawn(Tank)
- class HPBar():
- def __init__(self, maxHP, anchor, sizeIncreaseTrigger = 100):
- self.maxHP = maxHP
- self.currentHP = maxHP
- self.anchor = anchor
- self.greenbar = pygame.image.load("Images/HPbars/greenbar.png").convert()
- self.redbar = pygame.image.load("Images/HPbars/redbar.png").convert()
- if sizeIncreaseTrigger and maxHP >= sizeIncreaseTrigger:
- self.greenbar = pygame.transform.scale(self.greenbar, (self.greenbar.get_width() * math.floor(maxHP / sizeIncreaseTrigger), self.redbar.get_height()))
- self.redbar = pygame.transform.scale(self.redbar, (self.redbar.get_width() * math.floor(maxHP / sizeIncreaseTrigger), self.redbar.get_height()))
- self.maxwidth = self.greenbar.get_width()
- self.x = self.anchor.x + self.anchor.img.get_width() / 2 - self.redbar.get_width() / 2
- self.y = self.anchor.y - self.redbar.get_height()
- def updateHP(self, currentHP):
- self.currentHP = currentHP
- if currentHP > 0:
- newwidth = math.floor(self.maxwidth * (self.currentHP / self.maxHP))
- self.greenbar = pygame.transform.scale(self.greenbar, (newwidth, self.greenbar.get_height()))
- else:
- self.greenbar.set_alpha(255)
- def draw(self):
- screen.blit(self.redbar, (self.x, self.y))
- screen.blit(self.greenbar, (self.x, self.y))
- def move(self):
- self.x = self.anchor.x + self.anchor.img.get_width() / 2 - self.redbar.get_width() / 2
- self.y = self.anchor.y - self.redbar.get_height()
- class Ship():
- def __init__(self, img = "Images/ship.png", HP = 400):
- self.leftimg = pygame.image.load(img).convert_alpha()
- self.rightimg = pygame.transform.flip(self.leftimg, True, False)
- self.img = self.rightimg
- self.x = WIDTH / 2 - self.img.get_width() / 2
- self.y = self.img.get_height()
- self.midpoint = (self.x + self.img.get_width() / 2,
- self.y + self.img.get_height() / 2)
- self.maxHP = HP
- self.HP = HP
- self.HPBar = HPBar(HP, self)
- self.rect = pygame.Rect((self.x, self.y), self.img.get_size())
- self.score = 0
- self.scrap = 0
- self.speed = 5
- self.armour = 1
- self.laserPower = 1
- self.upgradeLevel = self.laserPower + self.armour + self.speed
- self.upgradeCost = 80
- self.laserOffset = 0.8
- self.laserDamage = self.laserPower * self.laserOffset
- self.maxLevel = 5
- #Movement boolean variables
- self.up = False
- self.down = False
- self.left = False
- self.right = False
- self.firing = False
- self.healing = False
- # # # # #
- def draw(self):
- screen.blit(self.img, (self.x, self.y))
- self.HPBar.draw()
- def regen(self):
- if self.healing and self.scrap > 0:
- self.HP += 1
- self.scrap -= 1
- def addScrap(self, amount):
- self.scrap += amount
- self.score += amount * 10
- def respondToKey(self, key, boolean):
- if key == K_w:
- self.up = boolean
- elif key == K_a:
- self.left = boolean
- if boolean:
- self.img = self.leftimg
- elif key == K_s:
- self.down = boolean
- elif key == K_d:
- self.right = boolean
- if boolean:
- self.img = self.rightimg
- self.spendScrap(key, boolean)
- def respondToMouse(self, boolean):
- self.firing = boolean
- def spendScrap(self, key, boolean):
- if boolean and key in (K_1, K_2, K_3):
- if key == K_1 and self.scrap >= self.upgradeCost * self.laserPower and self.laserPower < self.maxLevel:
- self.scrap -= self.upgradeCost * self.laserPower
- self.laserPower += 1
- self.laserDamage = self.laserPower * self.laserOffset
- elif key == K_2 and self.scrap >= self.upgradeCost * self.armour and self.armour < self.maxLevel:
- self.scrap -= self.upgradeCost * self.armour
- self.armour += 1
- elif key == K_3 and self.scrap >= self.upgradeCost * self.speed and self.speed < self.maxLevel:
- self.scrap -= self.upgradeCost * self.speed
- self.speed += 1
- self.upgradeLevel = self.laserPower + self.armour + self.speed
- if key == K_4:
- self.healing = boolean
- def remHP(self, loss):
- self.HP -= loss * (1 - self.armour / 10)
- self.HPBar.updateHP(self.HP)
- def update(self):
- if self.up or self.down or self.left or self.right:
- if self.up and not self.y < 0:
- self.y -= self.speed * 4
- elif self.down and not self.y > HEIGHT - self.img.get_height():
- self.y += self.speed * 4
- if self.left and not self.x < 0:
- self.x -= self.speed * 4
- elif self.right and not self.x > WIDTH - self.img.get_width():
- self.x += self.speed * 4
- self.midpoint = (self.x + self.img.get_width() / 2,
- self.y + self.img.get_height() / 2)
- self.rect = pygame.Rect((self.x, self.y), self.img.get_size())
- self.HPBar.move()
- if self.firing:
- return self.fire()
- else:
- if self.HP < self.maxHP:
- self.regen()
- def fire(self):
- mousepos = pygame.mouse.get_pos()
- pygame.draw.line(screen, red, self.midpoint,
- mousepos, 3 * self.laserPower)
- points = []
- numpoints = 100
- for i in range(1, numpoints):
- points.append((self.midpoint[0] + (mousepos[0] -
- self.midpoint[0]) * (i/numpoints),
- self.midpoint[1] + (mousepos[1] -
- self.midpoint[1]) * (i/numpoints)))
- return points
- class BulletManager():
- def __init__(self):
- self.bullets = []
- def update(self, ship):
- for bullet in self.bullets:
- bullet.move()
- bullet.draw()
- if ship.rect.colliderect(bullet.rect):
- self.remove(bullet)
- ship.remHP(bullet.damage)
- elif (bullet.x, bullet.y) == bullet.target:
- self.remove(bullet)
- if not SCREENRECT.colliderect(bullet.rect):
- self.remove(bullet)
- def add(self, bullet):
- self.bullets.append(bullet)
- def remove(self, bullet):
- self.bullets.remove(bullet)
- class Bullet():
- def __init__(self, startpoint, target,
- damage = 3, img = "Images/bullet.png", speed = 7):
- self.img = pygame.image.load(img).convert_alpha()
- self.x = startpoint[0]
- self.y = startpoint[1]
- self.target = target
- self.rect = ((self.x, self.y), self.img.get_size())
- self.damage = damage
- self.speed = speed
- self.xdist = (target[0] - self.x)
- self.ydist = (target[1] - self.y)
- self.movesToTarget = math.ceil(math.sqrt(self.xdist ** 2 + self.ydist ** 2) / speed)
- def draw(self):
- screen.blit(self.img, (self.x, self.y))
- def move(self):
- self.x += self.xdist / self.movesToTarget
- self.y += self.ydist / self.movesToTarget
- self.rect = ((self.x, self.y), self.img.get_size())
- if self.movesToTarget > 1:
- self.movesToTarget -= 1
- class Unit():
- def __init__(self, HP):
- self.HP = HP
- self.HPBar = HPBar(HP, self)
- self.rect = pygame.Rect((self.x, self.y), self.img.get_size())
- self.fireRate = 100
- self.explodes = True
- self.delete = False
- def remHP(self, loss):
- self.HP -= loss
- self.HPBar.updateHP(self.HP)
- def draw(self):
- screen.blit(self.img, (self.x, self.y))
- def move(self):
- if self.x < 0 or self.x > WIDTH - self.img.get_width():
- self.speed = -(self.speed)
- if self.img == self.rightimg:
- self.img = self.leftimg
- else:
- self.img = self.rightimg
- self.x += self.speed
- self.rect = pygame.Rect((self.x, self.y), self.img.get_size())
- self.HPBar.move()
- self.midpoint = (self.x + self.img.get_width() / 2,
- self.y + self.img.get_height() / 2)
- def fire(self, ship):
- return Bullet(self.midpoint, ship.midpoint, self.damage)
- class Person(Unit):
- def __init__(self, img = "Images/person.png", HP = 5):
- self.img = pygame.image.load(img).convert_alpha()
- self.x = random.randint(10, WIDTH)
- self.y = HEIGHT - self.img.get_height()
- self.speed = random.randint(-5, 5)
- if self.speed == 0:
- self.moves = 0
- elif not isNegative(self.speed):
- self.moves = random.randint(1, math.floor(WIDTH / self.speed))
- else:
- self.moves = random.randint(1, math.floor(self.x / -self.speed))
- self.midpoint = (self.x + self.img.get_width() / 2,
- self.y + self.img.get_height() / 2)
- self.shoots = False # Whether this mob can shoot
- self.scrapValue = 1
- Unit.__init__(self, HP)
- self.explodes = False
- def move(self):
- if self.moves > 0:
- self.x += self.speed
- self.moves -= 1
- else:
- self.speed = -(self.speed)
- if self.speed == 0:
- self.moves = 0
- elif not isNegative(self.speed):
- self.moves = random.randint(1, math.floor(WIDTH / self.speed))
- else:
- self.moves = random.randint(1, math.floor(self.x / -self.speed))
- if self.x > WIDTH or self.x < -self.img.get_width():
- self.delete = True
- self.rect = pygame.Rect((self.x, self.y), self.img.get_size())
- self.HPBar.move()
- self.midpoint = (self.x + self.img.get_width() / 2,
- self.y + self.img.get_height() / 2)
- class Tank(Unit):
- def __init__(self, img = "Images/tank.png", HP = 200, speed = 10):
- self.rightimg = pygame.image.load(img).convert_alpha()
- self.leftimg = pygame.transform.flip(self.rightimg, True, False)
- self.img = self.leftimg
- self.x = random.randint(self.img.get_width(),
- WIDTH - self.img.get_width())
- self.y = HEIGHT - self.img.get_height()
- self.speed = speed
- self.shoots = True # Whether this mob can shoot
- self.scrapValue = 10
- self.damage = 5
- Unit.__init__(self, HP)
- class Helicopter(Unit):
- def __init__(self, img = "Images/helicopter.png", HP = 50, speed = 15):
- self.rightimg = pygame.image.load(img).convert_alpha()
- self.leftimg = pygame.transform.flip(self.rightimg, True, False)
- self.img = self.leftimg
- self.x = random.randint(self.img.get_width(),
- WIDTH - self.img.get_width())
- self.y = random.randint(0, int(HEIGHT - HEIGHT / 4))
- self.speed = speed
- self.shoots = True # Whether this mob can shoot
- self.scrapValue = 7
- self.damage = 4
- Unit.__init__(self, HP)
- class StealthPlane(Unit):
- def __init__(self, img = "Images/stealth plane.png", HP = 20):
- leftimg = pygame.image.load(img).convert_alpha()
- rightimg = pygame.transform.flip(leftimg, True, False)
- self.dir = random.choice(("left", "right"))
- self.speed = random.randint(20, 30)
- if self.dir == "left":
- self.img = leftimg
- self.speed = -(self.speed)
- else:
- self.img = rightimg
- self.y = random.randint(0, HEIGHT / 4)
- if self.dir == "left":
- self.x = WIDTH
- else:
- self.x = -self.img.get_width()
- self.scrapValue = deNegate(self.speed) * 5
- self.shoots = False
- Unit.__init__(self, HP)
- def move(self):
- self.x += self.speed
- self.rect = pygame.Rect((self.x, self.y), self.img.get_size())
- self.HPBar.move()
- if self.x > WIDTH and self.dir == "right":
- self.delete = True
- elif self.x < -self.img.get_width() and self.dir == "left":
- self.delete = True
- class Soldier(Person):
- def __init__(self, img = "Images/soldier.png", HP = 8):
- Person.__init__(self, img, HP)
- self.shoots = True
- self.scrapValue = 2
- self.damage = 3
- self.explodes = False
- class Background():
- def __init__(self, img):
- self.img = pygame.image.load(img).convert()
- if self.img.get_size() != screen.get_size():
- self.img = pygame.transform.scale(self.img, screen.get_size())
- def draw(self):
- screen.blit(self.img, (0, 0))
- def play(gm, sm, cursor):
- bg = Background("Images/bg.png")
- ship = Ship()
- um = UnitManager(sm)
- bm = BulletManager()
- while True:
- clock.tick(30)
- bg.draw()
- beam = ship.update()
- ship.draw()
- um.update(beam, bm, ship, sm)
- bm.update(ship)
- if ship.HP <= 0:
- return ship.score
- gm.drawHUD(ship)
- cursor.draw()
- pygame.display.update()
- if not pygame.key.get_focused():
- pause()
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- end()
- elif event.type == KEYDOWN:
- ship.respondToKey(event.key, True)
- if event.key == K_ESCAPE:
- pause()
- elif event.type == KEYUP:
- ship.respondToKey(event.key, False)
- elif event.type == MOUSEBUTTONDOWN:
- ship.respondToMouse(True)
- sm.play("laserstart")
- elif event.type == MOUSEBUTTONUP:
- ship.respondToMouse(False)
- sm.play("laserstop")
- def main():
- cursor = Cursor()
- gm = GUIManager()
- sm = SoundManager()
- hsm = HighScoreManager()
- sm.loadSong("menu")
- while True:
- gm.menu(cursor, sm, hsm)
- sm.stopSong(1000)
- sm.loadSong("battle")
- score = play(gm, sm, cursor)
- sm.stopSong(2000)
- sm.loadSong("menu")
- if hsm.checkScore(score):
- hsm.addScore(gm.newHighScore(), score)
- else:
- gm.lose()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement