Compare commits
79 commits
Author | SHA1 | Date | |
---|---|---|---|
bb2bc41b68 | |||
8020853ef7 | |||
cb5ece304a | |||
|
5640158e82 | ||
d91f82a889 | |||
7cf6638cb9 | |||
5b14f36770 | |||
a9d7d9c6f7 | |||
230c2db7ec | |||
8f56f52980 | |||
0bbd172764 | |||
3542fe1f74 | |||
1d216164c8 | |||
1b34829e62 | |||
73a913c43c | |||
b4a8b7db3f | |||
e7687ded09 | |||
b30a7c4ff0 | |||
f278d9b103 | |||
840e1d0b78 | |||
33df9d2ecf | |||
cce185db01 | |||
852071900e | |||
b166569da3 | |||
|
f9d90cd6ad | ||
|
ffe7e0568b | ||
b6566b20ec | |||
6ce5e0a463 | |||
746a9b3389 | |||
a6c9e8100b | |||
42d74daaf8 | |||
51f8d3e4eb | |||
7ae0ca4d3f | |||
c91a7e8359 | |||
b08cf848fa | |||
f0b36b23d5 | |||
|
038fb7a72f | ||
|
9c3cc001e8 | ||
b773930dd2 | |||
3ba98e89a6 | |||
43883a0ee2 | |||
cb82deed7b | |||
0d4580c854 | |||
cea485736e | |||
1784865b1a | |||
99ab88af18 | |||
c0f78046ef | |||
7475a69d2a | |||
11ff4cd502 | |||
0bc944c284 | |||
07ecced10b | |||
1b44b11144 | |||
f8e2e5df71 | |||
a56dd547b9 | |||
613a4b36c7 | |||
701f722f10 | |||
55f3bdae15 | |||
9fb556cc7a | |||
e50d081004 | |||
5f4d456388 | |||
e34d53fdd4 | |||
3f25eb13b4 | |||
f7de3262d9 | |||
d005fd5a52 | |||
a0c1a77ef6 | |||
9196224a32 | |||
ab74f0bcad | |||
e16ee98f04 | |||
cb4293370a | |||
|
c627f7f13b | ||
00f6fd2e5e | |||
150efceafc | |||
8d3a77a9c3 | |||
e21781e586 | |||
03de948eb4 | |||
e34503d2bc | |||
a499534f11 | |||
fdd6994ce0 | |||
9f7918ab0e |
56
.gitignore
vendored
|
@ -1 +1,57 @@
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__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/
|
||||||
|
|
79
GUI.py
|
@ -1,21 +1,26 @@
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
from tkinter.ttk import *
|
from tkinter.ttk import *
|
||||||
import logging
|
import logging
|
||||||
|
from os import system
|
||||||
import game
|
import game
|
||||||
|
from assets import Textures
|
||||||
|
|
||||||
PADDING_TITLE = 15
|
PADDING_TITLE = 15
|
||||||
PADDING_BUTTON = 9
|
PADDING_BUTTON = 9
|
||||||
|
VERSION = {"ID":"2.2", "DATE": "19/05/15"}
|
||||||
|
|
||||||
class Main_Window:
|
class Main_Window:
|
||||||
def __init__(self, master):
|
def __init__(self, master):
|
||||||
self.master = master
|
self.master = master
|
||||||
self.master.title("SPACE INVADERS")
|
self.master.title("ATTACK ON BLOCKS")
|
||||||
|
|
||||||
self.title = Label(self.master)
|
self.title = Label(self.master)
|
||||||
self.title.config(text="SPACE INVADERS!",font=("Courier New", 37))
|
self.title.config(text="ATTACK ON BLOCKS!",font=("Courier New", 37))
|
||||||
self.title.pack(side="top", padx=PADDING_BUTTON, pady=PADDING_TITLE/2)
|
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.start_button = Button(self.master, style="Menu.TButton")
|
self.start_button = Button(self.master, style="Menu.TButton")
|
||||||
self.start_button.config(text="Play Game")
|
self.start_button.config(text="Play Game")
|
||||||
|
@ -27,13 +32,24 @@ 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.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.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 = Button(self.master, style="Quit.TButton")
|
||||||
self.exit_button.config(text="Quit Game")
|
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.pack(ipadx=PADDING_BUTTON/3, ipady=PADDING_BUTTON, padx=PADDING_BUTTON, pady=PADDING_BUTTON)
|
||||||
self.exit_button.bind('<Button-1>', self.close)
|
self.exit_button.bind('<Button-1>', self.close)
|
||||||
|
|
||||||
Style().configure("Menu.TButton", font=("Lucida", 25))
|
self.about_info = Label(self.master)
|
||||||
Style().configure("Quit.TButton", font=("Lucida", 15))
|
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))
|
||||||
|
|
||||||
self.options_window = Options_Window()
|
self.options_window = Options_Window()
|
||||||
logging.debug("GUI Generated.")
|
logging.debug("GUI Generated.")
|
||||||
|
@ -47,54 +63,77 @@ class Main_Window:
|
||||||
self.new_window = Toplevel(self.master)
|
self.new_window = Toplevel(self.master)
|
||||||
self.options_window.display(self.new_window)
|
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):
|
def close(self, event):
|
||||||
logging.critical("Closing Main Window.")
|
logging.critical("Closing Main Window.")
|
||||||
self.master.destroy()
|
self.master.destroy()
|
||||||
|
|
||||||
|
def show_site(self, event):
|
||||||
|
logging.info("Loading Website")
|
||||||
|
system("start http://theorangeone.net")
|
||||||
|
|
||||||
class Options_Window:
|
class Options_Window:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.textures_object = Textures()
|
self.textures_object = Textures()
|
||||||
self.options = {
|
self.options = {
|
||||||
"Difficulty": 120,
|
"Difficulty": 120,
|
||||||
"Textures": self.textures_object
|
"Textures": self.textures_object,
|
||||||
|
"Sounds": True
|
||||||
}
|
}
|
||||||
|
|
||||||
def display(self, master):
|
def display(self, master):
|
||||||
self.master = master
|
self.master = master
|
||||||
self.master.title("SPACE INVADERS - Options")
|
self.master.title("ATTACK ON BLOCKS - Options")
|
||||||
|
|
||||||
self.title = Label(self.master)
|
self.title = Label(self.master)
|
||||||
self.title.config(text="OPTIONS",font=("Courier New", 37))
|
self.title.config(text="OPTIONS",font=("Courier New", 37))
|
||||||
self.title.pack(side="top", padx=PADDING_TITLE, pady=PADDING_TITLE/2)
|
self.title.pack(side="top", padx=PADDING_TITLE, pady=PADDING_TITLE/2)
|
||||||
|
|
||||||
self.difficulty_title = Label(self.master)
|
self.difficulty_title = Label(self.master)
|
||||||
self.difficulty_title.config(text="Current Difficulty: {}".format(self.options["Difficulty"]), font=("Courier New", 19))
|
self.difficulty_title.config(text="Current Difficulty: {}".format(self.options["Difficulty"]), font=("Courier New", 13))
|
||||||
self.difficulty_title.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
|
self.difficulty_title.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
|
||||||
self.difficulty_scale = Scale(self.master, from_=30, to=300, orient="horizontal", command=self.update_difficulty, length=400)
|
self.difficulty_scale = Scale(self.master, from_=5, to=500, orient="horizontal", command=self.update_difficulty, length=350)
|
||||||
self.difficulty_scale.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
|
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 = Label(self.master)
|
||||||
self.texture_title.config(text="Select Texture Pack", font=("Courier New", 19))
|
self.texture_title.config(text="Select Texture Pack", font=("Courier New", 13))
|
||||||
self.texture_title.pack(side="bottom", ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
|
self.texture_title.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON)
|
||||||
self.texture_select = ListBox(master)
|
self.texture_select = Listbox(master)
|
||||||
|
self.texture_select.delete(0, END)
|
||||||
for directory in self.options["Textures"].list_packs():
|
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)
|
self.texture_select.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
|
||||||
|
|
||||||
self.exit_button = Button(self.master, style="Minor.TButton")
|
Frame(self.master,height=23).pack()
|
||||||
self.exit_button.config(text="Reset")
|
|
||||||
self.exit_button.pack(ipadx=PADDING_BUTTON/3, padx=PADDING_BUTTON/3)
|
self.using_sounds = IntVar()
|
||||||
self.exit_button.bind('<Button-1>', self.reset_difficulty)
|
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)
|
||||||
|
|
||||||
Style().configure("Minor.TButton", font=("Lucida", 10))
|
Style().configure("Minor.TButton", font=("Lucida", 10))
|
||||||
self.dlgWin.protocol('WM_DELETE_WINDOW', self.close)
|
self.master.protocol('WM_DELETE_WINDOW', self.close)
|
||||||
logging.info("Options menu created.")
|
logging.info("Options menu created.")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.options["Textures"].pack = self.texture_select.get(ACTIVE) # Because it has no changed event
|
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.master.destroy()
|
self.master.destroy()
|
||||||
|
|
||||||
|
def update_sounds(self):
|
||||||
|
self.options["Sounds"] = self.using_sounds.get()
|
||||||
|
|
||||||
def update_difficulty(self, event):
|
def update_difficulty(self, event):
|
||||||
self.options["Difficulty"] = int(self.difficulty_scale.get())
|
self.options["Difficulty"] = int(self.difficulty_scale.get())
|
||||||
self.difficulty_title["text"] = "Current Difficulty: {}".format(self.options["Difficulty"])
|
self.difficulty_title["text"] = "Current Difficulty: {}".format(self.options["Difficulty"])
|
||||||
|
|
22
LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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.
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
print("Starting Space Invaders...\nLoading Main Window...")
|
print("Starting Attack on Blocks...\nLoading Main Window...")
|
||||||
import GUI
|
import GUI
|
||||||
GUI.display()
|
GUI.display()
|
||||||
|
|
18
README.md
|
@ -1,24 +1,26 @@
|
||||||
# Space Invaders #
|
# Attack on Blocks #
|
||||||
|
|
||||||
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.
|
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 ###
|
### Requirements ###
|
||||||
|
|
||||||
* Python
|
* Python 3
|
||||||
* Pygame
|
* Pygame
|
||||||
* TKinter
|
* 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.
|
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 ###
|
### Playing the game ###
|
||||||
|
|
||||||
* Clone the repository
|
* Clone the repository, or visit the downloads page
|
||||||
* Install the required libraries (See Above)
|
* Install the required libraries (See Above)
|
||||||
* Run 'Play The Game.py'
|
* Run 'Play The Game.py'
|
||||||
|
|
||||||
### Core Contributors ###
|
### Core Contributors ###
|
||||||
|
|
||||||
* Jake Howard
|
* Jake Howard
|
||||||
* Furhan Bhatti
|
* Furhan Bhatti (Well not really)
|
||||||
|
|
||||||
# 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
58
assets.py
|
@ -5,53 +5,66 @@ from random import randint
|
||||||
class Textures():
|
class Textures():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.images = {
|
self.images = {
|
||||||
"PLAYER":"player.png",
|
"PLAYER":"player",
|
||||||
"BULLET":"bullet.png",
|
"BULLET":"bullet",
|
||||||
"TARGETS":[],
|
"TARGETS":[],
|
||||||
"SHOOTER":"shooter.png",
|
"SHOOTER":"shooter",
|
||||||
"TARGET_BULLET":"target_bullet.png"
|
"TARGET_BULLET":"bullet_target",
|
||||||
|
"POWERUP": "powerup"
|
||||||
}
|
}
|
||||||
self.path=os.path.dirname(os.path.realpath(__file__)) + "\\resources\\texture_packs\\"
|
self.path=os.path.dirname(os.path.realpath(__file__)) + "\\resources\\texture_packs\\"
|
||||||
self.pack = "default"
|
self.pack = "default"
|
||||||
|
|
||||||
def load_texture_pack(self, packName):
|
def load_texture_pack(self, pack_name):
|
||||||
if os.path.exists(self.path + packName):
|
if os.path.exists(self.path + pack_name):
|
||||||
self.images["TARGETS"] = []
|
self.images["TARGETS"] = []
|
||||||
|
|
||||||
targets = glob.glob(self.path+packName+"\\target*.png")
|
targets = glob.glob(self.path+pack_name+"\\target*.png")
|
||||||
logging.debug("Found {0} target files.".format(len(targets)))
|
logging.debug("Found {0} target files.".format(len(targets)))
|
||||||
for file in targets:
|
for file in targets:
|
||||||
fileName = file.split("\\")[-1]
|
filename = file.split("\\")[-1].replace(".png", "")
|
||||||
self.images["TARGETS"].append(filename)
|
self.images["TARGETS"].append(filename)
|
||||||
|
|
||||||
self.pack = packName
|
self.pack = pack_name
|
||||||
else: logging.warn("Cannot find texture pack '{}'".format(packName))
|
else: logging.warn("Cannot find texture pack '{}'".format(ppack_name))
|
||||||
|
|
||||||
def get_texture(self, objectName):
|
def get_texture(self, objectName):
|
||||||
filename = self.path + self.pack + "\\{0}.png".format(self.images[objectName.upper()])
|
filename = self.path + self.pack + "\\{0}.png".format(self.images[objectName.upper()])
|
||||||
return pygame.image.load(filename)
|
return pygame.image.load(filename)
|
||||||
|
|
||||||
def get_target_texture(self):
|
def get_target_texture(self, ID=False):
|
||||||
filename = self.path + self.pack + "\\{}.png".format(self.images["TARGETS"][randint(0,len(self.images["TARGETS"]))])
|
if not ID:
|
||||||
return pygame.image.load(filename)
|
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 list_packs(self):
|
def list_packs(self):
|
||||||
return [x[0] for x in os.walk(self.path)]
|
return [x[0].replace(self.path, "") for x in os.walk(self.path)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Level_Template = namedtuple('Level_Template', ("rows", "padding", "firebacks", "powerups"))
|
Level_Template = namedtuple('Level_Template', ("rows", "padding", "firebacks", "powerups"))
|
||||||
Levels = [
|
Levels = [
|
||||||
Level_Template(2, 20, 0, 0),
|
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, 15, 2, 1),
|
||||||
Level_Template(4, 25, 7, 1)
|
Level_Template(3, 7, 2, 4),
|
||||||
|
Level_Template(4, 15, 4, 3),
|
||||||
|
Level_Template(5, 35, 4, 6),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def generate_random_level():
|
def generate_random_level():
|
||||||
logging.info("Generating a random level!")
|
logging.info("Generating a random level!")
|
||||||
rows = randint(0, 12)
|
rows = randint(1, 12)
|
||||||
padding = randint(0, 30)
|
padding = randint(5, 30)
|
||||||
firebacks = randint(0, 15)
|
firebacks = randint(0, 15)
|
||||||
powerups = randint(0, 15)
|
powerups = randint(0, 15)
|
||||||
return Level_Template(rows, padding, firebacks, powerups)
|
return Level_Template(rows, padding, firebacks, powerups)
|
||||||
|
@ -59,9 +72,12 @@ def generate_random_level():
|
||||||
|
|
||||||
Sounds = {}
|
Sounds = {}
|
||||||
def init_sounds():
|
def init_sounds():
|
||||||
music_files = ["main.mp3", "fire.mp3"]
|
music_files = ["main.ogg", "OP.ogg", "shot.ogg"]
|
||||||
for file in music_files:
|
for file in music_files:
|
||||||
path = os.path.dirname(os.path.realpath(__file__)) + "\\resources\\sounds\\" + file
|
path = os.path.dirname(os.path.realpath(__file__)) + "\\resources\\sounds\\" + file
|
||||||
if file == "main.mp3": mixer = pygame.mixer.music.load(path)
|
if file == "main.ogg":
|
||||||
else: mixer = pygame.mixer.Sound(file)
|
mixer = pygame.mixer.music
|
||||||
Sounds.update(file.split(".")[0], mixer)
|
mixer.load(path)
|
||||||
|
else: mixer = pygame.mixer.Sound(path)
|
||||||
|
mixer.set_volume(1.0)
|
||||||
|
Sounds[file.replace(".ogg", "")] = mixer
|
|
@ -2,10 +2,10 @@ import pygame
|
||||||
|
|
||||||
|
|
||||||
class Bullet(pygame.sprite.Sprite):
|
class Bullet(pygame.sprite.Sprite):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, textures, bigger):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.width = 4
|
self.width = 6 * (1+int(bigger))
|
||||||
self.height = 10
|
self.height = 14 * (1+int(bigger))
|
||||||
self.image = pygame.transform.scale(textures.get_texture("BULLET"), (self.width, self.height))
|
self.image = pygame.transform.scale(textures.get_texture("BULLET"), (self.width, self.height))
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.rect.x = parent.rect.x + parent.width/2 - self.width/2
|
self.rect.x = parent.rect.x + parent.width/2 - self.width/2
|
||||||
|
|
2
eggs.py
|
@ -3,7 +3,7 @@ from time import sleep
|
||||||
|
|
||||||
def r9k(window):
|
def r9k(window):
|
||||||
logging.warn("Look, you found a pepe!")
|
logging.warn("Look, you found a pepe!")
|
||||||
raw_image = urllib.request.urlopen("https://38.media.tumblr.com/avatar_2cd47bc1ad07_128.png").read()
|
raw_image = urllib.request.urlopen("http://img.ifcdn.com/images/620f230fad2806fe5305fac45dd673b8fc005b98c1e3b8584abc9c439b050950_1.jpg").read()
|
||||||
image_file = io.BytesIO(raw_image)
|
image_file = io.BytesIO(raw_image)
|
||||||
image = pygame.transform.scale(pygame.image.load(image_file), window.get_size())
|
image = pygame.transform.scale(pygame.image.load(image_file), window.get_size())
|
||||||
window.blit(image, (0,0))
|
window.blit(image, (0,0))
|
||||||
|
|
157
game.py
|
@ -5,36 +5,34 @@ import eggs
|
||||||
from bullet import Bullet
|
from bullet import Bullet
|
||||||
from player import Shooter
|
from player import Shooter
|
||||||
from assets import *
|
from assets import *
|
||||||
from target import Target
|
from target import Target, generate_targets
|
||||||
|
|
||||||
|
|
||||||
|
POWERUPS = ["SPEED", "DOUBLE", "LIVES", "SCORE", "BIGGER"]
|
||||||
PLAYING_GAME = False
|
PLAYING_GAME = False
|
||||||
WINDOW_SIZE = (640,480)
|
WINDOW_SIZE = (680, 790)
|
||||||
FPS = 120
|
HUD_COLOUR = (255,168,72)
|
||||||
|
|
||||||
|
|
||||||
def update_score(window, score):
|
def update_score(window, score, colour=HUD_COLOUR):
|
||||||
font = pygame.font.SysFont(None, 30, bold=False)
|
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))
|
window.blit(font.render("Score: {}".format(int(score)), True, colour), (25, WINDOW_SIZE[1] - 30))
|
||||||
|
|
||||||
def update_level(window, level):
|
def update_level(window, level, colour=HUD_COLOUR):
|
||||||
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)
|
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))
|
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):
|
def initialise(menu, options):
|
||||||
pygame.mixer.pre_init(44100, -16, 2, 2048)
|
pygame.mixer.pre_init(44100, -16, 2, 2048)
|
||||||
pygame.init()
|
pygame.init()
|
||||||
init_sounds()
|
|
||||||
options["Difficulty"] = FPS
|
|
||||||
window = pygame.display.set_mode(WINDOW_SIZE)
|
window = pygame.display.set_mode(WINDOW_SIZE)
|
||||||
|
pygame.display.set_caption("Attack on Blocks")
|
||||||
exit_code = play(window, options) # Run main game loop
|
exit_code = play(window, options) # Run main game loop
|
||||||
for key, value in Sounds.items():
|
for key, value in Sounds.items():
|
||||||
value.stop()
|
value.fadeout(500)
|
||||||
|
|
||||||
logging.debug("Game Exited with code {}".format(exit_code))
|
logging.debug("Game Exited with code {}".format(exit_code))
|
||||||
if exit_code != "QUIT": sleep(1)
|
if exit_code != "QUIT": sleep(1)
|
||||||
|
@ -43,77 +41,50 @@ def initialise(menu, options):
|
||||||
menu.deiconify()
|
menu.deiconify()
|
||||||
return exit_code
|
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):
|
def play(window, options):
|
||||||
window_rect = window.get_rect()
|
window_rect = window.get_rect()
|
||||||
|
options["Textures"].load_texture_pack(options["Textures"].pack)
|
||||||
player = Shooter(window=window)
|
player = Shooter(window=window, texture=options["Textures"])
|
||||||
player.set_position(WINDOW_SIZE[0]/2, WINDOW_SIZE[1]*0.83)
|
player.set_position(WINDOW_SIZE[0]/2, WINDOW_SIZE[1]*0.90)
|
||||||
player.options = options
|
player.options = options
|
||||||
player_group = pygame.sprite.Group()
|
player_group = pygame.sprite.Group()
|
||||||
player_group.add(player)
|
player_group.add(player)
|
||||||
|
|
||||||
target_group = generate_targets(player)
|
target_group = generate_targets(player, WINDOW_SIZE, Levels)
|
||||||
bullet_group = pygame.sprite.Group()
|
bullet_group = pygame.sprite.Group()
|
||||||
|
|
||||||
clock = pygame.time.Clock()
|
clock = pygame.time.Clock()
|
||||||
|
FPS = player.options["Difficulty"]
|
||||||
|
|
||||||
timeouts = {
|
timeouts = {
|
||||||
"Target Movement":[FPS*0.5,FPS*0.5],
|
"Target Movement":[FPS*0.65,FPS*0.65],
|
||||||
"Powerup":[FPS*100, FPS*100]
|
"Powerup":[FPS*15, FPS*15]
|
||||||
}
|
}
|
||||||
Sounds["main"].play(loops=-1) #Start background music
|
init_sounds()
|
||||||
|
if options["Sounds"]: Sounds["main"].play(loops=-1) #Start background music
|
||||||
|
|
||||||
logging.info("Game Started.")
|
logging.info("Game Started.")
|
||||||
PLAYING_GAME = True
|
PLAYING_GAME = True
|
||||||
while PLAYING_GAME:
|
while PLAYING_GAME:
|
||||||
window.fill((0,0,0))
|
window.fill((0,0,0))
|
||||||
|
|
||||||
|
fired = False
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
logging.critical("Exiting Game...")
|
logging.critical("Exiting Game...")
|
||||||
PLAYING_GAME = False
|
PLAYING_GAME = False
|
||||||
return "QUIT"
|
return "QUIT"
|
||||||
|
|
||||||
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
|
if event.type == pygame.KEYDOWN and event.key in [pygame.K_SPACE, pygame.K_w, pygame.K_UP] and not fired:
|
||||||
temp = Bullet(player)
|
if player.options["Sounds"]: Sounds["shot"].play()
|
||||||
|
temp = Bullet(player, player.options["Textures"], player.powerup == "BIGGER")
|
||||||
bullet_group.add(temp)
|
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
|
||||||
|
|
||||||
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()
|
keys = pygame.key.get_pressed()
|
||||||
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
|
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
|
||||||
|
@ -125,12 +96,28 @@ def play(window, options):
|
||||||
else: player.move(-player.speed)
|
else: player.move(-player.speed)
|
||||||
|
|
||||||
if keys[pygame.K_KP4] and keys[pygame.K_KP5] and keys[pygame.K_KP6] and player.OP:
|
if keys[pygame.K_KP4] and keys[pygame.K_KP5] and keys[pygame.K_KP6] and player.OP:
|
||||||
temp = Bullet(player)
|
temp = Bullet(player, player.options["Textures"], False)
|
||||||
bullet_group.add(temp)
|
bullet_group.add(temp)
|
||||||
|
|
||||||
if keys[pygame.K_r] and [pygame.K_9] and [pygame.K_k] and player.OP:
|
if keys[pygame.K_r] and [pygame.K_9] and [pygame.K_k] and player.OP:
|
||||||
eggs.r9k(window)
|
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:
|
for sprite in bullet_group:
|
||||||
sprite.update()
|
sprite.update()
|
||||||
if sprite.rect.y < 0 or (sprite.rect.y > player.rect.y and sprite.type == "TARGET"):
|
if sprite.rect.y < 0 or (sprite.rect.y > player.rect.y and sprite.type == "TARGET"):
|
||||||
|
@ -140,16 +127,21 @@ def play(window, options):
|
||||||
hit_list = pygame.sprite.spritecollide(bullet, target_group, False)
|
hit_list = pygame.sprite.spritecollide(bullet, target_group, False)
|
||||||
for target in hit_list:
|
for target in hit_list:
|
||||||
if bullet.type != "TARGET":
|
if bullet.type != "TARGET":
|
||||||
|
target.lives -= 1
|
||||||
|
if target.lives <= 0:
|
||||||
target_group.remove(target)
|
target_group.remove(target)
|
||||||
bullet_group.remove(bullet)
|
|
||||||
player.score += 1
|
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)
|
hit_list = pygame.sprite.spritecollide(bullet, player_group, False)
|
||||||
for player in hit_list:
|
for player in hit_list:
|
||||||
if bullet.type == "TARGET":
|
if bullet.type == "TARGET":
|
||||||
bullet_group.remove(bullet)
|
bullet_group.remove(bullet)
|
||||||
logging.info("You were hit by a target's bullet!")
|
logging.info("You were hit by a target's bullet!")
|
||||||
player.lives -= 1
|
if not player.OP: player.lives -= 1
|
||||||
if player.lives <= 0:
|
if player.lives <= 0:
|
||||||
return "LIVES"
|
return "LIVES"
|
||||||
|
|
||||||
|
@ -157,10 +149,10 @@ def play(window, options):
|
||||||
drop_targets = False
|
drop_targets = False
|
||||||
for target in target_group:
|
for target in target_group:
|
||||||
target.move()
|
target.move()
|
||||||
if target.rect.x <= 30 or target.rect.x >=WINDOW_SIZE[0] - 30:
|
if target.rect.x <= 30 or target.rect.x >=WINDOW_SIZE[0] - target.width/2 - 30:
|
||||||
drop_targets = True
|
drop_targets = True
|
||||||
|
|
||||||
if target.rect.y >= player.rect.y + 20:
|
if target.rect.y >= player.rect.y + target.height/2:
|
||||||
PLAYING_GAME = False
|
PLAYING_GAME = False
|
||||||
return "PLAYER COLLISION"
|
return "PLAYER COLLISION"
|
||||||
|
|
||||||
|
@ -171,35 +163,44 @@ def play(window, options):
|
||||||
|
|
||||||
timeouts["Target Movement"][0] = timeouts["Target Movement"][1]
|
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:
|
for target in target_group:
|
||||||
if target.type == "SHOOTER":
|
if target.type == "SHOOTER":
|
||||||
if randint(0,375) > 1: continue
|
if randint(0,600) > 1: continue
|
||||||
temp = Bullet(target)
|
temp = Bullet(target, player.options["Textures"], False)
|
||||||
temp.type="TARGET"
|
temp.type="TARGET"
|
||||||
temp.image = pygame.transform.scale(textures.get_texture("TARGET_BULLET"), (temp.width, temp.height))
|
temp.image = pygame.transform.scale(player.options["Textures"].get_texture("TARGET_BULLET"), (temp.width, temp.height))
|
||||||
x,y = temp.rect.x, temp.rect.y
|
x,y = temp.rect.x, temp.rect.y
|
||||||
temp.rect = temp.image.get_rect()
|
temp.rect = temp.image.get_rect()
|
||||||
temp.set_position(x,y)
|
temp.set_position(x,y)
|
||||||
temp.speed = -3 #So it shoots down!
|
temp.speed = -1 #So it shoots down!
|
||||||
bullet_group.add(temp)
|
bullet_group.add(temp)
|
||||||
|
|
||||||
if len(target_group) == 0: #If all current players are gone.
|
if len(target_group) == 0: #If all current players are gone.
|
||||||
player.level += 1
|
player.level += 1
|
||||||
target_group = generate_targets(player)
|
Sounds["main"].set_volume(0.5)
|
||||||
player.change_colour(player.colours[player.level])
|
target_group = generate_targets(player, WINDOW_SIZE, Levels)
|
||||||
target_group.draw()
|
target_group.draw(window)
|
||||||
|
bullet_group.empty()
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
sleep(1.5)
|
sleep(0.75)
|
||||||
|
Sounds["main"].set_volume(1.0)
|
||||||
if player.OP:
|
|
||||||
player.change_colour((255,96,0)) #override colour change if changed before
|
|
||||||
|
|
||||||
update_score(window, player.score)
|
update_score(window, player.score)
|
||||||
update_level(window, player.level)
|
update_level(window, player.level)
|
||||||
update_lives(window, player.lives)
|
update_lives(window, player.lives)
|
||||||
|
|
||||||
bullet_group.draw(window)
|
|
||||||
target_group.draw(window)
|
target_group.draw(window)
|
||||||
|
bullet_group.draw(window)
|
||||||
player_group.draw(window)
|
player_group.draw(window)
|
||||||
|
|
||||||
for key, value in timeouts.items():
|
for key, value in timeouts.items():
|
||||||
|
|
12
player.py
|
@ -2,12 +2,13 @@ import pygame
|
||||||
|
|
||||||
|
|
||||||
class Shooter(pygame.sprite.Sprite):
|
class Shooter(pygame.sprite.Sprite):
|
||||||
def __init__(self, window, texture, colour=(255,255,255), width=45, height=20):
|
def __init__(self, window, texture, colour=(255,255,255), width=55, height=25):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.colour = colour
|
self.colour = colour
|
||||||
self.image = pygame.transform.scale(textures.get_texture("PLAYER"), (self.width, self.height))
|
self.texture = texture
|
||||||
|
self.image = pygame.transform.scale(self.texture.get_texture("PLAYER"), (self.width, self.height))
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.speed = 3
|
self.speed = 3
|
||||||
self.window_rect = window.get_rect()
|
self.window_rect = window.get_rect()
|
||||||
|
@ -17,7 +18,6 @@ class Shooter(pygame.sprite.Sprite):
|
||||||
self.level = 0
|
self.level = 0
|
||||||
self.lives = 3
|
self.lives = 3
|
||||||
self.powerup = ""
|
self.powerup = ""
|
||||||
self.colours = [(255,0,0), (255,255,0), (0,255,0)]
|
|
||||||
|
|
||||||
def set_position(self,x,y):
|
def set_position(self,x,y):
|
||||||
self.rect.x, self.rect.y = x, y
|
self.rect.x, self.rect.y = x, y
|
||||||
|
@ -35,3 +35,9 @@ class Shooter(pygame.sprite.Sprite):
|
||||||
self.image.fill(colour)
|
self.image.fill(colour)
|
||||||
self.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.set_position(x,y)
|
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)
|
BIN
resources/sounds/OP.ogg
Normal file
BIN
resources/sounds/main.ogg
Normal file
BIN
resources/sounds/shot.ogg
Normal file
BIN
resources/texture_packs/default/bullet.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
resources/texture_packs/default/bullet_target.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
resources/texture_packs/default/player.png
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
resources/texture_packs/default/powerup.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
resources/texture_packs/default/shooter.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
resources/texture_packs/default/target0.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
resources/texture_packs/default/target1.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
resources/texture_packs/default/target2.png
Normal file
After Width: | Height: | Size: 48 KiB |
66
target.py
|
@ -1,23 +1,27 @@
|
||||||
import pygame
|
import pygame, logging
|
||||||
from random import randint
|
from random import randint
|
||||||
|
from game import generate_random_level
|
||||||
|
|
||||||
|
|
||||||
class Target(pygame.sprite.Sprite):
|
class Target(pygame.sprite.Sprite):
|
||||||
def __init__(self, x, y, textures, color=(30,0,150), width=16, height=16):
|
def __init__(self, x, y, textures, color=(30,0,150), width=23, height=23):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.image = pygame.transform.scale(textures.get_target_texture(), (self.width, self.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.rect = self.image.get_rect()
|
self.rect = self.image.get_rect()
|
||||||
self.speed = 7
|
self.speed = 5
|
||||||
self.rect.x, self.rect.y = (x+(self.width/2)),(y+(self.width/2)) # centres co-ordinates
|
self.rect.x, self.rect.y = (x+(self.width/2)),(y+(self.width/2)) # centres co-ordinates
|
||||||
self.type = "NORMAL"
|
self.type = "NORMAL"
|
||||||
|
self.lives = 1
|
||||||
|
|
||||||
def move(self):
|
def move(self):
|
||||||
self.rect.x += self.speed
|
self.rect.x += self.speed
|
||||||
|
|
||||||
def drop(self):
|
def drop(self):
|
||||||
self.rect.y += 17
|
self.rect.y += 13
|
||||||
self.speed *= -1
|
self.speed *= -1
|
||||||
|
|
||||||
def set_position(self, x, y, center=False):
|
def set_position(self, x, y, center=False):
|
||||||
|
@ -26,4 +30,56 @@ class Target(pygame.sprite.Sprite):
|
||||||
else:
|
else:
|
||||||
self.rect.x, self.rect.y = x, y
|
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
|
||||||
|
|