Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
import pygame, time, sys, random, math
from pygame.locals import *
pygame.font.init()
#This is a class that both aliens and the player will be derived from
class Entity:
def __init__(self, name, health, sprite, bulletsprite, width, height):
self.name = name
self.health = health
self.sprite = sprite
self.bulletsprite = bulletsprite
self.width = width
self.height = height
#The Class is now split into subclasses of Player and Alien. This allows for examples of both to be created and have different attributes.
class Player(Entity):
def HighScore(self, highscore):
self.highscore = highscore
def Earnings(self, earnings):
self.earnings = earnings
class Alien(Entity):
def Points(self,value):
self.value = value
def Movement(self, velocity):
self.velocity = velocity
def Location(self, x, y):
self.x = x
self.y = y
def Bullet(self, invadernotshot, invadershotstillgoing, invadershotchanceincrease, bullet_x, bullet_y):
self.invadernotshot = invadernotshot
self.invadershotstillgoing = invadershotstillgoing
self.invadershotchanceincrease = invadershotchanceincrease
self.invadershotchance = random.randint(0, 4000-self.invadershotchanceincrease*10)
self.bullet_x = bullet_x
self.bullet_y = bullet_y
#This function creates multiple invader objects
def InvaderFactory():
SpaceInvadi = []
InvaderHeight = 5
InvaderWidth = 5
for i in range(InvaderHeight):
Row = []
for j in range(InvaderWidth):
BInvaderSprite = pygame.image.load("BInvader.png")
BInvaderBulletSprite = pygame.image.load("InvaderBullet.jpg")
BInvader = Alien("BInvader{0}".format(j), 1, BInvaderSprite, BInvaderBulletSprite, 22, 19)
BInvader.Points(100)
BInvader.Movement(2)
BInvader.Location(1, 1)
InvaderShotChanceIncrease = 1
BInvader.Bullet(True, False, 1, BInvader.x + 10, BInvader.y)
Row.append(BInvader)
SpaceInvadi.append(Row)
for i in range(5):
for j in range(5):
SpaceInvadi[i][j].x = 50 + (BInvader.width*j) + (20*j)
SpaceInvadi[i][j].y = 50 + (BInvader.height*i) + (20*i)
return SpaceInvadi
def StartGame(InputtedName, WindowH, WindowW, Clock, Window, MyFont, NewPlayer, SpaceInvadi, CurrentLevel):
pygame.display.set_caption("Space Invaders")
#Defining coordinates before the main game loop
Ship_x = (WindowW/2)
Ship_y = (9/10*WindowH)
PlayerBullet_y = Ship_y + 5
PlayerBullet_x = Ship_x + 28
#Set to false as default to prevent called before assignement error (also should defaultly not be true).
PlayerBulletStart = False
CurrentInvaderBreakTime = 1
InGameLoop = True
InvincibleFrames = 0
#Calls the main game loop
GameLoop(WindowH,
WindowW,
Clock,
Window,
MyFont,
NewPlayer,
Ship_y,
Ship_x,
PlayerBullet_y,
PlayerBullet_x,
PlayerBulletStart,
CurrentInvaderBreakTime,
InputtedName,
InGameLoop,
SpaceInvadi,
CurrentLevel,
InvincibleFrames)
def GameLoop(WindowH,
WindowW,
Clock,
Window,
MyFont,
NewPlayer,
Ship_y,
Ship_x,
PlayerBullet_y,
PlayerBullet_x,
PlayerBulletStart,
CurrentInvaderBreakTime,
InputtedName,
InGameLoop,
SpaceInvadi,
CurrentLevel,
InvincibleFrames):
while InGameLoop:
#Checks which invaders are alive and moves those invaders across the screen accordingly
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
if SpaceInvadi[i][j].health == 1:
SpaceInvadi[i][j].x += SpaceInvadi[i][j].velocity
SpaceInvadi[i][j].invadershotchance = random.randint(0, 4000-SpaceInvadi[i][j].invadershotchanceincrease*100)
else:
SpaceInvadi[i][j].x = -2000
SpaceInvadi[i][j].y = -2000
#When invaders get to the left hand side of the screen
CurrentFirstAliveColumn = 0
CheckForDeadColumnsLEFT = True
while CheckForDeadColumnsLEFT:
PreviousFirstAliveColumn = CurrentFirstAliveColumn
DeadColumnCounter = 0
for i in range(len(SpaceInvadi)):
if SpaceInvadi[i][CurrentFirstAliveColumn].health == 0:
DeadColumnCounter += 1
if DeadColumnCounter == 5:
CurrentFirstAliveColumn += 1
if CurrentFirstAliveColumn == PreviousFirstAliveColumn:
CheckForDeadColumnsLEFT = False
for i in range(len(SpaceInvadi)):
if SpaceInvadi[i][CurrentFirstAliveColumn].x <= 0 and SpaceInvadi[i][CurrentFirstAliveColumn].x != -2000:
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
SpaceInvadi[i][j].y += 20
if SpaceInvadi[i][j].velocity < 0:
SpaceInvadi[i][j].velocity -= 0.5
SpaceInvadi[i][j].velocity *= -1
else:
SpaceInvadi[i][j].velocity += 0.5
SpaceInvadi[i][j].velocity *= -1
SpaceInvadi[i][j].invadershotchanceincrease += 1
break
#When invaders get to the right hand side of the screen
CurrentLastAliveColumn = -1
CheckForDeadColumnsRIGHT = True
while CheckForDeadColumnsRIGHT:
PreviousLastAliveColumn = CurrentLastAliveColumn
DeadColumnCounter = 0
for i in range(len(SpaceInvadi)):
if SpaceInvadi[i][CurrentLastAliveColumn].health == 0:
DeadColumnCounter += 1
if DeadColumnCounter == 5:
CurrentLastAliveColumn -= 1
if CurrentLastAliveColumn == PreviousLastAliveColumn:
CheckForDeadColumnsRIGHT = False
for i in range(len(SpaceInvadi)):
if SpaceInvadi[i][CurrentLastAliveColumn].x >= 1280 - SpaceInvadi[i][CurrentLastAliveColumn].width:
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
SpaceInvadi[i][j].y += 20
SpaceInvadi[i][j].velocity *= -1
SpaceInvadi[i][j].velocity -= 0.5
SpaceInvadi[i][j].invadershotchanceincrease += 1
break
#player hits space invader
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
if PlayerBullet_y >= SpaceInvadi[i][j].y and PlayerBullet_y <= SpaceInvadi[i][j].y + SpaceInvadi[i][j].height and PlayerBullet_x >= SpaceInvadi[i][j].x and PlayerBullet_x <= SpaceInvadi[i][j].x + SpaceInvadi[i][j].width or PlayerBullet_y >= SpaceInvadi[i][j].y and PlayerBullet_y <= SpaceInvadi[i][j].y + SpaceInvadi[i][j].height and PlayerBullet_x + 5 >= SpaceInvadi[i][j].x and PlayerBullet_x + 5 <= SpaceInvadi[i][j].x + SpaceInvadi[i][j].width:
PlayerBullet_y = Ship_y + 5
PlayerBullet_x = Ship_x + 28
SpaceInvadi[i][j].health = 0
PlayerBulletStart = False
NewPlayer.earnings += SpaceInvadi[i][j].value
if NewPlayer.earnings > NewPlayer.highscore:
NewPlayer.highscore = NewPlayer.earnings
#invader hits player
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
if SpaceInvadi[i][j].invadershotchance == 0:
SpaceInvadi[i][j].invadernotshot = False
if SpaceInvadi[i][j].invadernotshot:
SpaceInvadi[i][j].bullet_x = -50
SpaceInvadi[i][j].bullet_y = -50
elif not SpaceInvadi[i][j].invadernotshot and SpaceInvadi[i][j].invadershotstillgoing:
SpaceInvadi[i][j].bullet_y += 10
else:
SpaceInvadi[i][j].bullet_x = SpaceInvadi[i][j].x
SpaceInvadi[i][j].bullet_y = SpaceInvadi[i][j].y + 10
SpaceInvadi[i][j].invadershotstillgoing = True
if SpaceInvadi[i][j].bullet_x >= Ship_x and SpaceInvadi[i][j].bullet_x <= Ship_x + NewPlayer.width and SpaceInvadi[i][j].bullet_y + 9 >= Ship_y and SpaceInvadi[i][j].bullet_y + 9 <= Ship_y + NewPlayer.height and InvincibleFrames <= 0 or SpaceInvadi[i][j].bullet_x + 5 >= Ship_x and SpaceInvadi[i][j].bullet_x + 5 <= Ship_x + NewPlayer.width and SpaceInvadi[i][j].bullet_y + 9 >= Ship_y and SpaceInvadi[i][j].bullet_y + 9 <= Ship_y + NewPlayer.height and InvincibleFrames <= 0:
NewPlayer.health -= 1
InvincibleFrames = 60
SpaceInvadi[i][j].invadernotshot = True
SpaceInvadi[i][j].invadershotstillgoing = False
time.sleep(1)
Ship_x = (WindowW/2)
Ship_y = (9/10*WindowH)
if SpaceInvadi[i][j].x >= Ship_x and SpaceInvadi[i][j].x <= Ship_x + NewPlayer.width and SpaceInvadi[i][j].y + SpaceInvadi[i][j].height >= Ship_y and SpaceInvadi[i][j].y + SpaceInvadi[i][j].height <= Ship_y + NewPlayer.height or SpaceInvadi[i][j].x + SpaceInvadi[i][j].width >= Ship_x and SpaceInvadi[i][j].x + SpaceInvadi[i][j].width <= Ship_x + NewPlayer.width and SpaceInvadi[i][j].y + SpaceInvadi[i][j].height >= Ship_y and SpaceInvadi[i][j].y + SpaceInvadi[i][j].height <= Ship_y + NewPlayer.height:
NewPlayer.health = 0
SpaceInvadi[i][j].invadernotshot = True
SpaceInvadi[i][j].invadershotstillgoing = False
Ship_x = (WindowW/2)
Ship_y = (9/10*WindowH)
if SpaceInvadi[i][j].bullet_y >= 1280:
SpaceInvadi[i][j].bulletnotshot = True
SpaceInvadi[i][j].invadershotstillgoing = False
#For when event keys are pressed
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
try:
if event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
#print(event)
keys = pygame.key.get_pressed()
if keys[K_LEFT]:
Ship_x -= 8
if keys[K_RIGHT]:
Ship_x += 8
if keys[K_RIGHT] and PlayerBullet_x != (Ship_x + 28) and PlayerBulletStart == False:
PlayerBullet_x = Ship_x + 28
PlayerBullet_y = Ship_y + 5
if keys[K_LEFT] and PlayerBullet_x != (Ship_x + 28) and PlayerBulletStart == False:
PlayerBullet_x = Ship_x + 28
PlayerBullet_y = Ship_y + 5
if keys[K_SPACE]:
#PlayerBulletStart becomes true when the space key is pressed (or is 'down') and now the non-keydown event will occur unless
PlayerBulletStart = True
#...it gets to the top of the screen
if PlayerBullet_y < 0:
PlayerBullet_x = Ship_x + 28
PlayerBullet_y = Ship_y + 5
#it gets sent back to behind the ship before being fired again
PlayerBulletStart = False
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
except UnboundLocalError:
pass
#print("I assume no event happened here")
#PLAYER SHIP BOUNADARIES
if Ship_x < 0:
Ship_x = 0
if Ship_x + NewPlayer.width> 1280:
Ship_x = 1280 - NewPlayer.width
if PlayerBulletStart == True:
PlayerBullet_y -= 20
if InGameLoop == True:
MainGameLoopOutput(MyFont, Window, InputtedName, Clock, NewPlayer, PlayerBullet_x, PlayerBullet_y, Ship_x, Ship_y, SpaceInvadi)
#This checks if the game is over
LivingList = []
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
if SpaceInvadi[i][j].health == 0:
LivingList.append(SpaceInvadi[i][j])
if len(LivingList) == 25 or NewPlayer.health == 0:
GameFinish(WindowH,
WindowW,
Clock,
Window,
MyFont,
NewPlayer,
InputtedName,
InGameLoop,
SpaceInvadi,
CurrentLevel)
InvincibleFrames -= 1
def MainGameLoopOutput(MyFont,
Window,
InputtedName,
Clock,
NewPlayer,
PlayerBullet_x,
PlayerBullet_y,
Ship_x,
Ship_y,
SpaceInvadi):
Clock.tick(60)
#This removes all the images from the previous events.
Black = (0, 0, 0)
Window.fill(Black)
#Renders and displays name.
NameDisplay = MyFont.render(InputtedName, False, (255, 255, 255))
Window.blit(NameDisplay,(0,0))
#Makes sure that the Highscore is diplayed and that it doesn't overlap with the name.
HighScoreDisplay = MyFont.render("HighScore: "+(str(NewPlayer.highscore)), False, (255, 255, 255))
HealthDisplay = MyFont.render("Health: "+(str(NewPlayer.health)), False, (255, 255, 255))
Window.blit(HighScoreDisplay,((len(NewPlayer.name)*10) + 10,0))
Window.blit(HealthDisplay,((len(NewPlayer.name)*10) + 100 + len(str((NewPlayer.highscore)))*10,0))
#Places sprite(s) with current cooridinates.
Window.blit(NewPlayer.bulletsprite, (PlayerBullet_x, PlayerBullet_y))
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
Window.blit(SpaceInvadi[i][j].bulletsprite, (SpaceInvadi[i][j].bullet_x, SpaceInvadi[i][j].bullet_y))
Window.blit(NewPlayer.sprite, (Ship_x, Ship_y))
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
Window.blit(SpaceInvadi[i][j].sprite, (SpaceInvadi[i][j].x, SpaceInvadi[i][j].y))
#Carries out all of the above.
pygame.display.flip()
pygame.display.update()
def GameFinish(WindowH,
WindowW,
Clock,
Window,
MyFont,
NewPlayer,
InputtedName,
InGameLoop,
SpaceInvadi,
CurrentLevel):
if NewPlayer.health < 1:
print("The game is over")
with open("HighScores.txt", 'a') as f:
PlayerData = (str(NewPlayer.name) + ": " + str(NewPlayer.highscore) + '\n')
f.write(PlayerData)
pygame.quit()
sys.exit()
else:
SpaceInvadi = InvaderFactory()
CurrentLevel += 1
for i in range(len(SpaceInvadi)):
for j in range(len(SpaceInvadi[i])):
#CurrentLevel += 1
SpaceInvadi[i][j].velocity += CurrentLevel
StartGame(InputtedName, WindowH, WindowW, Clock, Window, MyFont, NewPlayer, SpaceInvadi, CurrentLevel)
def DisplayMenu(InputtedName):
WindowH = 720
WindowW = 1280
Clock = pygame.time.Clock()
Window = pygame.display.set_mode((WindowW, WindowH))
pygame.display.set_caption("Space Invaders")
MyFont = pygame.font.SysFont('Bernard MT Condensed MS', 18)
#InputtedName = "Jake"
MenuChoiceList = ["PlayGame", "HighScoreList", "Quit"]
MenuDisplay = True
MenuChoice = 0
MENU1 = pygame.image.load("MENU1.png")
MENU2 = pygame.image.load("MENU2.png")
MENU3 = pygame.image.load("MENU3.png")
while MenuDisplay:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
MenuChoice += 1
if MenuChoice > 2:
MenuChoice = 0
if event.key == pygame.K_UP:
MenuChoice -= 1
if MenuChoice < -3:
MenuChoice = -1
time.sleep(0.1)
if event.key == pygame.K_RETURN:
MenuDisplay = False
if MenuChoiceList[MenuChoice] == MenuChoiceList[0]:
Window.blit(MENU1, (0, 64))
if MenuChoiceList[MenuChoice] == MenuChoiceList[1]:
Window.blit(MENU2, (0, 64))
if MenuChoiceList[MenuChoice] == MenuChoiceList[2]:
Window.blit(MENU3, (0, 64))
pygame.display.flip()
pygame.display.update()
if MenuChoiceList[MenuChoice] == MenuChoiceList[0]:
#Creates a fresh player with no highscore and three lives
PlayerShipSprite = pygame.image.load("ship.png")
PlayerBulletSprite = pygame.image.load("pbullet.png")
NewPlayer = Player(InputtedName, 3, PlayerShipSprite, PlayerBulletSprite, 58, 38)
NewPlayer.HighScore(0)
NewPlayer.Earnings(0)
SpaceInvadi = InvaderFactory()
CurrentLevel = 0
StartGame(InputtedName, WindowH, WindowW, Clock, Window, MyFont, NewPlayer, SpaceInvadi, CurrentLevel)
elif MenuChoiceList[MenuChoice] == MenuChoiceList[1]:
DisplayHighscores(InputtedName)
pygame.quit()
else:
pygame.quit()
sys.exit()
def DisplayHighscores(InputtedName):
HighscoresDisplay = True
WindowH = 720
WindowW = 1280
Clock = pygame.time.Clock()
Window = pygame.display.set_mode((WindowW, WindowH))
pygame.display.set_caption("Space Invaders")
MyFont1 = pygame.font.SysFont('sitkasmallsitkatextbolditalicsitkasubheadingbolditalicsitkaheadingbolditalicsitkadisplaybolditalicsitkabannerbolditalic', 25)
MyFont2 = pygame.font.SysFont('Bernard MT Condensed MS', 25)
HighscoreList = []
with open("HighScores.txt", 'r') as f:
for line in f:
CurrentHighscoreList = line.split(": ")
HighscoreList.append(CurrentHighscoreList)
HighscoreList = MergeSortingHighscores(HighscoreList)
while HighscoresDisplay:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
DisplayMenu(InputtedName)
Clock.tick(60)
Window.fill((0, 0, 0))
for i in range(len(HighscoreList)):
HighScoresDisplay = MyFont2.render(HighscoreList[i][0] + ": " + HighscoreList[i][1], False, (255, 235, 255))
Window.blit(HighScoresDisplay,(10,i*50 + 30))
HighscoreText = MyFont1.render("Highscores - Press Escape to Return to Main Menu:", False, (255, 235, 255))
Window.blit(HighscoreText,(10,0))
pygame.display.flip()
pygame.display.update()
def MergeSortingHighscores(HighscoreList):
ArrayA = []
for i in range(len(HighscoreList)):
ArrayA.append(int(HighscoreList[i][1]))
OrderedHighscoreNumbers = Split(ArrayA)
FinalArray = []
for i in range(len(OrderedHighscoreNumbers)):
for j in range(len(HighscoreList)):
if int(OrderedHighscoreNumbers[i]) == int(HighscoreList[j][1]):
FinalArray.append(HighscoreList[j])
FinalArray = FinalArray[::-1]
HighscoreList = FinalArray
return HighscoreList
def Merge(ArrayA, ArrayB):
ArrayC = []
while len(ArrayA) > 0 and len(ArrayB) > 0:
if ArrayA[0] > ArrayB[0]:
ArrayC.append(ArrayB[0])
del ArrayB[0]
else:
ArrayC.append(ArrayA[0])
del ArrayA[0]
while len(ArrayA) > 0:
ArrayC.append(ArrayA[0])
del ArrayA[0]
while len(ArrayB) > 0:
ArrayC.append(ArrayB[0])
del ArrayB[0]
return ArrayC
def Split(ArrayA):
#base case
if len(ArrayA) == 1:
return ArrayA
ArrayOne = []
for i in range(int(len(ArrayA)/2)):
ArrayOne.append(ArrayA[i])
#print(ArrayOne)
ArrayTwo = []
for i in range(math.ceil(len(ArrayA)/2)):
ArrayTwo.append(ArrayA[int(i+len(ArrayOne))])
#print(ArrayTwo)
ArrayOne = Split(ArrayOne)
ArrayTwo = Split(ArrayTwo)
return Merge(ArrayOne, ArrayTwo)
InputtedName = str(input("Enter your name: "))
DisplayMenu(InputtedName)