New assets added to Drone Invaders, refactored vars to be lower_snake
This commit is contained in:
parent
56098735ee
commit
ddac591131
12 changed files with 375 additions and 36 deletions
|
@ -3,8 +3,9 @@ import math
|
|||
from drone import Drone
|
||||
from pygame import mixer
|
||||
|
||||
|
||||
class Bomb(BoundedTurtle):
|
||||
def __init__(self, initHeading, speed, x_min, xMax, yMin, yMax, scoreboard):
|
||||
def __init__(self, init_heading, speed, x_min, x_max, y_min, y_max, scoreboard):
|
||||
pass
|
||||
|
||||
def move(self):
|
||||
|
|
|
@ -11,18 +11,18 @@ class BoundedTurtle(Turtle):
|
|||
self.__speed = speed
|
||||
|
||||
def out_of_bounds(self):
|
||||
xPos, yPos = self.position()
|
||||
x_pos, y_pos = self.position()
|
||||
out = False
|
||||
if xPos < self.__xMin or xPos > self.__xMax:
|
||||
if x_pos < self.__x_min or x_pos > self.__x_max:
|
||||
out = True
|
||||
if yPos < self.__yMin or yPos > self.__yMax:
|
||||
if y_pos < self.__y_min or y_pos > self.__y_max:
|
||||
out = True
|
||||
return out
|
||||
|
||||
def below_bottom_bound(self):
|
||||
x_pos, y_pos = self.position()
|
||||
out = False
|
||||
if y_pos < self.__yMin:
|
||||
if y_pos < self.__y_min:
|
||||
out = True
|
||||
return out
|
||||
|
||||
|
@ -30,16 +30,16 @@ class BoundedTurtle(Turtle):
|
|||
return self.__speed
|
||||
|
||||
def get_x_min(self):
|
||||
return self.__xMin
|
||||
return self.__x_min
|
||||
|
||||
def getXMax(self):
|
||||
return self.__xMax
|
||||
return self.__x_max
|
||||
|
||||
def getYMin(self):
|
||||
return self.__yMin
|
||||
def get_y_min(self):
|
||||
return self.__y_min
|
||||
|
||||
def getYMax(self):
|
||||
return self.__yMax
|
||||
def get_y_max(self):
|
||||
return self.__y_max
|
||||
|
||||
@abstractmethod
|
||||
def remove(self):
|
||||
|
|
|
@ -1,42 +1,99 @@
|
|||
import turtle
|
||||
from turtle import Screen
|
||||
from drone import Drone
|
||||
from lasercannon import LaserCannon
|
||||
from scoreboard import Scoreboard
|
||||
import time
|
||||
from sound_and_music import SoundAndMusic
|
||||
|
||||
|
||||
class DroneInvaders:
|
||||
def __init__(self, x_min, x_max, y_min, y_max):
|
||||
"""
|
||||
Initializes DroneInvaders
|
||||
:param x_min: minimum x value for things on screen
|
||||
:param x_max: maximum x value for things on screen
|
||||
:param y_min: minimum y value for things on screen
|
||||
:param y_max: maximum y value from things on screen
|
||||
"""
|
||||
self.x_min = x_min
|
||||
self.x_max = x_max
|
||||
self.y_min = y_min
|
||||
self.y_max = y_max
|
||||
self.screen = Screen()
|
||||
self.screen.title('Drone Invaders - A totally original game')
|
||||
self.screen.setworldcoordinates(x_min, y_min, x_max, y_max)
|
||||
self.scoreboard = Scoreboard(x_min + 0.1, y_max - 0.2)
|
||||
self.screen.tracer(False)
|
||||
self.screen.title('Drone Invaders - Not Space Invaders or Asteroids')
|
||||
self.screen.bgcolor('light green')
|
||||
self.screen.setworldcoordinates(self.x_min, self.y_min, self.x_max, self.y_max)
|
||||
self.scoreboard = Scoreboard(x_min + 0.02, y_max - 0.2)
|
||||
self.lasercannon = LaserCannon(self.x_min, self.x_max, self.y_min, self.y_max, self.screen, self.scoreboard)
|
||||
self.delay = 0.1
|
||||
self.game_states = {'Intro': 1, 'Playing': 2, 'InterLevel': 3, 'GameOver': 4, 'Pause': 5}
|
||||
self.game_state = self.game_states['Intro']
|
||||
self.screen.bgcolor('light green')
|
||||
self.laser_cannon = LaserCannon(x_min, x_max, y_min, y_max, self.screen, self.scoreboard)
|
||||
|
||||
def play(self):
|
||||
|
||||
self.screen.exitonclick()
|
||||
|
||||
def add_drone(self):
|
||||
if len(Drone.get_drones()) < 7:
|
||||
Drone(0.01, self.x_min, self.x_max, self.y_min, self.y_max)
|
||||
if self.game_state != self.game_states['Playing']:
|
||||
return
|
||||
if self.scoreboard.drones_remaining > len(Drone.getDrones()) and len(
|
||||
Drone.getDrones()) < self.scoreboard.max_drones:
|
||||
Drone(self.scoreboard.drone_speed, self.x_min, self.x_max, self.y_min, self.y_max)
|
||||
if not self.done:
|
||||
self.screen.ontimer(fun=self.addDrone, t=1000)
|
||||
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
||||
|
||||
def pause(self):
|
||||
if self.game_state == self.game_states['Playing']:
|
||||
self.screen.ontimer(self.add_drone, 0)
|
||||
self.game_state = self.game_states['Pause']
|
||||
SoundAndMusic.pause_music()
|
||||
# Write to screen
|
||||
# self.pause_screen.bgcolor('light blue')
|
||||
self.lasercannon.hideturtle()
|
||||
for drone in Drone.getDrones():
|
||||
drone.hideturtle()
|
||||
self.draw_pause_message()
|
||||
|
||||
|
||||
else:
|
||||
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
||||
self.game_state = self.game_states['Playing']
|
||||
SoundAndMusic.unpause_music()
|
||||
self.lasercannon.showturtle()
|
||||
for drone in Drone.getDrones():
|
||||
drone.showturtle()
|
||||
self.pause_turtle.clear()
|
||||
|
||||
def draw_pause_message(self):
|
||||
self.pause_turtle.clear()
|
||||
up = '⇑'
|
||||
down = '⇓'
|
||||
self.pause_turtle.color('black')
|
||||
self.pause_turtle.goto(-0.5, 0.3)
|
||||
self.pause_turtle.write(f'Music volume: {SoundAndMusic.music_volume} of 100', align='left',
|
||||
font=self.PAUSE_FONT)
|
||||
self.pause_turtle.goto(-0.5, 0.2)
|
||||
self.pause_turtle.write(f'Sfx volume: {SoundAndMusic.sfx_volume} of 100', align='left', font=self.PAUSE_FONT)
|
||||
self.pause_turtle.goto(-0.5, 0)
|
||||
self.pause_turtle.write(f'Music up {up}', align='left', font=self.PAUSE_FONT)
|
||||
self.pause_turtle.goto(-0.5, -0.1)
|
||||
self.pause_turtle.write(f'Music down {down}', align='left', font=self.PAUSE_FONT)
|
||||
self.pause_turtle.goto(-0.5, -0.2)
|
||||
self.pause_turtle.write(f'Sfx up +', align='left', font=self.PAUSE_FONT)
|
||||
self.pause_turtle.goto(-0.5, -0.3)
|
||||
self.pause_turtle.write(f'Sfx down -', align='left', font=self.PAUSE_FONT)
|
||||
|
||||
def music_up(self):
|
||||
SoundAndMusic.change_music_volume(1)
|
||||
self.draw_pause_message()
|
||||
|
||||
def music_down(self):
|
||||
SoundAndMusic.change_music_volume(-1)
|
||||
self.draw_pause_message()
|
||||
|
||||
def sfx_up(self):
|
||||
SoundAndMusic.change_sfx_volume(1)
|
||||
self.draw_pause_message()
|
||||
|
||||
def sfx_down(self):
|
||||
SoundAndMusic.change_music_volume(-1)
|
||||
self.draw_pause_message()
|
||||
|
||||
def quit(self):
|
||||
self.screen.bye()
|
||||
exit(0)
|
||||
sys.exit()
|
||||
|
|
|
@ -2,14 +2,13 @@ from turtle import Turtle
|
|||
from bomb import Bomb
|
||||
from pygame import mixer
|
||||
|
||||
|
||||
class LaserCannon(Turtle):
|
||||
def __init__(self, x_min, x_max, y_min, y_max, screen, scoreboard):
|
||||
pass
|
||||
|
||||
|
||||
def aim(self, x, y):
|
||||
pass
|
||||
|
||||
def shoot(self):
|
||||
pass
|
||||
|
||||
|
||||
|
|
32
Turtle/Drone Invaders/level_data.json
Normal file
32
Turtle/Drone Invaders/level_data.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"Level1": {
|
||||
"NumDrones": 10,
|
||||
"MaxDrones": 7,
|
||||
"DroneSpeed": 0.005,
|
||||
"SpawnTime": 2000
|
||||
},
|
||||
"Level2": {
|
||||
"NumDrones": 15,
|
||||
"MaxDrones": 10,
|
||||
"DroneSpeed": 0.01,
|
||||
"SpawnTime": 1500
|
||||
},
|
||||
"Level3": {
|
||||
"NumDrones": 20,
|
||||
"MaxDrones": 15,
|
||||
"DroneSpeed": 0.015,
|
||||
"SpawnTime": 1000
|
||||
},
|
||||
"Level4": {
|
||||
"NumDrones": 30,
|
||||
"MaxDrones": 20,
|
||||
"DroneSpeed": 0.02,
|
||||
"SpawnTime": 800
|
||||
},
|
||||
"Level5": {
|
||||
"NumDrones": 50,
|
||||
"MaxDrones": 25,
|
||||
"DroneSpeed": 0.025,
|
||||
"SpawnTime": 600
|
||||
}
|
||||
}
|
8
Turtle/Drone Invaders/level_data_easy.json
Normal file
8
Turtle/Drone Invaders/level_data_easy.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Level1": {
|
||||
"NumDrones": 10,
|
||||
"MaxDrones": 7,
|
||||
"DroneSpeed": 0.005,
|
||||
"SpawnTime": 2000
|
||||
}
|
||||
}
|
11
Turtle/Drone Invaders/main.py
Normal file
11
Turtle/Drone Invaders/main.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from droneinvaders import DroneInvaders
|
||||
from sound_and_music import SoundAndMusic
|
||||
|
||||
SoundAndMusic.start_pygame()
|
||||
SoundAndMusic.load_music()
|
||||
SoundAndMusic.play_music()
|
||||
SoundAndMusic.load_sounds()
|
||||
|
||||
if __name__ == '__main__':
|
||||
di = DroneInvaders(-1, 1, -1, 1)
|
||||
di.play()
|
|
@ -1,18 +1,139 @@
|
|||
from turtle import Turtle
|
||||
import json
|
||||
from sound_and_music import SoundAndMusic
|
||||
import time
|
||||
|
||||
|
||||
class Scoreboard(Turtle):
|
||||
|
||||
def __init__(self, x, y):
|
||||
pass
|
||||
super().__init__()
|
||||
self.score = 0
|
||||
|
||||
# Level Data
|
||||
with open('level_data.json', 'r') as file:
|
||||
self.level_data = json.load(file)
|
||||
|
||||
self.levels = list(self.level_data.keys())
|
||||
self.__current_level = 0 # must use dunderscore here because of @property, do not want a setter
|
||||
self.__drones_remaining = self.level_data[self.levels[self.current_level]]['NumDrones']
|
||||
self.__max_drones = self.level_data[self.levels[self.current_level]]['MaxDrones']
|
||||
self.__drone_speed = self.level_data[self.levels[self.current_level]]['DroneSpeed']
|
||||
self.__spawn_time = self.level_data[self.levels[self.current_level]]['SpawnTime']
|
||||
|
||||
try:
|
||||
with open('data.txt') as file:
|
||||
self.high_score = int(file.read())
|
||||
except FileNotFoundError:
|
||||
self.high_score = 0
|
||||
self.color('white')
|
||||
self.penup()
|
||||
|
||||
self.hideturtle()
|
||||
self.setposition(x, y)
|
||||
self.SCORE_FONT = ('Courier', 18, 'bold')
|
||||
self.GAME_OVER_FONT = ('Courier', 36, 'bold')
|
||||
self.LEFT_ALIGN = 'left'
|
||||
self.CENTER_ALIGN = 'center'
|
||||
self.draw_scoreboard()
|
||||
|
||||
self.gameover_sound_played = False
|
||||
|
||||
@property
|
||||
def current_level(self):
|
||||
return self.__current_level
|
||||
|
||||
@property
|
||||
def drones_remaining(self):
|
||||
return self.__drones_remaining
|
||||
|
||||
@property
|
||||
def max_drones(self):
|
||||
return self.__max_drones
|
||||
|
||||
@property
|
||||
def drone_speed(self):
|
||||
return self.__drone_speed
|
||||
|
||||
@property
|
||||
def spawn_time(self):
|
||||
return self.__spawn_time
|
||||
|
||||
def draw_scoreboard(self):
|
||||
pass
|
||||
self.clear()
|
||||
display = (
|
||||
f'Score: {self.score} :: Level: {self.current_level + 1} :: Drones Remaining: {self.drones_remaining}'
|
||||
f' :: High Score: {self.high_score}')
|
||||
self.write(display, align=self.LEFT_ALIGN, font=self.SCORE_FONT)
|
||||
|
||||
def reset(self):
|
||||
pass
|
||||
if self.score > self.high_score:
|
||||
self.high_score = self.score
|
||||
with open('data.txt', 'w') as file:
|
||||
file.write(str(self.high_score))
|
||||
self.score = 0
|
||||
self.draw_scoreboard()
|
||||
|
||||
def game_over(self):
|
||||
pass
|
||||
SoundAndMusic.stop_music()
|
||||
if self.score > self.high_score:
|
||||
with open('data.txt', 'w') as file:
|
||||
file.write(str(self.score))
|
||||
self.score = -1
|
||||
if self.current_level == len(self.levels) and self.drones_remaining == 0:
|
||||
self.game_over_won()
|
||||
else:
|
||||
self.game_over_lost()
|
||||
|
||||
def increment(self, amount):
|
||||
pass
|
||||
def game_over_lost(self):
|
||||
self.goto(0, 0)
|
||||
self.write('GAME OVER', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
self.goto(0, -0.15)
|
||||
self.write('The world has been destroyed', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
if not self.gameover_sound_played:
|
||||
self.gameover_sound_played = True
|
||||
SoundAndMusic.play_game_lost_sound()
|
||||
|
||||
def game_over_won(self):
|
||||
self.goto(0, 0.15)
|
||||
self.write('Victory', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
self.goto(0, 0)
|
||||
self.write('You saved the world!', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
self.goto(0, -0.15)
|
||||
self.write('You have been elected', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
self.goto(0, -0.30)
|
||||
self.write('Grand Poobah!', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
if not self.gameover_sound_played:
|
||||
self.gameover_sound_played = True
|
||||
SoundAndMusic.play_game_won_sound()
|
||||
|
||||
def increment(self, amount, droneLost=True):
|
||||
self.score += amount
|
||||
if droneLost:
|
||||
self.__drones_remaining -= 1
|
||||
self.draw_scoreboard()
|
||||
|
||||
def new_level(self):
|
||||
self.__current_level += 1
|
||||
if self.__current_level < len(self.levels):
|
||||
self.__drones_remaining = self.level_data[self.levels[self.current_level]]['NumDrones']
|
||||
self.__max_drones = self.level_data[self.levels[self.current_level]]['MaxDrones']
|
||||
self.__drone_speed = self.level_data[self.levels[self.current_level]]['DroneSpeed']
|
||||
self.__spawn_time = self.level_data[self.levels[self.current_level]]['SpawnTime']
|
||||
SoundAndMusic.play_change_level_sound()
|
||||
count = 5
|
||||
countDown = Turtle()
|
||||
countDown.hideturtle()
|
||||
countDown.penup()
|
||||
countDown.goto(0, 0)
|
||||
SoundAndMusic.pause_music()
|
||||
while count >= 0:
|
||||
countDown.write(f'{count}', align=self.CENTER_ALIGN, font=self.GAME_OVER_FONT)
|
||||
time.sleep(1.0)
|
||||
countDown.clear()
|
||||
count -= 1
|
||||
SoundAndMusic.unpause_music()
|
||||
self.draw_scoreboard()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
110
Turtle/Drone Invaders/sound_and_music.py
Normal file
110
Turtle/Drone Invaders/sound_and_music.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
import pygame
|
||||
from pygame import mixer
|
||||
|
||||
class SoundAndMusic:
|
||||
|
||||
laser_sound = 0
|
||||
explosion_sound = 0
|
||||
change_level_sound = 0
|
||||
music_volume = 0
|
||||
sfx_volume = 0
|
||||
game_lost_sound = 0
|
||||
game_won_sound = 0
|
||||
|
||||
@staticmethod
|
||||
def start_pygame():
|
||||
#global laser_sound, explosion_sound, change_level_sound, music_volume, sfx_volume
|
||||
pygame.init()
|
||||
SoundAndMusic.laser_sound = 0.0
|
||||
SoundAndMusic.explosion_sound = 0.0
|
||||
SoundAndMusic.change_level_sound = 0.0
|
||||
SoundAndMusic.game_lost_sound = 0.0
|
||||
SoundAndMusic.game_won_sound = 0.0
|
||||
SoundAndMusic.music_volume = 5
|
||||
SoundAndMusic.sfx_volume = 10
|
||||
|
||||
@staticmethod
|
||||
def load_music():
|
||||
#global music_volume
|
||||
mixer.music.load('sounds/mixed_themes.ogg')
|
||||
mixer.music.set_volume(SoundAndMusic.music_volume / 100)
|
||||
|
||||
@staticmethod
|
||||
def play_music():
|
||||
mixer.music.play(loops=-1)
|
||||
|
||||
@staticmethod
|
||||
def pause_music():
|
||||
mixer.music.pause()
|
||||
|
||||
@staticmethod
|
||||
def unpause_music():
|
||||
mixer.music.unpause()
|
||||
|
||||
@staticmethod
|
||||
def stop_music():
|
||||
mixer.music.stop()
|
||||
|
||||
@staticmethod
|
||||
def load_sounds():
|
||||
#global sfx_volume, laser_sound, explosion_sound, change_level_sound
|
||||
SoundAndMusic.laser_sound = mixer.Sound('sounds/laser.wav')
|
||||
SoundAndMusic.laser_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
SoundAndMusic.explosion_sound = mixer.Sound('sounds/explosion.wav')
|
||||
SoundAndMusic.explosion_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
SoundAndMusic.change_level_sound = mixer.Sound('sounds/change_levels.wav')
|
||||
SoundAndMusic.change_level_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
SoundAndMusic.game_lost_sound = mixer.Sound('sounds/game_lost_sound.wav')
|
||||
SoundAndMusic.game_lost_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
SoundAndMusic.game_won_sound = mixer.Sound('sounds/game_won_sound.wav')
|
||||
SoundAndMusic.game_won_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def play_laser_sound():
|
||||
SoundAndMusic.laser_sound.play()
|
||||
|
||||
@staticmethod
|
||||
def play_explosion_sound():
|
||||
SoundAndMusic.explosion_sound.play()
|
||||
|
||||
@staticmethod
|
||||
def play_change_level_sound():
|
||||
SoundAndMusic.change_level_sound.play()
|
||||
|
||||
@staticmethod
|
||||
def play_game_lost_sound():
|
||||
SoundAndMusic.game_lost_sound.play()
|
||||
|
||||
@staticmethod
|
||||
def play_game_won_sound():
|
||||
SoundAndMusic.game_won_sound.play()
|
||||
|
||||
@staticmethod
|
||||
def change_sfx_volume(delta_volume):
|
||||
#global laser_sound, explosion_sound, change_level_sound, sfx_volume
|
||||
SoundAndMusic.sfx_volume += delta_volume
|
||||
if SoundAndMusic.sfx_volume > 100:
|
||||
SoundAndMusic.sfx_volume = 100
|
||||
elif SoundAndMusic.sfx_volume < 0:
|
||||
SoundAndMusic.sfx_volume = 0
|
||||
SoundAndMusic.laser_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
SoundAndMusic.explosion_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
SoundAndMusic.change_level_sound.set_volume(SoundAndMusic.sfx_volume / 100)
|
||||
print(SoundAndMusic.sfx_volume)
|
||||
|
||||
@staticmethod
|
||||
def change_music_volume(delta_volume):
|
||||
#global music_volume
|
||||
SoundAndMusic.music_volume += delta_volume
|
||||
if SoundAndMusic.music_volume > 100:
|
||||
SoundAndMusic.music_volume = 100
|
||||
elif SoundAndMusic.music_volume < 0:
|
||||
SoundAndMusic.music_volume = 0
|
||||
mixer.music.set_volume(SoundAndMusic.music_volume / 100)
|
||||
print(SoundAndMusic.music_volume)
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
Turtle/Drone Invaders/sounds/change_levels.wav
Normal file
BIN
Turtle/Drone Invaders/sounds/change_levels.wav
Normal file
Binary file not shown.
BIN
Turtle/Drone Invaders/sounds/game_lost_sound.wav
Normal file
BIN
Turtle/Drone Invaders/sounds/game_lost_sound.wav
Normal file
Binary file not shown.
BIN
Turtle/Drone Invaders/sounds/game_won_sound.wav
Normal file
BIN
Turtle/Drone Invaders/sounds/game_won_sound.wav
Normal file
Binary file not shown.
Loading…
Reference in a new issue