1
Fork 0

Compare commits

..

No commits in common. "master" and "V1.4" have entirely different histories.
master ... V1.4

23 changed files with 325 additions and 523 deletions

56
.gitignore vendored
View file

@ -1,57 +1 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/

85
GUI.py
View file

@ -1,26 +1,21 @@
from tkinter import *
from tkinter.ttk import *
import logging
from os import system
import game
from assets import Textures
PADDING_TITLE = 15
PADDING_BUTTON = 9
VERSION = {"ID":"2.2", "DATE": "19/05/15"}
class Main_Window:
def __init__(self, master):
self.master = master
self.master.title("ATTACK ON BLOCKS")
self.master.title("SPACE INVADERS")
self.title = Label(self.master)
self.title.config(text="ATTACK ON BLOCKS!",font=("Courier New", 37))
self.title.pack(side="top", padx=PADDING_TITLE, pady=PADDING_TITLE/2)
self.version_info = Label(self.master)
self.version_info.config(text="Version {ID} tagged {DATE}".format(**VERSION), font=("Courier New", 13))
self.version_info.pack(side="top", padx=0, pady=PADDING_BUTTON/2)
self.title.config(text="SPACE INVADERS!",font=("Courier New", 37))
self.title.pack(side="top", padx=PADDING_BUTTON, pady=PADDING_TITLE/2)
self.start_button = Button(self.master, style="Menu.TButton")
self.start_button.config(text="Play Game")
@ -32,24 +27,13 @@ class Main_Window:
self.options_button.pack(fill=BOTH, ipadx=PADDING_BUTTON/2, ipady=PADDING_BUTTON/2, padx=PADDING_BUTTON, pady=PADDING_BUTTON)
self.options_button.bind('<Button-1>', self.show_options)
self.help_button = Button(self.master, style="About.TButton")
self.help_button.config(text="About / Help")
self.help_button.pack(fill=BOTH, ipadx=PADDING_BUTTON/4, ipady=PADDING_BUTTON/4, padx=PADDING_BUTTON, pady=PADDING_BUTTON)
self.help_button.bind('<Button-1>', self.show_info)
self.exit_button = Button(self.master, style="Quit.TButton")
self.exit_button.config(text="Quit Game")
self.exit_button.pack(ipadx=PADDING_BUTTON/3, ipady=PADDING_BUTTON, padx=PADDING_BUTTON, pady=PADDING_BUTTON)
self.exit_button.bind('<Button-1>', self.close)
self.about_info = Label(self.master)
self.about_info.config(text="Game Created by TheOrangeOne!", font=("Courier New", 9))
self.about_info.bind("<Button-1>", self.show_site)
self.about_info.pack(side="top", padx=0, pady=PADDING_BUTTON/2)
Style().configure("Menu.TButton", font=("Lucida", 21))
Style().configure("About.TButton", font=("Lucida", 17))
Style().configure("Quit.TButton", font=("Lucida", 13))
Style().configure("Menu.TButton", font=("Lucida", 25))
Style().configure("Quit.TButton", font=("Lucida", 15))
self.options_window = Options_Window()
logging.debug("GUI Generated.")
@ -63,77 +47,54 @@ class Main_Window:
self.new_window = Toplevel(self.master)
self.options_window.display(self.new_window)
def show_info(self, event):
logging.info("Loading About Page...")
system("start https://bitbucket.org/theorangeone/attack-on-blocks/wiki/Home")
def close(self, event):
logging.critical("Closing Main Window.")
self.master.destroy()
def show_site(self, event):
logging.info("Loading Website")
system("start http://theorangeone.net")
class Options_Window:
def __init__(self):
self.textures_object = Textures()
self.textures_object = Textures()
self.options = {
"Difficulty": 120,
"Textures": self.textures_object,
"Sounds": True
"Textures": self.textures_object
}
def display(self, master):
self.master = master
self.master.title("ATTACK ON BLOCKS - Options")
self.master.title("SPACE INVADERS - Options")
self.title = Label(self.master)
self.title.config(text="OPTIONS",font=("Courier New", 37))
self.title.pack(side="top", padx=PADDING_TITLE, pady=PADDING_TITLE/2)
self.difficulty_title = Label(self.master)
self.difficulty_title.config(text="Current Difficulty: {}".format(self.options["Difficulty"]), font=("Courier New", 13))
self.difficulty_title.config(text="Current Difficulty: {}".format(self.options["Difficulty"]), font=("Courier New", 19))
self.difficulty_title.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
self.difficulty_scale = Scale(self.master, from_=5, to=500, orient="horizontal", command=self.update_difficulty, length=350)
self.difficulty_scale = Scale(self.master, from_=30, to=300, orient="horizontal", command=self.update_difficulty, length=400)
self.difficulty_scale.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
self.difficulty_scale["value"] = self.options["Difficulty"]
self.difficulty_reset_button = Button(self.master, style="Minor.TButton")
self.difficulty_reset_button.config(text="Reset Difficulty")
self.difficulty_reset_button.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
self.difficulty_reset_button.bind('<Button-1>', self.reset_difficulty)
Frame(self.master,height=23).pack()
self.texture_title = Label(self.master)
self.texture_title.config(text="Select Texture Pack", font=("Courier New", 13))
self.texture_title.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
self.texture_select = Listbox(master)
self.texture_select.delete(0, END)
self.texture_title.config(text="Select Texture Pack", font=("Courier New", 19))
self.texture_title.pack(side="bottom", ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
self.texture_select = ListBox(master)
for directory in self.options["Textures"].list_packs():
if directory == "": continue
self.texture_select.insert(END, directory)
self.texture_select.insert(END, directory)
self.texture_select.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
Frame(self.master,height=23).pack()
self.using_sounds = IntVar()
self.using_sounds.set(self.options["Sounds"])
self.sounds_check = Checkbutton(self.master, text="Use Sound Effects", command=self.update_sounds, variable=self.using_sounds)
self.sounds_check.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
self.exit_button = Button(self.master, style="Minor.TButton")
self.exit_button.config(text="Reset")
self.exit_button.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
self.exit_button.bind('<Button-1>', self.reset_difficulty)
Style().configure("Minor.TButton", font=("Lucida", 10))
self.master.protocol('WM_DELETE_WINDOW', self.close)
self.dlgWin.protocol('WM_DELETE_WINDOW', self.close)
logging.info("Options menu created.")
def close(self):
self.options["Textures"].pack = self.texture_select.get(ACTIVE) if self.texture_select.get(ACTIVE) != "" else "default" # Because it has no changed event
logging.info("Selected Texture Pack: {}".format(self.options["Textures"].pack))
self.options["Textures"].pack = self.texture_select.get(ACTIVE) # Because it has no changed event
self.master.destroy()
def update_sounds(self):
self.options["Sounds"] = self.using_sounds.get()
def update_difficulty(self, event):
self.options["Difficulty"] = int(self.difficulty_scale.get())
self.difficulty_title["text"] = "Current Difficulty: {}".format(self.options["Difficulty"])

22
LICENSE
View file

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Jake Howard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,3 +1,3 @@
print("Starting Attack on Blocks...\nLoading Main Window...")
print("Starting Space Invaders...\nLoading Main Window...")
import GUI
GUI.display()

View file

@ -1,26 +1,24 @@
# Attack on Blocks #
This take on space invaders was written for my IT BTEC course, Unit 22 Games Development at college. This version, written in python, includes more advanced features such as resource packs.
### More Information ###
For more information, check out the [Wiki](//bitbucket.org/TheOrangeOne/attack-on-blocks/wiki) page.
### Requirements ###
* Python 3
* Pygame
* TKinter
The game is only playable on windows, due to the GUI library only being available on windows. However a cross platform, lightweight version may be made in the future.
### Playing the game ###
* Clone the repository, or visit the downloads page
* Install the required libraries (See Above)
* Run 'Play The Game.py'
### Core Contributors ###
* Jake Howard
* Furhan Bhatti (Well not really)
# Space Invaders #
This take on space invaders was written for my IT BTEC course, Unit 21 Games Development at college. This version, written in python, includes more advanced features such as resource packs.
### Requirements ###
* Python
* Pygame
* TKinter
The game is only playable on windows, due to the GUI library only being available on windows. However a cross platform, lightweight version may be made in the future.
### Playing the game ###
* Clone the repository
* Install the required libraries (See Above)
* Run 'Play The Game.py'
### Core Contributors ###
* Jake Howard
* Furhan Bhatti
# Note #
At the moment, the game WILL NOT play at all, as it is still in development, all the time this message is here, the program will not run!

BIN
Thumbs.db Normal file

Binary file not shown.

102
assets.py
View file

@ -3,81 +3,65 @@ from collections import namedtuple
from random import randint
class Textures():
def __init__(self):
self.images = {
"PLAYER":"player",
"BULLET":"bullet",
"TARGETS":[],
"SHOOTER":"shooter",
"TARGET_BULLET":"bullet_target",
"POWERUP": "powerup"
}
self.path=os.path.dirname(os.path.realpath(__file__)) + "\\resources\\texture_packs\\"
self.pack = "default"
def __init__(self):
self.images = {
"PLAYER":"player.png",
"BULLET":"bullet.png",
"TARGETS":[],
"SHOOTER":"shooter.png",
"TARGET_BULLET":"target_bullet.png"
}
self.path=os.path.dirname(os.path.realpath(__file__)) + "\\resources\\texture_packs\\"
self.pack = "default"
def load_texture_pack(self, pack_name):
if os.path.exists(self.path + pack_name):
self.images["TARGETS"] = []
def load_texture_pack(self, packName):
if os.path.exists(self.path + packName):
self.images["TARGETS"] = []
targets = glob.glob(self.path+pack_name+"\\target*.png")
logging.debug("Found {0} target files.".format(len(targets)))
for file in targets:
filename = file.split("\\")[-1].replace(".png", "")
self.images["TARGETS"].append(filename)
targets = glob.glob(self.path+packName+"\\target*.png")
logging.debug("Found {0} target files.".format(len(targets)))
for file in targets:
fileName = file.split("\\")[-1]
self.images["TARGETS"].append(filename)
self.pack = pack_name
else: logging.warn("Cannot find texture pack '{}'".format(ppack_name))
self.pack = packName
else: logging.warn("Cannot find texture pack '{}'".format(packName))
def get_texture(self, objectName):
filename = self.path + self.pack + "\\{0}.png".format(self.images[objectName.upper()])
return pygame.image.load(filename)
def get_texture(self, objectName):
filename = self.path + self.pack + "\\{0}.png".format(self.images[objectName.upper()])
return pygame.image.load(filename)
def get_target_texture(self, ID=False):
if not ID:
index = randint(0,len(self.images["TARGETS"])-1) if len(self.images["TARGETS"]) >=1 else 0
filename = self.path + self.pack + "\\{}.png".format(self.images["TARGETS"][index])
return [pygame.image.load(filename), index]
else:
filename = self.path + self.pack + "\\target{}.png".format(int(ID))
return [pygame.image.load(filename), ID]
def get_target_texture(self):
filename = self.path + self.pack + "\\{}.png".format(self.images["TARGETS"][randint(0,len(self.images["TARGETS"]))])
return pygame.image.load(filename)
def list_packs(self):
return [x[0].replace(self.path, "") for x in os.walk(self.path)]
def list_packs(self):
return [x[0] for x in os.walk(self.path)]
Level_Template = namedtuple('Level_Template', ("rows", "padding", "firebacks", "powerups"))
Levels = [
Level_Template(2, 20, 0, 0),
Level_Template(3, 15, 1, 0),
Level_Template(4, 15, 3, 1),
Level_Template(3, 7, 2, 2),
Level_Template(5, 15, 2, 1),
Level_Template(2, 20, 100, 2), #All the enemies!
Level_Template(3, 15, 2, 1),
Level_Template(3, 7, 2, 4),
Level_Template(4, 15, 4, 3),
Level_Template(5, 35, 4, 6),
Level_Template(2, 20, 0, 0),
Level_Template(3, 15, 2, 1),
Level_Template(4, 25, 7, 1)
]
def generate_random_level():
logging.info("Generating a random level!")
rows = randint(1, 12)
padding = randint(5, 30)
firebacks = randint(0, 15)
powerups = randint(0, 15)
return Level_Template(rows, padding, firebacks, powerups)
logging.info("Generating a random level!")
rows = randint(0, 12)
padding = randint(0, 30)
firebacks = randint(0, 15)
powerups = randint(0, 15)
return Level_Template(rows, padding, firebacks, powerups)
Sounds = {}
def init_sounds():
music_files = ["main.ogg", "OP.ogg", "shot.ogg"]
for file in music_files:
path = os.path.dirname(os.path.realpath(__file__)) + "\\resources\\sounds\\" + file
if file == "main.ogg":
mixer = pygame.mixer.music
mixer.load(path)
else: mixer = pygame.mixer.Sound(path)
mixer.set_volume(1.0)
Sounds[file.replace(".ogg", "")] = mixer
music_files = ["main.mp3", "fire.mp3"]
for file in music_files:
path = os.path.dirname(os.path.realpath(__file__)) + "\\resources\\sounds\\" + file
if file == "main.mp3": mixer = pygame.mixer.music.load(path)
else: mixer = pygame.mixer.Sound(file)
Sounds.update(file.split(".")[0], mixer)

View file

@ -2,10 +2,10 @@ import pygame
class Bullet(pygame.sprite.Sprite):
def __init__(self, parent, textures, bigger):
def __init__(self, parent):
super().__init__()
self.width = 6 * (1+int(bigger))
self.height = 14 * (1+int(bigger))
self.width = 4
self.height = 10
self.image = pygame.transform.scale(textures.get_texture("BULLET"), (self.width, self.height))
self.rect = self.image.get_rect()
self.rect.x = parent.rect.x + parent.width/2 - self.width/2

18
eggs.py
View file

@ -2,12 +2,12 @@ import pygame, logging, urllib.request, io
from time import sleep
def r9k(window):
logging.warn("Look, you found a pepe!")
raw_image = urllib.request.urlopen("http://img.ifcdn.com/images/620f230fad2806fe5305fac45dd673b8fc005b98c1e3b8584abc9c439b050950_1.jpg").read()
image_file = io.BytesIO(raw_image)
image = pygame.transform.scale(pygame.image.load(image_file), window.get_size())
window.blit(image, (0,0))
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("A rare pepe has been found. Alert R9k", True, (0,0,0)), (window.get_width()/2-175, window.get_height()/2))
pygame.display.update()
sleep(9)
logging.warn("Look, you found a pepe!")
raw_image = urllib.request.urlopen("https://38.media.tumblr.com/avatar_2cd47bc1ad07_128.png").read()
image_file = io.BytesIO(raw_image)
image = pygame.transform.scale(pygame.image.load(image_file), window.get_size())
window.blit(image, (0,0))
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("A rare pepe has been found. Alert R9k", True, (0,0,0)), (window.get_width()/2-175, window.get_height()/2))
pygame.display.update()
sleep(9)

