New assets added to Drone Invaders, refactored vars to be lower_snake

This commit is contained in:
ben 2022-07-26 14:12:41 -05:00
parent 56098735ee
commit ddac591131
12 changed files with 375 additions and 36 deletions

View file

@ -3,8 +3,9 @@ import math
from drone import Drone from drone import Drone
from pygame import mixer from pygame import mixer
class Bomb(BoundedTurtle): 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 pass
def move(self): def move(self):

View file

@ -11,18 +11,18 @@ class BoundedTurtle(Turtle):
self.__speed = speed self.__speed = speed
def out_of_bounds(self): def out_of_bounds(self):
xPos, yPos = self.position() x_pos, y_pos = self.position()
out = False out = False
if xPos < self.__xMin or xPos > self.__xMax: if x_pos < self.__x_min or x_pos > self.__x_max:
out = True out = True
if yPos < self.__yMin or yPos > self.__yMax: if y_pos < self.__y_min or y_pos > self.__y_max:
out = True out = True
return out return out
def below_bottom_bound(self): def below_bottom_bound(self):
x_pos, y_pos = self.position() x_pos, y_pos = self.position()
out = False out = False
if y_pos < self.__yMin: if y_pos < self.__y_min:
out = True out = True
return out return out
@ -30,16 +30,16 @@ class BoundedTurtle(Turtle):
return self.__speed return self.__speed
def get_x_min(self): def get_x_min(self):
return self.__xMin return self.__x_min
def getXMax(self): def getXMax(self):
return self.__xMax return self.__x_max
def getYMin(self): def get_y_min(self):
return self.__yMin return self.__y_min
def getYMax(self): def get_y_max(self):
return self.__yMax return self.__y_max
@abstractmethod @abstractmethod
def remove(self): def remove(self):

View file

@ -1,42 +1,99 @@
import turtle
from turtle import Screen from turtle import Screen
from drone import Drone from drone import Drone
from lasercannon import LaserCannon from lasercannon import LaserCannon
from scoreboard import Scoreboard from scoreboard import Scoreboard
import time import time
from sound_and_music import SoundAndMusic
class DroneInvaders: class DroneInvaders:
def __init__(self, x_min, x_max, y_min, y_max): 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_min = x_min
self.x_max = x_max self.x_max = x_max
self.y_min = y_min self.y_min = y_min
self.y_max = y_max self.y_max = y_max
self.screen = Screen() self.screen = Screen()
self.screen.title('Drone Invaders - A totally original game') self.screen.tracer(False)
self.screen.setworldcoordinates(x_min, y_min, x_max, y_max) self.screen.title('Drone Invaders - Not Space Invaders or Asteroids')
self.scoreboard = Scoreboard(x_min + 0.1, y_max - 0.2) 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.delay = 0.1
self.game_states = {'Intro': 1, 'Playing': 2, 'InterLevel': 3, 'GameOver': 4, 'Pause': 5} self.game_states = {'Intro': 1, 'Playing': 2, 'InterLevel': 3, 'GameOver': 4, 'Pause': 5}
self.game_state = self.game_states['Intro'] 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): def play(self):
self.screen.exitonclick() self.screen.exitonclick()
def add_drone(self): def add_drone(self):
if len(Drone.get_drones()) < 7: if self.game_state != self.game_states['Playing']:
Drone(0.01, self.x_min, self.x_max, self.y_min, self.y_max) 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: 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): def quit(self):
self.screen.bye() self.screen.bye()
exit(0) sys.exit()

View file

@ -2,6 +2,7 @@ from turtle import Turtle
from bomb import Bomb from bomb import Bomb
from pygame import mixer from pygame import mixer
class LaserCannon(Turtle): class LaserCannon(Turtle):
def __init__(self, x_min, x_max, y_min, y_max, screen, scoreboard): def __init__(self, x_min, x_max, y_min, y_max, screen, scoreboard):
pass pass
@ -11,5 +12,3 @@ class LaserCannon(Turtle):
def shoot(self): def shoot(self):
pass pass

View 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
}
}

View file

@ -0,0 +1,8 @@
{
"Level1": {
"NumDrones": 10,
"MaxDrones": 7,
"DroneSpeed": 0.005,
"SpawnTime": 2000
}
}

View 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()

View file

@ -1,18 +1,139 @@
from turtle import Turtle from turtle import Turtle
import json
from sound_and_music import SoundAndMusic
import time
class Scoreboard(Turtle): class Scoreboard(Turtle):
def __init__(self, x, y): 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): 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): 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): 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): def game_over_lost(self):
pass 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

View 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)

Binary file not shown.

Binary file not shown.

Binary file not shown.