More effects and tweaks

This commit is contained in:
2026-03-12 08:50:21 -06:00
parent 009527dc89
commit f1845e044e
5 changed files with 64 additions and 27 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+64 -27
View File
@@ -4,6 +4,7 @@ import time
from typing import Any from typing import Any
import pygame import pygame
import multiprocessing import multiprocessing
import signal
class Game: class Game:
@@ -18,6 +19,8 @@ class Game:
# Defaults # Defaults
self.snake_length = 3 self.snake_length = 3
self.snake_speed = 7 self.snake_speed = 7
self.enable_effects = True
self.enable_music = False
# Snake and food characters # Snake and food characters
# ASCII Table: https://theasciicode.com.ar/ # ASCII Table: https://theasciicode.com.ar/
@@ -55,10 +58,8 @@ class Game:
# Get terminal (screen) height and width # Get terminal (screen) height and width
self.screen_height, self.screen_width = self.stdscr.getmaxyx() self.screen_height, self.screen_width = self.stdscr.getmaxyx()
# Start Music
self.queue.put('music.start')
# Show selcome page # Show selcome page
self.effect('start')
self.load_welcome() self.load_welcome()
# Ask for snake length # Ask for snake length
@@ -67,11 +68,21 @@ class Game:
# Ask for snake speed # Ask for snake speed
self.snake_speed = self.ask_question(f"Snake Speed (1 to 10, Default {self.snake_speed}): ", int, 7, 1, 10) self.snake_speed = self.ask_question(f"Snake Speed (1 to 10, Default {self.snake_speed}): ", int, 7, 1, 10)
# Ask for Music
self.enable_music = (self.ask_question(f"Turn on Music (y/N): ", str, 'N')).upper() == 'Y'
# Ask for Effects
self.enable_effects = (self.ask_question(f"Turn on Sound Effects (Y/n): ", str, 'Y')).upper() == 'Y'
# Debug Inputs # Debug Inputs
#self.print_center(f"Length: {self.snake_length}, Speed: {self.snake_speed}, Width: {self.screen_width}, Height: {self.screen_height}") #self.print_center(f"Length: {self.snake_length}, Speed: {self.snake_speed}, Width: {self.screen_width}, Height: {self.screen_height}")
#time.sleep(2) #time.sleep(2)
# Start Game!!! # Start music
if self.enable_music:
self.queue.put('music.start')
# Start game!!!
self.start_game() self.start_game()
@@ -181,19 +192,24 @@ class Game:
#exit('yyyyy') #exit('yyyyy')
#new_head = head #new_head = head
# Check collisions # Check wall collisions
if (new_head[0] in [0, self.screen_height - 1] or if (new_head[0] in [0, self.screen_height - 1] or
new_head[1] in [0, self.screen_width - 1] or new_head[1] in [0, self.screen_width - 1]):
new_head in snake): # Crashed into wall, quit
# Crashed into something, show quit screen self.effect('wall')
self.queue.put('effect.wall') break
# Check self collisions
if new_head in snake:
# Crashed into self, quit
self.effect('self')
break break
snake.insert(0, new_head) snake.insert(0, new_head)
# Check if snake ate food # Check if snake ate food
if snake[0] == food: if snake[0] == food:
self.queue.put('effect.eat') self.effect('eat')
score += 1 score += 1
food = get_new_food() food = get_new_food()
else: else:
@@ -219,6 +235,7 @@ class Game:
self.refresh_screen() self.refresh_screen()
# Game Over screen # Game Over screen
self.effect('over')
self.print_center(f"GAME OVER! SCORE: {score}", 0, self.colors['red']) self.print_center(f"GAME OVER! SCORE: {score}", 0, self.colors['red'])
self.print_center(f"(R)estart, or (Q)uit", 2, self.colors['green']) self.print_center(f"(R)estart, or (Q)uit", 2, self.colors['green'])
self.stdscr.nodelay(0) self.stdscr.nodelay(0)
@@ -241,7 +258,7 @@ class Game:
self.refresh_screen() self.refresh_screen()
def ask_question(self, question: str, value_type: Any, value_default: Any, value_min: int, value_max: int) -> Any: def ask_question(self, question: str, value_type: Any, value_default: Any, value_min: int = 0, value_max: int = 0) -> Any:
# Make the cursor visible # Make the cursor visible
curses.curs_set(1) curses.curs_set(1)
@@ -291,6 +308,9 @@ class Game:
self.print_center(f"ERROR: Must be an integer between {value_min} and {value_max}", 2, self.colors['red']) self.print_center(f"ERROR: Must be an integer between {value_min} and {value_max}", 2, self.colors['red'])
time.sleep(2) time.sleep(2)
self.ask_question(question, value_type, value_min, value_max) self.ask_question(question, value_type, value_min, value_max)
else:
if not answer:
answer = value_default
return answer return answer
@@ -322,6 +342,9 @@ class Game:
self.queue.put('quit') self.queue.put('quit')
exit() exit()
def effect(self, effect):
if self.enable_effects:
self.queue.put(effect)
def main(stdscr, queue): def main(stdscr, queue):
@@ -335,8 +358,10 @@ def sound_process(sound_queue):
effects = { effects = {
'eat': pygame.mixer.Sound('effects/bing.mp3'), 'eat': pygame.mixer.Sound('effects/bing.mp3'),
'wall': pygame.mixer.Sound('effects/cut.mp3'), 'wall': pygame.mixer.Sound('effects/wall.mp3'),
'self': pygame.mixer.Sound('effects/cut.mp3'), 'self': pygame.mixer.Sound('effects/cut.mp3'),
'over': pygame.mixer.Sound('effects/over.mp3'),
'start': pygame.mixer.Sound('effects/start2.mp3'),
} }
# Load sounds/music (adjust file paths as needed) # Load sounds/music (adjust file paths as needed)
@@ -348,33 +373,45 @@ def sound_process(sound_queue):
while True: while True:
if not sound_queue.empty(): if not sound_queue.empty():
command = sound_queue.get() command = sound_queue.get()
if command == 'effect.eat':
effects['eat'].play() # Play effects if requested
if command == 'effect.wall': for effect, sound in effects.items():
effects['wall'].play() if command == effect:
if command == 'effect.self': sound.play()
effects['self'].play()
elif command == 'music.start': # Play music
if command == 'music.start':
pygame.mixer.music.load(music_file) pygame.mixer.music.load(music_file)
pygame.mixer.music.set_volume(0.25) pygame.mixer.music.set_volume(0.25)
pygame.mixer.music.play(-1) # Play music indefinitely pygame.mixer.music.play(-1) # Play music indefinitely
elif command == 'music.stop': elif command == 'music.stop':
pygame.mixer.music.stop() pygame.mixer.music.stop()
# Quit came
elif command == 'quit': elif command == 'quit':
break break
time.sleep(0.1) # Small delay to prevent high CPU usage
# Small delay to prevent high CPU usage
time.sleep(0.1)
if __name__ == "__main__": if __name__ == "__main__":
# Create a queue for communication try:
queue = multiprocessing.Queue()
# Start the sound process # Handle CTRL+C (uvicore also handles with Aborted! but this catches other odd cases)
p = multiprocessing.Process(target=sound_process, args=(queue,)) signal.signal(signal.SIGINT, lambda sig, frame: exit())
p.start()
# Start curses game loop # Create a queue for communication
game = curses.wrapper(main, queue) queue = multiprocessing.Queue()
# Start the sound process
p = multiprocessing.Process(target=sound_process, args=(queue,))
p.start()
# Start curses game loop
game = curses.wrapper(main, queue)
except KeyboardInterrupt:
exit(0)