419
game.py
View file

@ -1,210 +1,209 @@
import pygame, logging
from time import time, sleep
from random import randint
import eggs
from bullet import Bullet
from player import Shooter
from assets import *
from target import Target, generate_targets
POWERUPS = ["SPEED", "DOUBLE", "LIVES", "SCORE", "BIGGER"]
PLAYING_GAME = False
WINDOW_SIZE = (680, 790)
HUD_COLOUR = (255,168,72)
def update_score(window, score, colour=HUD_COLOUR):
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("Score: {}".format(int(score)), True, colour), (25, WINDOW_SIZE[1] - 30))
def update_level(window, level, colour=HUD_COLOUR):
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("Level: {}".format(int(level)+1), True, colour), (8.5*WINDOW_SIZE[0]/10, WINDOW_SIZE[1] - 30))
def update_lives(window, lives, colour=HUD_COLOUR):
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("Lives Remaining: {}".format(int(lives)), True, colour if lives != 1 else (255,50,0)), (3.8*WINDOW_SIZE[0]/10, WINDOW_SIZE[1] - 30))
def initialise(menu, options):
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
window = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("Attack on Blocks")
exit_code = play(window, options) # Run main game loop
for key, value in Sounds.items():
value.fadeout(500)
logging.debug("Game Exited with code {}".format(exit_code))
if exit_code != "QUIT": sleep(1)
pygame.quit()
menu.deiconify()
return exit_code
def play(window, options):
window_rect = window.get_rect()
options["Textures"].load_texture_pack(options["Textures"].pack)
player = Shooter(window=window, texture=options["Textures"])
player.set_position(WINDOW_SIZE[0]/2, WINDOW_SIZE[1]*0.90)
player.options = options
player_group = pygame.sprite.Group()
player_group.add(player)
target_group = generate_targets(player, WINDOW_SIZE, Levels)
bullet_group = pygame.sprite.Group()
clock = pygame.time.Clock()
FPS = player.options["Difficulty"]
timeouts = {
"Target Movement":[FPS*0.65,FPS*0.65],
"Powerup":[FPS*15, FPS*15]
}
init_sounds()
if options["Sounds"]: Sounds["main"].play(loops=-1) #Start background music
logging.info("Game Started.")
PLAYING_GAME = True
while PLAYING_GAME:
window.fill((0,0,0))
fired = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
logging.critical("Exiting Game...")
PLAYING_GAME = False
return "QUIT"
if event.type == pygame.KEYDOWN and event.key in [pygame.K_SPACE, pygame.K_w, pygame.K_UP] and not fired:
if player.options["Sounds"]: Sounds["shot"].play()
temp = Bullet(player, player.options["Textures"], player.powerup == "BIGGER")
bullet_group.add(temp)
if player.powerup == "DOUBLE":
temp = Bullet(player, player.options["Textures"], player.powerup == "BIGGER")
temp.rect.y += 20
bullet_group.add(temp)
fired = True
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
if player.powerup == "SPEED": player.move(player.speed * 1.5)
else: player.move(player.speed)
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
if player.powerup == "SPEED": player.move(-player.speed*1.5)
else: player.move(-player.speed)
if keys[pygame.K_KP4] and keys[pygame.K_KP5] and keys[pygame.K_KP6] and player.OP:
temp = Bullet(player, player.options["Textures"], False)
bullet_group.add(temp)
if keys[pygame.K_r] and [pygame.K_9] and [pygame.K_k] and player.OP:
eggs.r9k(window)
if keys[pygame.K_KP4] and keys[pygame.K_KP2] and keys[pygame.K_KP0] and keys[pygame.K_o] and keys[pygame.K_p] and not player.OP:
if player.options["Sounds"]:
Sounds["main"].stop()
Sounds["OP"].play(loops=-1)
player.OP = True
player.change_colour((255,96,0))
logging.warn("OP mode engaged.")
if keys[pygame.K_KP_MINUS] and player.OP:
if player.options["Sounds"]:
Sounds["OP"].stop()
Sounds["main"].play(loops=-1)
player.OP = False
player.reset_image()
logging.warn("OP mode disabled.")
for sprite in bullet_group:
sprite.update()
if sprite.rect.y < 0 or (sprite.rect.y > player.rect.y and sprite.type == "TARGET"):
bullet_group.remove(sprite)
for bullet in bullet_group:
hit_list = pygame.sprite.spritecollide(bullet, target_group, False)
for target in hit_list:
if bullet.type != "TARGET":
target.lives -= 1
if target.lives <= 0:
target_group.remove(target)
player.score += 1
bullet_group.remove(bullet)
if target.lives <= 0 and target.type == "POWERUP":
player.powerup = POWERUPS[randint(0,len(POWERUPS)-1)]
logging.info("Powerup set to {}".format(player.powerup))
hit_list = pygame.sprite.spritecollide(bullet, player_group, False)
for player in hit_list:
if bullet.type == "TARGET":
bullet_group.remove(bullet)
logging.info("You were hit by a target's bullet!")
if not player.OP: player.lives -= 1
if player.lives <= 0:
return "LIVES"
if timeouts["Target Movement"][0] <=0:
drop_targets = False
for target in target_group:
target.move()
if target.rect.x <= 30 or target.rect.x >=WINDOW_SIZE[0] - target.width/2 - 30:
drop_targets = True
if target.rect.y >= player.rect.y + target.height/2:
PLAYING_GAME = False
return "PLAYER COLLISION"
if drop_targets:
logging.debug("The targets are moving down a level!")
for target in target_group:
target.drop()
timeouts["Target Movement"][0] = timeouts["Target Movement"][1]
if timeouts["Powerup"][0] <= 0:
timeouts["Powerup"][0] = timeouts["Powerup"][1]
if player.powerup == "SCORE":
player.score += 10
player.powerup = ""
elif player.powerup == "LIVES":
player.lives += 1
player.powerup = ""
for target in target_group:
if target.type == "SHOOTER":
if randint(0,600) > 1: continue
temp = Bullet(target, player.options["Textures"], False)
temp.type="TARGET"
temp.image = pygame.transform.scale(player.options["Textures"].get_texture("TARGET_BULLET"), (temp.width, temp.height))
x,y = temp.rect.x, temp.rect.y
temp.rect = temp.image.get_rect()
temp.set_position(x,y)
temp.speed = -1 #So it shoots down!
bullet_group.add(temp)
if len(target_group) == 0: #If all current players are gone.
player.level += 1
Sounds["main"].set_volume(0.5)
target_group = generate_targets(player, WINDOW_SIZE, Levels)
target_group.draw(window)
bullet_group.empty()
pygame.display.update()
sleep(0.75)
Sounds["main"].set_volume(1.0)
update_score(window, player.score)
update_level(window, player.level)
update_lives(window, player.lives)
target_group.draw(window)
bullet_group.draw(window)
player_group.draw(window)
for key, value in timeouts.items():
value[0] -= 1
pygame.display.update()
clock.tick(FPS)
import pygame, logging
from time import time, sleep
from random import randint
import eggs
from bullet import Bullet
from player import Shooter
from assets import *
from target import Target
PLAYING_GAME = False
WINDOW_SIZE = (640,480)
FPS = 120
def update_score(window, score):
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("Score: {}".format(int(score)), True, (255,0,0)), (25, WINDOW_SIZE[1] - 30))
def update_level(window, level):
font = pygame.font.SysFont(None, 25, bold=True)
window.blit(font.render("Level: {}".format(int(level)+1), True, (0,255,0)), (8.7*WINDOW_SIZE[0]/10, WINDOW_SIZE[1] - 30))
def update_lives(window, lives):
font = pygame.font.SysFont(None, 30, bold=False)
window.blit(font.render("Lives Remaining: {}".format(int(lives)), True, (0,0,255)), (4.5*WINDOW_SIZE[0]/10, WINDOW_SIZE[1] - 30))
def initialise(menu, options):
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
init_sounds()
options["Difficulty"] = FPS
window = pygame.display.set_mode(WINDOW_SIZE)
exit_code = play(window, options) # Run main game loop
for key, value in Sounds.items():
value.stop()
logging.debug("Game Exited with code {}".format(exit_code))
if exit_code != "QUIT": sleep(1)
pygame.quit()
menu.deiconify()
return exit_code
def generate_targets(player):
sprite_list = []
group = pygame.sprite.Group()
if player.level > len(Levels)-1:
level = generate_random_level()
else: level = Levels[player.level]
logging.debug("Generating Level: " + str(level))
for i in range(level.rows):
i *= level.padding + 8
for j in range(40, WINDOW_SIZE[0] - 40, level.padding + 8):
temp = Target(x=j,y=i, player.options["Textures"])
sprite_list.append(temp)
del temp
for i in range(level.firebacks):
changed = False
while not changed:
index = randint(0, len(sprite_list)-1)
if sprite_list[index].type != "SHOOTER":
sprite_list[index].type = "SHOOTER"
sprite_list[index].image = pygame.transform.scale(player.options["Textures"].get_texture("SHOOTER"), (sprite_list[index].width, sprite_list[index].height))
x,y = sprite_list[index].rect.x, sprite_list[index].rect.y
sprite_list[index].rect = sprite_list[index].image.get_rect()
sprite_list[index].set_position(x,y, center=False) #Already Centered!
changed = True
for sprite in sprite_list: #Because sprite groups dont support indexing!
group.add(sprite)
return group
def play(window, options):
window_rect = window.get_rect()
player = Shooter(window=window)
player.set_position(WINDOW_SIZE[0]/2, WINDOW_SIZE[1]*0.83)
player.options = options
player_group = pygame.sprite.Group()
player_group.add(player)
target_group = generate_targets(player)
bullet_group = pygame.sprite.Group()
clock = pygame.time.Clock()
timeouts = {
"Target Movement":[FPS*0.5,FPS*0.5],
"Powerup":[FPS*100, FPS*100]
}
Sounds["main"].play(loops=-1) #Start background music
logging.info("Game Started.")
PLAYING_GAME = True
while PLAYING_GAME:
window.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
logging.critical("Exiting Game...")
PLAYING_GAME = False
return "QUIT"
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
temp = Bullet(player)
bullet_group.add(temp)
if event.type == pygame.KEYDOWN and event.key == pygame.K_KP_PLUS:
player.OP = not player.OP
logging.info("Player is now OP!")
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
if player.powerup == "SPEED": player.move(player.speed * 1.5)
else: player.move(player.speed)
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
if player.powerup == "SPEED": player.move(-player.speed*1.5)
else: player.move(-player.speed)
if keys[pygame.K_KP4] and keys[pygame.K_KP5] and keys[pygame.K_KP6] and player.OP:
temp = Bullet(player)
bullet_group.add(temp)
if keys[pygame.K_r] and [pygame.K_9] and [pygame.K_k] and player.OP:
eggs.r9k(window)
for sprite in bullet_group:
sprite.update()
if sprite.rect.y < 0 or (sprite.rect.y > player.rect.y and sprite.type == "TARGET"):
bullet_group.remove(sprite)
for bullet in bullet_group:
hit_list = pygame.sprite.spritecollide(bullet, target_group, False)
for target in hit_list:
if bullet.type != "TARGET":
target_group.remove(target)
bullet_group.remove(bullet)
player.score += 1
hit_list = pygame.sprite.spritecollide(bullet, player_group, False)
for player in hit_list:
if bullet.type == "TARGET":
bullet_group.remove(bullet)
logging.info("You were hit by a target's bullet!")
player.lives -= 1
if player.lives <= 0:
return "LIVES"
if timeouts["Target Movement"][0] <=0:
drop_targets = False
for target in target_group:
target.move()
if target.rect.x <= 30 or target.rect.x >=WINDOW_SIZE[0] - 30:
drop_targets = True
if target.rect.y >= player.rect.y + 20:
PLAYING_GAME = False
return "PLAYER COLLISION"
if drop_targets:
logging.debug("The targets are moving down a level!")
for target in target_group:
target.drop()
timeouts["Target Movement"][0] = timeouts["Target Movement"][1]
for target in target_group:
if target.type == "SHOOTER":
if randint(0,375) > 1: continue
temp = Bullet(target)
temp.type="TARGET"
temp.image = pygame.transform.scale(textures.get_texture("TARGET_BULLET"), (temp.width, temp.height))
x,y = temp.rect.x, temp.rect.y
temp.rect = temp.image.get_rect()
temp.set_position(x,y)
temp.speed = -3 #So it shoots down!
bullet_group.add(temp)
if len(target_group) == 0: #If all current players are gone.
player.level += 1
target_group = generate_targets(player)
player.change_colour(player.colours[player.level])
target_group.draw()
pygame.display.update()
sleep(1.5)
if player.OP:
player.change_colour((255,96,0)) #override colour change if changed before
update_score(window, player.score)
update_level(window, player.level)
update_lives(window, player.lives)
bullet_group.draw(window)
target_group.draw(window)
player_group.draw(window)
for key, value in timeouts.items():
value[0] -= 1
pygame.display.update()
clock.tick(FPS)

