2022-07-26 14:12:41 -05:00
|
|
|
import turtle
|
2022-07-21 16:07:13 -05:00
|
|
|
from turtle import Screen
|
|
|
|
from drone import Drone
|
2022-07-26 14:39:29 -05:00
|
|
|
from rocket import Rocket
|
2022-07-21 16:07:13 -05:00
|
|
|
from scoreboard import Scoreboard
|
|
|
|
import time
|
2022-07-28 14:55:15 -05:00
|
|
|
from audio import Audio
|
2022-07-21 16:07:13 -05:00
|
|
|
|
2022-07-21 16:36:45 -05:00
|
|
|
|
2022-07-21 16:07:13 -05:00
|
|
|
class DroneInvaders:
|
2022-07-21 16:36:45 -05:00
|
|
|
def __init__(self, x_min, x_max, y_min, y_max):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Initialize the game.
|
|
|
|
:param x_min: Minimum x coordinate of the screen.
|
|
|
|
:param x_max: Maximum x coordinate of the screen.
|
|
|
|
:param y_min: Minimum y coordinate of the screen.
|
|
|
|
:param y_max: Maximum y coordinate of the screen.
|
|
|
|
"""
|
2022-07-26 16:27:55 -05:00
|
|
|
self.done = None
|
2022-07-21 16:36:45 -05:00
|
|
|
self.x_min = x_min
|
|
|
|
self.x_max = x_max
|
|
|
|
self.y_min = y_min
|
|
|
|
self.y_max = y_max
|
|
|
|
self.screen = Screen()
|
2022-07-26 14:12:41 -05:00
|
|
|
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)
|
2022-07-26 16:27:55 -05:00
|
|
|
self.rocket = Rocket(self.x_min, self.x_max, self.y_min, self.y_max, self.screen, self.scoreboard)
|
2022-07-21 16:36:45 -05:00
|
|
|
self.delay = 0.1
|
|
|
|
self.game_states = {'Intro': 1, 'Playing': 2, 'InterLevel': 3, 'GameOver': 4, 'Pause': 5}
|
|
|
|
self.game_state = self.game_states['Intro']
|
2022-07-21 16:07:13 -05:00
|
|
|
|
2022-07-26 16:27:55 -05:00
|
|
|
self.pause_turtle = turtle.Turtle()
|
|
|
|
self.pause_turtle.hideturtle()
|
|
|
|
self.pause_turtle.penup()
|
|
|
|
self.PAUSE_FONT = ('Arial', 24, 'bold')
|
|
|
|
|
2022-07-21 16:07:13 -05:00
|
|
|
def play(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Play the game.
|
|
|
|
:return: None
|
|
|
|
"""
|
2022-07-26 16:27:55 -05:00
|
|
|
self.scoreboard.draw_scoreboard()
|
|
|
|
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
|
|
|
|
|
|
|
# Register listeners
|
|
|
|
self.screen.onclick(self.rocket.aim)
|
|
|
|
self.screen.onkey(self.rocket.shoot, 'space')
|
|
|
|
self.screen.onkey(self.rocket.shoot, 's')
|
|
|
|
self.screen.onkey(self.pause, 'p')
|
|
|
|
self.screen.onkey(self.quit, 'Escape')
|
|
|
|
self.screen.onkey(self.quit, 'q')
|
|
|
|
self.screen.onkey(self.music_up, 'Up')
|
|
|
|
self.screen.onkey(self.music_down, 'Down')
|
|
|
|
self.screen.onkey(self.sfx_up, '+') # Only works with plus on num pad
|
|
|
|
self.screen.onkey(self.sfx_down, '=') # For plus beside backspace
|
|
|
|
self.screen.onkey(self.sfx_down, '-') # Works with either minus
|
|
|
|
self.screen.listen()
|
|
|
|
|
|
|
|
self.done = False
|
|
|
|
while not self.done:
|
|
|
|
self.screen.update()
|
|
|
|
|
|
|
|
if self.game_state == self.game_states['Intro']:
|
|
|
|
self.game_state = self.game_states['Playing']
|
|
|
|
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
2022-07-28 16:00:29 -05:00
|
|
|
|
2022-07-26 16:27:55 -05:00
|
|
|
elif self.game_state == self.game_states['Playing']:
|
|
|
|
# Update drones
|
|
|
|
if self.scoreboard.drones_remaining <= 0:
|
|
|
|
self.game_state = self.game_states['InterLevel']
|
|
|
|
else:
|
|
|
|
for drone in Drone.get_drones():
|
2022-07-28 16:00:29 -05:00
|
|
|
out_of_bounds = drone.move()
|
|
|
|
if out_of_bounds:
|
2022-07-26 16:27:55 -05:00
|
|
|
Drone.destory_all()
|
|
|
|
self.game_state = self.game_states['GameOver']
|
|
|
|
break
|
2022-07-28 16:00:29 -05:00
|
|
|
|
2022-07-26 16:27:55 -05:00
|
|
|
elif self.game_state == self.game_states['InterLevel']:
|
|
|
|
self.screen.ontimer(self.add_drone, 0)
|
|
|
|
self.game_state = self.game_states['Playing']
|
|
|
|
Drone.destory_all()
|
|
|
|
self.rocket.hideturtle()
|
|
|
|
if self.scoreboard.new_level():
|
|
|
|
self.rocket.showturtle()
|
|
|
|
self.game_state = self.game_states['Playing']
|
|
|
|
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
|
|
|
self.scoreboard.draw_scoreboard()
|
|
|
|
else:
|
|
|
|
self.game_state = self.game_states['GameOver']
|
2022-07-28 16:00:29 -05:00
|
|
|
|
2022-07-26 16:27:55 -05:00
|
|
|
elif self.game_state == self.game_states['GameOver']:
|
|
|
|
self.screen.ontimer(self.add_drone, 0)
|
|
|
|
Drone.destory_all()
|
|
|
|
self.rocket.hideturtle()
|
|
|
|
self.scoreboard.game_over()
|
2022-07-28 16:00:29 -05:00
|
|
|
|
2022-07-26 16:27:55 -05:00
|
|
|
elif self.game_state == self.game_states['Pause']:
|
|
|
|
pass
|
|
|
|
|
|
|
|
time.sleep(self.delay)
|
2022-07-26 14:12:41 -05:00
|
|
|
|
2022-07-21 16:36:45 -05:00
|
|
|
self.screen.exitonclick()
|
2022-07-21 16:07:13 -05:00
|
|
|
|
2022-07-21 16:36:45 -05:00
|
|
|
def add_drone(self):
|
2022-07-26 14:12:41 -05:00
|
|
|
if self.game_state != self.game_states['Playing']:
|
|
|
|
return
|
2022-07-26 16:27:55 -05:00
|
|
|
if self.scoreboard.drones_remaining > len(Drone.get_drones()) and len(
|
|
|
|
Drone.get_drones()) < self.scoreboard.max_drones:
|
2022-07-26 14:12:41 -05:00
|
|
|
Drone(self.scoreboard.drone_speed, self.x_min, self.x_max, self.y_min, self.y_max)
|
2022-07-21 16:36:45 -05:00
|
|
|
if not self.done:
|
2022-07-26 14:12:41 -05:00
|
|
|
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
|
|
|
|
|
|
|
def pause(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Does things when the game is paused.
|
|
|
|
:return: None
|
|
|
|
"""
|
2022-07-26 14:12:41 -05:00
|
|
|
if self.game_state == self.game_states['Playing']:
|
|
|
|
self.screen.ontimer(self.add_drone, 0)
|
|
|
|
self.game_state = self.game_states['Pause']
|
2022-07-28 14:55:15 -05:00
|
|
|
Audio.pause_music()
|
2022-07-26 14:12:41 -05:00
|
|
|
# Write to screen
|
|
|
|
# self.pause_screen.bgcolor('light blue')
|
2022-07-26 16:27:55 -05:00
|
|
|
self.rocket.hideturtle()
|
|
|
|
for drone in Drone.get_drones():
|
2022-07-26 14:12:41 -05:00
|
|
|
drone.hideturtle()
|
|
|
|
self.draw_pause_message()
|
|
|
|
|
|
|
|
else:
|
|
|
|
self.screen.ontimer(self.add_drone, self.scoreboard.spawn_time)
|
|
|
|
self.game_state = self.game_states['Playing']
|
2022-07-28 14:55:15 -05:00
|
|
|
Audio.unpause_music()
|
2022-07-26 16:27:55 -05:00
|
|
|
self.rocket.showturtle()
|
|
|
|
for drone in Drone.get_drones():
|
2022-07-26 14:12:41 -05:00
|
|
|
drone.showturtle()
|
|
|
|
self.pause_turtle.clear()
|
|
|
|
|
|
|
|
def draw_pause_message(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Draws the pause message to the screen.
|
|
|
|
:return: None
|
|
|
|
"""
|
2022-07-26 14:12:41 -05:00
|
|
|
self.pause_turtle.clear()
|
|
|
|
up = '⇑'
|
|
|
|
down = '⇓'
|
|
|
|
self.pause_turtle.color('black')
|
|
|
|
self.pause_turtle.goto(-0.5, 0.3)
|
2022-07-28 14:55:15 -05:00
|
|
|
self.pause_turtle.write(f'Music volume: {Audio.music_volume} of 100', align='left',
|
2022-07-26 14:12:41 -05:00
|
|
|
font=self.PAUSE_FONT)
|
|
|
|
self.pause_turtle.goto(-0.5, 0.2)
|
2022-07-28 14:55:15 -05:00
|
|
|
self.pause_turtle.write(f'Sfx volume: {Audio.sfx_volume} of 100', align='left', font=self.PAUSE_FONT)
|
2022-07-26 14:12:41 -05:00
|
|
|
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):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Increases the music volume.
|
|
|
|
:return: None
|
|
|
|
"""
|
|
|
|
Audio.change_music_volume(1)
|
2022-07-26 14:12:41 -05:00
|
|
|
self.draw_pause_message()
|
|
|
|
|
|
|
|
def music_down(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Decreases the music volume.
|
|
|
|
:return: None
|
|
|
|
"""
|
|
|
|
Audio.change_music_volume(-1)
|
2022-07-26 14:12:41 -05:00
|
|
|
self.draw_pause_message()
|
|
|
|
|
|
|
|
def sfx_up(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Increases the sfx volume.
|
|
|
|
:return: None
|
|
|
|
"""
|
|
|
|
Audio.change_sfx_volume(1)
|
2022-07-26 14:12:41 -05:00
|
|
|
self.draw_pause_message()
|
|
|
|
|
|
|
|
def sfx_down(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Decreases the sfx volume.
|
|
|
|
:return: None
|
|
|
|
"""
|
|
|
|
Audio.change_music_volume(-1)
|
2022-07-26 14:12:41 -05:00
|
|
|
self.draw_pause_message()
|
2022-07-21 16:07:13 -05:00
|
|
|
|
|
|
|
def quit(self):
|
2022-07-28 14:55:15 -05:00
|
|
|
"""
|
|
|
|
Quits the game.
|
|
|
|
:return: None
|
|
|
|
"""
|
2022-07-21 16:36:45 -05:00
|
|
|
self.screen.bye()
|
2022-07-26 16:27:55 -05:00
|
|
|
exit(0)
|