Skip to content

Commit

Permalink
Merge pull request #9 from bradwyatt/info-button
Browse files Browse the repository at this point in the history
Info button
  • Loading branch information
bradwyatt authored Apr 13, 2024
2 parents 4f29632 + 154f109 commit 6326625
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 36 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
__pycache__/
*.py[cod]

# Photoshop files
Sprites/Photoshop/

# C extensions
*.so

Expand Down
Binary file added Sprites/info_screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 74 additions & 36 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Propeller Platformer: Level Editor created by Brad Wyatt
"""
import random
import time
import sys
import os
import copy
Expand Down Expand Up @@ -125,6 +126,9 @@ def snap_to_grid(pos, screen_width, screen_height, grid_spacing, top_ui_boundary

return adjusted_x, adjusted_y

def InfoScreen(info_screen, screen):
screen.blit(info_screen, (0, 0)) # Display the Info Screen image

def draw_yellow_outline(screen, sprite_or_image, position, thickness=2):
# Determine if we have a sprite or a direct image
if hasattr(sprite_or_image, 'rect'):
Expand Down Expand Up @@ -287,28 +291,6 @@ def draw_grid(screen, grid_spacing, screen_width, screen_height, top_ui_boundary
pygame.draw.line(screen, grid_color, (horizontal_offset, y_position), (horizontal_offset + adjusted_width, y_position))


class InfoScreen():
def __init__(self, INFO_SCREEN, screen):
self.screen = screen
self.title = INFO_SCREEN
self.clock = pygame.time.Clock()
self.menuon = 2
self.main_loop()

def main_loop(self):
while self.menuon == 2:
self.clock.tick(60)
self.screen.blit(self.title, (0, 0))
info_events = pygame.event.get()
pygame.display.flip()
for info_event in info_events:
if info_event.type == QUIT:
pygame.quit()
sys.exit()
if info_event.type == KEYDOWN:
if info_event.key == K_ESCAPE:
self.menuon = 1
break

class ArrowButton(pygame.sprite.Sprite):
def __init__(self, play_sprites, images, direction):
Expand Down Expand Up @@ -490,6 +472,27 @@ def __init__(self, start_sprites, start_positions):
self.stand_spikes = StartStandSpikes(start_positions['stand_spikes'], IMAGES)
start_sprites.add(self.stand_spikes)

class NotificationManager:
def __init__(self):
self.messages = []

def add_message(self, text, duration, position, font, color=(255, 0, 0)):
""" Adds a message to the queue. Duration in seconds. """
message = {'text': text, 'duration': duration, 'position': position, 'font': font, 'color': color, 'start_time': pygame.time.get_ticks()}
self.messages.append(message)

def draw_messages(self, screen):
""" Draws all messages that are still active. """
current_time = pygame.time.get_ticks()
active_messages = []
for message in self.messages:
if current_time - message['start_time'] < message['duration'] * 1000: # Convert seconds to milliseconds
text_surface = message['font'].render(message['text'], True, message['color'])
text_rect = text_surface.get_rect(center=message['position'])
screen.blit(text_surface, text_rect)
active_messages.append(message) # Keep this message for the next frame
self.messages = active_messages # Only keep active messages

class GameState:
EDIT_MODE, PLAY_MODE = 0, 1
START_POSITIONS = {'player': (10, 4), 'wall': (270, 12), 'reverse_wall': (405, 12),
Expand Down Expand Up @@ -549,6 +552,9 @@ def __init__(self):
self.jumping = False

self.selected_object_type = None

self.notification_manager = NotificationManager()


def update_mouse_pos(self):
self.mouse_pos = pygame.mouse.get_pos()
Expand Down Expand Up @@ -635,19 +641,30 @@ def place_object_at_position(self, position, object_type):
PlacedStandSpikes(position, self.placed_sprites, IMAGES, self.rotate_button.current_stand_spikes_rotate)


def handle_events(self):
def handle_events(self, menu_on):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if self.info_button.rect.collidepoint(event.pos):
# Toggle info screen on/off
menu_on = 2 if menu_on == 1 else 1 # Toggle between game and info screen
else:
# Make sure info menu is closed if clicked elsewhere
if menu_on == 2:
menu_on = 1
elif event.type == pygame.KEYDOWN:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.key == pygame.K_SPACE:
# Toggle pause state
self.is_paused = not self.is_paused
print("Pause Toggled:", self.is_paused)
font = pygame.font.SysFont('Arial', 14)
pause_message = "Pause Toggled: " + str(self.is_paused)
self.notification_manager.add_message(pause_message, 1, (SCREEN_WIDTH-80, 100), font)
print(pause_message)
if self.game_mode == GameState.EDIT_MODE:
# Update dragging state with left click
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: # Left click hold down
Expand Down Expand Up @@ -840,8 +857,6 @@ def select_object_for_placement():
if self.restart_button.rect.collidepoint(self.mouse_pos):
if self.game_mode == self.PLAY_MODE:
restart_level(self)
if self.info_button.rect.collidepoint(self.mouse_pos):
MENUON = 2
if self.clear_button.rect.collidepoint(self.mouse_pos):
if self.game_mode == self.EDIT_MODE: #Editing mode
self.start = restart_start_objects(self.start, self.START_POSITIONS)
Expand All @@ -855,6 +870,7 @@ def select_object_for_placement():
if self.selected_object_type == "stand_spikes":
# Update the yellow outline spikes
self.start.dynamic_object_placeholder.start_sprite_with_yellow_outline(self.selected_object_type, self.start.stand_spikes.rect.topleft, IMAGES, self.rotate_button.current_stand_spikes_rotate)
return menu_on

def handle_mouse_down_events(self, event):
self.mouse_button_down = True
Expand Down Expand Up @@ -923,6 +939,8 @@ def toggle_eraser_mode(self):
self.eraser_button.toggle_eraser_button_image(self.eraser_mode_active)
def switch_to_edit_mode(self):
# Makes sure you are not in editing mode to enter editing mode
font = pygame.font.SysFont('Arial', 14)
self.notification_manager.add_message("Editing Mode Activated", 1, (SCREEN_WIDTH-80, 100), font)
print("Editing Mode Activated")
self.game_mode = self.EDIT_MODE
self.play_player.death_count = 0
Expand All @@ -944,6 +962,8 @@ def switch_to_play_mode(self):
# Makes clicking play again unclickable
self.game_mode = self.PLAY_MODE
self.play_edit_switch_button.image = self.play_edit_switch_button.game_mode_button(self.game_mode)
font = pygame.font.SysFont('Arial', 14)
self.notification_manager.add_message("Play Mode Activated", 1, (SCREEN_WIDTH-80, 100), font, (0, 255, 0))
print("Play Mode Activated")

#MUSIC_PLAYER = [MusicPlayer()]
Expand Down Expand Up @@ -973,6 +993,8 @@ def switch_to_play_mode(self):
self.right_arrow_button = ArrowButton(self.play_sprites, IMAGES, "right")
self.jump_button = JumpButton(self.play_sprites, IMAGES)
else:
font = pygame.font.SysFont('Arial', 14)
self.notification_manager.add_message("You need a character!", 3, (SCREEN_WIDTH-80, 100), font, (255, 255, 0))
print("You need a character!")
def edit_mode_function(self):
# DRAG- switch dynamic object placeholder with player sprite and vice versa
Expand Down Expand Up @@ -1096,7 +1118,12 @@ def play_mode_function(self):
self.play_door.image = self.play_door.open_or_close(self.play_player.score, PlayDiamonds.diamonds_list)
if pygame.sprite.collide_mask(self.play_player, self.play_door):
if self.play_player.score == len(PlayDiamonds.diamonds_list):
font = pygame.font.SysFont('Arial', 96)
self.notification_manager.add_message("You Win!", 3, (SCREEN_WIDTH//2, SCREEN_HEIGHT//2), font)
print("You Win!")
self.notification_manager.draw_messages(self.screen)
pygame.display.update()
time.sleep(3)
self.switch_to_edit_mode()
#music_player = [MusicPlayer()]

Expand Down Expand Up @@ -1294,10 +1321,13 @@ def main():
if not MOBILE_ACCESSIBILITY_MODE:
ROOT = tk.Tk()
ROOT.withdraw()

MENU_ON = 1

MENUON = 1
load_all_assets()



game_state = GameState()

#Fonts
Expand All @@ -1307,7 +1337,7 @@ def main():
#Backgrounds
START_MENU = pygame.image.load("sprites/start_menu.png").convert()
START_MENU = pygame.transform.scale(START_MENU, (SCREEN_WIDTH, SCREEN_HEIGHT))
INFO_SCREEN = pygame.image.load("sprites/info_screen.bmp").convert()
INFO_SCREEN = pygame.image.load("sprites/info_screen.png").convert()
INFO_SCREEN = pygame.transform.scale(INFO_SCREEN, (SCREEN_WIDTH, SCREEN_HEIGHT))

METROPOLIS_BACKGROUND = pygame.image.load("sprites/metropolis_background.png").convert()
Expand All @@ -1318,13 +1348,14 @@ def main():
clock.tick(FPS)
game_state.update_mouse_pos()

if MENUON == 1: # Initiate room
if MENU_ON == 1: # Normal game state

game_state.initiate_room()
game_state.handle_events()
MENU_ON = game_state.handle_events(MENU_ON)

if not game_state.is_paused:
# Only update game logic if the game is not paused
game_state.handle_events()
game_state.handle_events(MENU_ON)
if game_state.game_mode == GameState.EDIT_MODE:
game_state.edit_mode_function()
game_state.start_sprites.update()
Expand All @@ -1338,7 +1369,7 @@ def main():

SCREEN.blit(METROPOLIS_BACKGROUND, (0, 0))


game_state.game_mode_sprites.draw(SCREEN)
if game_state.game_mode == game_state.EDIT_MODE: #Only draw placed sprites in editing mode
if game_state.grid_button.grid_on_var:
Expand All @@ -1354,17 +1385,24 @@ def main():
sprite_name, pos = GameState.DYNAMIC_OBJECT_PLACEHOLDER_YELLOW_OUTLINE_OBJ_AND_POS
draw_yellow_outline(SCREEN, IMAGES[sprite_name], pos, thickness=1)


elif game_state.game_mode == game_state.PLAY_MODE: #Only draw play sprites in play mode
if game_state.eraser_mode_active:
game_state.toggle_eraser_mode()
game_state.play_sprites.draw(SCREEN)
DEATH_COUNT_TEXT = FONT_ARIAL.render("Deaths: " + str(game_state.play_player.death_count), 1, (0, 0, 0))
game_state.notification_manager.draw_messages(game_state.screen)
SCREEN.blit(DEATH_COUNT_TEXT, ((SCREEN_WIDTH/2-50), 5))


pygame.display.update()
elif MENU_ON == 2:
InfoScreen(INFO_SCREEN, SCREEN) # Display the Info Screen
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
# Click anywhere to return to the game
MENU_ON = 1

pygame.display.update()
elif MENUON == 2: # Info SCREEN in a WHILE loop
InfoScreen(INFO_SCREEN, SCREEN)
MENUON = 1

if __name__ == "__main__":
main()
Binary file removed sprites/info_screen.bmp
Binary file not shown.

0 comments on commit 6326625

Please sign in to comment.