Return to repo list

gatemender

Arcade game about fixing warp gates. LibreJam Dec 2020 Entry.
Return to HMagellan.com

commit 21b469649189d12116a93a113be150180d18a41a
parent 8704aab66254b5d325dd4cb73e8ab63c4b145bc0
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Mon, 14 Dec 2020 22:50:36 -0600

Added options menu and support for disabling music

Diffstat:
Adata/checked_checkbox.png | 0
Adata/empty_checkbox.png | 0
Mhs.json | 3+--
Msrc/constants.py | 6++++--
Msrc/game.py | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/sprites.py | 27+++++++++++++++++++++++++++
6 files changed, 93 insertions(+), 16 deletions(-)

diff --git a/data/checked_checkbox.png b/data/checked_checkbox.png Binary files differ. diff --git a/data/empty_checkbox.png b/data/empty_checkbox.png Binary files differ. diff --git a/hs.json b/hs.json @@ -1 +1 @@ -{"SCORES": [20, 500, 1000]}- \ No newline at end of file +{"SCORES": [500, 1000]} diff --git a/src/constants.py b/src/constants.py @@ -62,7 +62,9 @@ IMAGE_FILES = { "UI_Tray" : os.path.join("data", "hud_tray.png"), "Fix_Aura" : os.path.join("data", "fix_aura.png"), "Vortex" : os.path.join("data", "vortex.png"), - "Info" : os.path.join("data", "info.png") + "Info" : os.path.join("data", "info.png"), + "Empty_Checkbox" : os.path.join("data", "empty_checkbox.png"), + "Checked_Checkbox" : os.path.join("data", "checked_checkbox.png") } SOUND_FILES = { "Main_Menu_Music" : os.path.join("data", "title_screen.ogg"), @@ -79,4 +81,4 @@ SOUND_FILES = { } FONTPATH = os.path.join("data", "computerspeak03.ttf") MATERIALS = enum.Enum("MATERIALS", "Alpha Beta Gamma") -MODES = enum.Enum("MODES", "Menu Transition GameOver Play") +MODES = enum.Enum("MODES", "Menu Options Transition GameOver Play") diff --git a/src/game.py b/src/game.py @@ -18,6 +18,10 @@ class Game(object): self.just_pressed = False self.preserve_gate = False + # Options + self.sound_on = True + self.music_on = True + # Loading self.images = { i : pygame.image.load(IMAGE_FILES[i]).convert() for i in IMAGE_FILES } for i in self.images: @@ -54,9 +58,20 @@ class Game(object): self.instructions_button = self.font.render("INSTRUCTIONS", False, (255, 255, 255), (20, 20, 20)) self.instructions_button_rect = self.instructions_button.get_rect() self.instructions_button_rect.center = (self.screen_rect.centerx, self.screen_rect.centery + 50) - #self.options_button = self.font.render("OPTIONS", False, (255, 255, 255), (20, 20, 20)) - #self.options_button_rect = self.options_button.get_rect() - #self.options_button_rect.center = (self.screen_rect.centerx, self.screen_rect.centery + 90) + self.options_button = self.font.render("OPTIONS", False, (255, 255, 255), (20, 20, 20)) + self.options_button_rect = self.options_button.get_rect() + self.options_button_rect.center = (self.screen_rect.centerx, self.screen_rect.centery + 90) + self.music_on_label = self.font.render("ENABLE MUSIC", False, (255, 255, 255), (20, 20, 20)) + self.music_on_label_rect = self.music_on_label.get_rect() + self.music_on_label_rect.center = (self.screen_rect.centerx - 200, self.screen_rect.centery - 32) + self.sound_on_label = self.font.render("ENABLE SOUND", False, (255, 255, 255), (20, 20, 20)) + self.sound_on_label_rect = self.sound_on_label.get_rect() + self.sound_on_label_rect.center = (self.screen_rect.centerx - 200, self.screen_rect.centery + 32) + self.options_back_button = self.font.render("BACK", False, (255, 255, 255), (20, 20, 20)) + self.options_back_button_rect = self.options_back_button.get_rect() + self.options_back_button_rect.center = (self.screen_rect.centerx, self.screen_rect.centery + 180) + self.music_on_checkbox = None + self.sound_on_checkbox = None self.change_mode(MODES.Menu) def clear_level(self): @@ -148,28 +163,35 @@ class Game(object): self.screen_draw_group.add(self.alpha_icon, self.beta_icon, self.gamma_icon, self.hud_lives_icon) def change_mode(self, mode): + oldmode = self.mode self.mode = mode - pygame.mixer.stop() if mode == MODES.Play: self.load_level() self.play_sound("Game_Music", 0) elif mode == MODES.Transition: + pygame.mixer.stop() self.lives_text = self.font.render(" X " + str(self.lives), False, (255, 255, 255)) self.level_text = self.font.render("GATE " + str(self.level_factor), False, (255, 255, 255)) self.transition_timer = self.transition_timer_max elif mode == MODES.GameOver: + pygame.mixer.stop() self.transition_timer = self.transition_timer_max elif mode == MODES.Menu: - self.play_sound("Main_Menu_Music", 0) + if oldmode != MODES.Options: + self.play_sound("Main_Menu_Music", 0) self.lives = 2 self.score = 0 self.level_factor = 1 + elif mode == MODES.Options: + self.music_on_checkbox = sprites.Checkbox(self, self.images["Checked_Checkbox"], (self.screen_rect.centerx + 140, self.screen_rect.centery - 32), 0, self.music_on) + self.sound_on_checkbox = sprites.Checkbox(self, self.images["Checked_Checkbox"], (self.screen_rect.centerx + 140, self.screen_rect.centery + 32), 0, self.sound_on) - def play_sound(self, soundname, channel = None, concurrent = True, loops = -1): - if channel != None and not self.channels[channel].get_busy(): - self.channels[channel].play(self.sounds[soundname], loops) - elif concurrent or self.sounds[soundname].get_num_channels() == 0: - self.sounds[soundname].play(loops) + def play_sound(self, soundname, channel = None, concurrent = True, loops = -1, is_music = True): + if (is_music and self.music_on) or (not is_music and self.sound_on): + if channel != None and not self.channels[channel].get_busy(): + self.channels[channel].play(self.sounds[soundname], loops) + elif concurrent or self.sounds[soundname].get_num_channels() == 0: + self.sounds[soundname].play(loops) def render_hud(self): if self.mode == MODES.Play: @@ -231,7 +253,6 @@ class Game(object): self.keys[event.key] = False def handle_input(self): - if self.mode == MODES.Play: if self.ship != None and not self.ship.dead: self.ship.turning_left = self.keys[CONTROLS["TURN_LEFT_KEY"]] @@ -249,6 +270,8 @@ class Game(object): if not self.show_info: if self.start_button_rect.collidepoint(mousepos): self.change_mode(MODES.Transition) + elif self.options_button_rect.collidepoint(mousepos): + self.change_mode(MODES.Options) elif self.instructions_button_rect.collidepoint(mousepos): self.show_info = True self.just_pressed = True @@ -256,6 +279,25 @@ class Game(object): self.show_info = False else: self.just_pressed = False + elif self.mode == MODES.Options: + if pygame.mouse.get_pressed()[0]: + mousepos = pygame.mouse.get_pos() + if self.music_on_checkbox.rect.collidepoint(mousepos) and self.music_on_checkbox.check_cooldown == 0: + self.music_on_checkbox.be_checked() + if self.music_on_checkbox.checked: + self.music_on = True + self.play_sound("Main_Menu_Music", 0) + else: + self.music_on = False + pygame.mixer.stop() + elif self.sound_on_checkbox.rect.collidepoint(mousepos) and self.sound_on_checkbox.check_cooldown == 0: + self.sound_on_checkbox.be_checked() + if self.sound_on_checkbox.checked: + pass + else: + pass + elif self.options_back_button_rect.collidepoint(mousepos): + self.change_mode(MODES.Menu) def update_screen(self): if self.mode == MODES.Play: @@ -283,9 +325,9 @@ class Game(object): if not self.show_info: self.screen.blit(self.start_button, self.start_button_rect) self.screen.blit(self.instructions_button, self.instructions_button_rect) + self.screen.blit(self.options_button, self.options_button_rect) else: self.screen.blit(self.images["Info"], (0, 0)) - #self.screen.blit(self.options_button, self.options_button_rect) elif self.mode == MODES.Transition: self.screen.fill((0, 0, 0)) self.screen.blit(self.images["Ship"], (self.screen_rect.centerx - 30, 280)) @@ -294,6 +336,13 @@ class Game(object): elif self.mode == MODES.GameOver: self.screen.fill((0, 0, 0)) self.screen.blit(self.game_over_text, (100, 100)) + elif self.mode == MODES.Options: + self.screen.fill((0, 0, 0)) + self.screen.blit(self.music_on_label, self.music_on_label_rect) + self.screen.blit(self.sound_on_label, self.sound_on_label_rect) + self.screen.blit(self.options_back_button, self.options_back_button_rect) + self.music_on_checkbox.update(self.screen) + self.sound_on_checkbox.update(self.screen) pygame.display.update() def update_logic(self): diff --git a/src/sprites.py b/src/sprites.py @@ -378,3 +378,30 @@ class Vortex(CustomSprite): self.rotate(self.angle + 3) if self.passthru and self.passrect.colliderect(self.manager.ship.rect): self.manager.increment_level() + +class Checkbox(CustomSprite): + + def __init__(self, manager, image, pos, angle = 0, checked = False): + super().__init__(manager, image, pos, angle) + self.checked = checked + self.checked_image = manager.images["Checked_Checkbox"] + self.unchecked_image = manager.images["Empty_Checkbox"] + self.check_cooldown = 0 + if checked: + self.image = self.checked_image + else: + self.image = self.unchecked_image + + def be_checked(self): + if self.check_cooldown == 0: + if self.checked: + self.checked = False + self.image = self.unchecked_image + else: + self.checked = True + self.image = self.checked_image + self.check_cooldown = 40 + + def act(self): + if self.check_cooldown > 0: + self.check_cooldown -= 1