View file

@ -2,13 +2,12 @@ import pygame
class Shooter(pygame.sprite.Sprite):
def __init__(self, window, texture, colour=(255,255,255), width=55, height=25):
def __init__(self, window, texture, colour=(255,255,255), width=45, height=20):
super().__init__()
self.width = width
self.height = height
self.colour = colour
self.texture = texture
self.image = pygame.transform.scale(self.texture.get_texture("PLAYER"), (self.width, self.height))
self.image = pygame.transform.scale(textures.get_texture("PLAYER"), (self.width, self.height))
self.rect = self.image.get_rect()
self.speed = 3
self.window_rect = window.get_rect()
@ -17,14 +16,15 @@ class Shooter(pygame.sprite.Sprite):
self.OP = False
self.level = 0
self.lives = 3
self.powerup = ""
self.powerup = ""
self.colours = [(255,0,0), (255,255,0), (0,255,0)]
def set_position(self,x,y):
self.rect.x, self.rect.y = x, y
self.rect.x, self.rect.y = x,y
def move(self, value):
self.rect.x += value
self.rect.clamp_ip(self.window_rect)
self.rect.x += value
self.rect.clamp_ip(self.window_rect)
def update(self):
self.image.fill(self.colour)
@ -34,10 +34,4 @@ class Shooter(pygame.sprite.Sprite):
x,y = self.rect.x, self.rect.y
self.image.fill(colour)
self.rect = self.image.get_rect()
self.set_position(x,y)
def reset_image(self):
x,y = self.rect.x, self.rect.y
self.image = pygame.transform.scale(self.texture.get_texture("PLAYER"), (self.width, self.height))
self.rect = self.image.get_rect()
self.set_position(x,y)
self.set_position(x,y)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View file

@ -1,27 +1,23 @@
import pygame, logging
import pygame
from random import randint
from game import generate_random_level
class Target(pygame.sprite.Sprite):
def __init__(self, x, y, textures, color=(30,0,150), width=23, height=23):
def __init__(self, x, y, textures, color=(30,0,150), width=16, height=16):
super().__init__()
self.width = width
self.height = height
self.textures = textures
self.default_texture = textures.get_target_texture()
self.image = pygame.transform.scale(self.default_texture[0], (self.width, self.height))
self.image = pygame.transform.scale(textures.get_target_texture(), (self.width, self.height))
self.rect = self.image.get_rect()
self.speed = 5
self.speed = 7
self.rect.x, self.rect.y = (x+(self.width/2)),(y+(self.width/2)) # centres co-ordinates
self.type = "NORMAL"
self.lives = 1
def move(self):
self.rect.x += self.speed
def drop(self):
self.rect.y += 13
self.rect.y += 17
self.speed *= -1
def set_position(self, x, y, center=False):
@ -30,56 +26,4 @@ class Target(pygame.sprite.Sprite):
else:
self.rect.x, self.rect.y = x, y
def generate_targets(player, window_size, Levels):
sprite_list = []
group = pygame.sprite.Group()
if player.level > len(Levels)-1:
level = generate_random_level()
else: level = Levels[player.level]
logging.debug("Generating Level: " + str(level))
for i in range(level.rows):
i *= level.padding + 8
for j in range(75, window_size[0] - 75, level.padding + 10):
temp = Target(x=j,y=i, textures=player.options["Textures"])
sprite_list.append(temp)
del temp
if len(sprite_list) < level.firebacks:
firebacks = len(sprite_list)
else: firebacks = level.firebacks
for i in range(firebacks):
loop = 0
changed = False
while not changed:
if loop == firebacks: changed = True
index = randint(0, len(sprite_list)-1) if (len(sprite_list) - 1 != 0) else 0
if sprite_list[index].type != "SHOOTER":
sprite_list[index].type = "SHOOTER"
sprite_list[index].lives = 2
sprite_list[index].image = pygame.transform.scale(player.options["Textures"].get_texture("SHOOTER"), (sprite_list[index].width, sprite_list[index].height))
x,y = sprite_list[index].rect.x, sprite_list[index].rect.y
sprite_list[index].rect = sprite_list[index].image.get_rect()
sprite_list[index].set_position(x,y, center=False) #Already Centered!
changed = True
loop += 1
if len(sprite_list) < level.powerups:
powerups = len(sprite_list)
else: powerups = level.powerups
for i in range(powerups):
changed = False
while not changed:
index = randint(0, len(sprite_list)-1) if (len(sprite_list) - 1 != 0) else 0
if sprite_list[index].type != "POWERUP" and sprite_list[index].type != "SHOOTER" :
sprite_list[index].type = "POWERUP"
sprite_list[index].image = pygame.transform.scale(player.options["Textures"].get_texture("POWERUP"), (sprite_list[index].width, sprite_list[index].height))
x,y = sprite_list[index].rect.x, sprite_list[index].rect.y
sprite_list[index].rect = sprite_list[index].image.get_rect()
sprite_list[index].set_position(x,y, center=False) #Already Centered!
changed = True
for sprite in sprite_list: #Because sprite groups dont support indexing!
group.add(sprite)
return group