Compare commits

5 Commits

Author SHA1 Message Date
b61b35dfc9 More effects and tweaks 2026-03-12 11:53:40 -06:00
863fc06a1b More effects and tweaks 2026-03-12 10:53:06 -06:00
eebdc979de More effects and tweaks 2026-03-12 08:56:59 -06:00
f1845e044e More effects and tweaks 2026-03-12 08:50:21 -06:00
009527dc89 Add music and effects 2026-03-12 07:46:27 -06:00
12 changed files with 259 additions and 39 deletions

BIN
effects/bing.mp3 Normal file

Binary file not shown.

BIN
effects/cut.mp3 Normal file

Binary file not shown.

BIN
effects/over.mp3 Normal file

Binary file not shown.

BIN
effects/start.mp3 Normal file

Binary file not shown.

BIN
effects/start2.mp3 Normal file

Binary file not shown.

BIN
effects/wall.mp3 Normal file

Binary file not shown.

BIN
music/QonsVivaEveryone.mp3 Executable file

Binary file not shown.

BIN
music/bubbles.ogg Normal file

Binary file not shown.

BIN
music/s.mp3 Executable file

Binary file not shown.

76
poetry.lock generated Normal file
View File

@@ -0,0 +1,76 @@
# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand.
[[package]]
name = "pygame"
version = "2.6.1"
description = "Python Game Development"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "pygame-2.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9beeb647e555afb5657111fa83acb74b99ad88761108eaea66472e8b8547b55b"},
{file = "pygame-2.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:10e3d2a55f001f6c0a6eb44aa79ea7607091c9352b946692acedb2ac1482f1c9"},
{file = "pygame-2.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:816e85000c5d8b02a42b9834f761a5925ef3377d2924e3a7c4c143d2990ce5b8"},
{file = "pygame-2.6.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a78fd030d98faab4a8e27878536fdff7518d3e062a72761c552f624ebba5a5f"},
{file = "pygame-2.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da3ad64d685f84a34ebe5daacb39fff14f1251acb34c098d760d63fee768f50c"},
{file = "pygame-2.6.1-cp310-cp310-win32.whl", hash = "sha256:9dd5c054d4bd875a8caf978b82672f02bec332f52a833a76899220c460bb4b58"},
{file = "pygame-2.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:00827aba089355925902d533f9c41e79a799641f03746c50a374dc5c3362e43d"},
{file = "pygame-2.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:20349195326a5e82a16e351ed93465a7845a7e2a9af55b7bc1b2110ea3e344e1"},
{file = "pygame-2.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f3935459109da4bb0b3901da9904f0a3e52028a3332a355d298b1673a334cf21"},
{file = "pygame-2.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31dbdb5d0217f32764797d21c2752e258e5fb7e895326538d82b5f75a0cd856"},
{file = "pygame-2.6.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:173badf82fa198e6888017bea40f511cb28e69ecdd5a72b214e81e4dcd66c3b1"},
{file = "pygame-2.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce8cc108b92de9b149b344ad2e25eedbe773af0dc41dfb24d1f07f679b558c60"},
{file = "pygame-2.6.1-cp311-cp311-win32.whl", hash = "sha256:811e7b925146d8149d79193652cbb83e0eca0aae66476b1cb310f0f4226b8b5c"},
{file = "pygame-2.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:91476902426facd4bb0dad4dc3b2573bc82c95c71b135e0daaea072ed528d299"},
{file = "pygame-2.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4ee7f2771f588c966fa2fa8b829be26698c9b4836f82ede5e4edc1a68594942e"},
{file = "pygame-2.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8040ea2ab18c6b255af706ec01355c8a6b08dc48d77fd4ee783f8fc46a843bf"},
{file = "pygame-2.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47a6938de93fa610accd4969e638c2aebcb29b2fca518a84c3a39d91ab47116"},
{file = "pygame-2.6.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33006f784e1c7d7e466fcb61d5489da59cc5f7eb098712f792a225df1d4e229d"},
{file = "pygame-2.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1206125f14cae22c44565c9d333607f1d9f59487b1f1432945dfc809aeaa3e88"},
{file = "pygame-2.6.1-cp312-cp312-win32.whl", hash = "sha256:84fc4054e25262140d09d39e094f6880d730199710829902f0d8ceae0213379e"},
{file = "pygame-2.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:3a9e7396be0d9633831c3f8d5d82dd63ba373ad65599628294b7a4f8a5a01a65"},
{file = "pygame-2.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6039f3a55d800db80e8010f387557b528d34d534435e0871326804df2a62f2"},
{file = "pygame-2.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2a3a1288e2e9b1e5834e425bedd5ba01a3cd4902b5c2bff8ed4a740ccfe98171"},
{file = "pygame-2.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27eb17e3dc9640e4b4683074f1890e2e879827447770470c2aba9f125f74510b"},
{file = "pygame-2.6.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c1623180e70a03c4a734deb9bac50fc9c82942ae84a3a220779062128e75f3b"},
{file = "pygame-2.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef07c0103d79492c21fced9ad68c11c32efa6801ca1920ebfd0f15fb46c78b1c"},
{file = "pygame-2.6.1-cp313-cp313-win32.whl", hash = "sha256:3acd8c009317190c2bfd81db681ecef47d5eb108c2151d09596d9c7ea9df5c0e"},
{file = "pygame-2.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:813af4fba5d0b2cb8e58f5d95f7910295c34067dcc290d34f1be59c48bd1ea6a"},
{file = "pygame-2.6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:56ffca6059b165bbf64f4b4be23b8068f6a0e220780e4f96ec0bb5ac3c63ec39"},
{file = "pygame-2.6.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bede70ec708057e305815d6546012669226d1d80566785feca9b044216062e7"},
{file = "pygame-2.6.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f84f15d146d6aa93254008a626c56ef96fed276006202881a47b29757f0cd65a"},
{file = "pygame-2.6.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14f9dda45469b254c0f15edaaeaa85d2cc072ff6a83584a265f5d684c7f7efd8"},
{file = "pygame-2.6.1-cp36-cp36m-win32.whl", hash = "sha256:28b43190436037e428a5be28fc80cf6615304fd528009f2c688cc828f4ff104b"},
{file = "pygame-2.6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:a4b8f04fceddd9a3ac30778d11f0254f59efcd1c382d5801271113cea8b4f2f3"},
{file = "pygame-2.6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a620883d589926f157b8f1d1f543183ac52e5c30507dea445e3927ae0bee1c54"},
{file = "pygame-2.6.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b46e68cd168f44d0224c670bb72186688fc692d7079715f79d04096757d703d0"},
{file = "pygame-2.6.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0b11356ac96261162d54a2c2b41a41978f00525631b01ec9c4fe26b01c66595"},
{file = "pygame-2.6.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:325a84d072d52e3c2921eff02f87c6a74b7e77d71db3bdf53801c6c975f1b6c4"},
{file = "pygame-2.6.1-cp37-cp37m-win32.whl", hash = "sha256:2a615d78b2364e86f541458ff41c2a46181b9a1e9eabd97b389282fdf04efbb3"},
{file = "pygame-2.6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:94afd1177680d92f9214c54966ad3517d18210c4fbc5d84a0192d218e93647e0"},
{file = "pygame-2.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97ac4e13847b6b293ecaffa5ffce9886c98d09c03309406931cc592f0cea6366"},
{file = "pygame-2.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d1a7f2b66ac2e4c9583b6d4c6d6f346fb10a3392c04163f537061f86a448ed5c"},
{file = "pygame-2.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac3f033d2be4a9e23660a96afe2986df3a6916227538a6a0061bc218c5088507"},
{file = "pygame-2.6.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1bf7ab5311bbced70320f1a56701650b4c18231343ae5af42111eea91e0949a"},
{file = "pygame-2.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21160d9093533eb831f1b708e630706e5ac16b30750571ec27bc3b8364814f38"},
{file = "pygame-2.6.1-cp38-cp38-win32.whl", hash = "sha256:7bffdd3eaf394d9645331d1c3a5df9d782ebcc3c5a78f3b657c7879a828dd111"},
{file = "pygame-2.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:818b4eaec9c4acb6ac64805d4ca8edd4062bebca77bd815c18739fe2842c97e9"},
{file = "pygame-2.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15efaa11a80a65dd589a95bebe812fa5bfc7e14946b638a424c5bd9ac6cca1a4"},
{file = "pygame-2.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:481cfe1bdbb7fe00acc5950c494c26f00240888619bdc396fc8c39a734797432"},
{file = "pygame-2.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d09fd950725d187aa5207c0cb8eb9ab0d2f8ce9ab8d189c30eeb470e71b617e"},
{file = "pygame-2.6.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:163e66de169bd5670c86e27d0b74aad0d2d745e3b63cf4e7eb5b2bff1231ca8d"},
{file = "pygame-2.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6e8d0547f30ddc845f4fd1e33070ef548233ad0dbf21f7ecea768883d1bbdc"},
{file = "pygame-2.6.1-cp39-cp39-win32.whl", hash = "sha256:d29eb9a93f12aa3d997b6e3c447ac85b2a4b142ab2548441523a8fcf5e216042"},
{file = "pygame-2.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:6582aa71a681e02e55d43150a9ab41394e6bf4d783d2962a10aea58f424be060"},
{file = "pygame-2.6.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:4a8ea113b1bf627322a025a1a5a87e3818a7f55ab3a4077ff1ae5c8c60576614"},
{file = "pygame-2.6.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b7f9f8e6f76de36f4725175d686601214af362a4f30614b4dae2240198e72e6f"},
{file = "pygame-2.6.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bbb7167c92103a2091366e9af26d4914ba3776666e8677d3c93551353fffa626"},
{file = "pygame-2.6.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17498a2b043bc0e795faedef1b081199c688890200aef34991c1941caa2d2c89"},
{file = "pygame-2.6.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7103c60939bbc1e05cfc7ba3f1d2ad3bbf103b7828b82a7166a9ab6f51950146"},
{file = "pygame-2.6.1.tar.gz", hash = "sha256:56fb02ead529cee00d415c3e007f75e0780c655909aaa8e8bf616ee09c9feb1f"},
]
[metadata]
lock-version = "2.1"
python-versions = ">=3.12"
content-hash = "917fe230b6bc55713d196c895d8f271ff41f72f95e157ec5e702612513206263"

17
pyproject.toml Normal file
View File

@@ -0,0 +1,17 @@
[project]
name = "snake"
version = "0.1.0"
description = "Snake"
authors = [
{name = "Matthew Reschke",email = "mail@mreschke.com"}
]
license = {text = "MIT"}
requires-python = ">=3.12"
dependencies = [
"pygame (>=2.6.1,<3.0.0)"
]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

205
snake.py
View File

@@ -2,17 +2,26 @@ import curses
import random import random
import time import time
from typing import Any from typing import Any
import pygame
import multiprocessing
import signal
class Game: class Game:
def __init__(self, stdscr): def __init__(self, stdscr, queue):
# Get curses standard screen # Get curses standard screen
self.stdscr = stdscr self.stdscr = stdscr
# Multiprocessing Queue
self.queue = queue
# 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
self.music_started_once = False
# Snake and food characters # Snake and food characters
# ASCII Table: https://theasciicode.com.ar/ # ASCII Table: https://theasciicode.com.ar/
@@ -47,10 +56,13 @@ class Game:
curses.init_pair(self.colors['white'], curses.COLOR_WHITE, curses.COLOR_BLACK) # Score/Text curses.init_pair(self.colors['white'], curses.COLOR_WHITE, curses.COLOR_BLACK) # Score/Text
self.stdscr.bkgd(' ', curses.color_pair(self.colors['white'])) self.stdscr.bkgd(' ', curses.color_pair(self.colors['white']))
curses.set_escdelay(1)
# 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()
# Show selcome page # Show selcome page
self.effect('start')
self.load_welcome() self.load_welcome()
# Ask for snake length # Ask for snake length
@@ -59,11 +71,26 @@ 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:
if self.music_started_once:
self.music_unpause()
else:
self.music_start()
else:
self.music_pause()
# Start game!!!
self.start_game() self.start_game()
@@ -76,27 +103,10 @@ class Game:
# Calculate snake speed # Calculate snake speed
wait_for_input_ms = { wait_for_input_ms = {
1: 250, 1: 250, 2: 225, 3: 200,
2: 225, 4: 175, 5: 150, 6: 125,
3: 200, 7: 100, 8: 75, 9: 50, 10: 25
4: 175,
5: 150,
6: 125,
7: 100,
8: 75,
9: 50,
10: 25
} }
# if self.snake_speed == 1: wait_for_input_ms = 250
# if self.snake_speed == 2: wait_for_input_ms = 225
# if self.snake_speed == 3: wait_for_input_ms = 200
# if self.snake_speed == 4: wait_for_input_ms = 175
# if self.snake_speed == 5: wait_for_input_ms = 150
# if self.snake_speed == 6: wait_for_input_ms = 125
# if self.snake_speed == 7: wait_for_input_ms = 100
# if self.snake_speed == 8: wait_for_input_ms = 75
# if self.snake_speed == 9: wait_for_input_ms = 50
# if self.snake_speed == 10: wait_for_input_ms = 25
self.stdscr.timeout(wait_for_input_ms[self.snake_speed]) self.stdscr.timeout(wait_for_input_ms[self.snake_speed])
# Ensure window is large enough # Ensure window is large enough
@@ -138,23 +148,36 @@ class Game:
# RIGHT # RIGHT
elif next_key == curses.KEY_RIGHT and key != curses.KEY_LEFT: elif next_key == curses.KEY_RIGHT and key != curses.KEY_LEFT:
key = next_key key = next_key
# (P)ause # ESCAPE Menu
elif next_key == ord('p'): elif next_key == 27:
previous_key = key previous_key = key
self.print_center("Game Paused. Press P to Resume.") if self.enable_music: self.music_pause()
self.print_center(f"GAME PAUSED...", 0, self.colors['red'])
self.print_center(f"ESC Resume, (R)estart, (Q)uit, (M)enu", 2, self.colors['green'])
while True: while True:
key = self.stdscr.getch() key = self.stdscr.getch()
if key == ord('p'): if key == 27:
break break
elif key == ord('r'):
if self.enable_music: self.music_unpause()
self.start_game()
return
elif key == ord('q'):
self.exit_game()
elif key == ord('m'):
self.load()
return
# Resume
key = previous_key key = previous_key
if self.enable_music: self.music_unpause()
continue continue
# (R)estart # (R)estart
elif next_key == ord('r'): elif next_key == ord('r'):
self.start_game() self.start_game()
return return
# (Q)uit # # (Q)uit
elif next_key == ord('q'): # elif next_key == ord('q'):
break # break
# Calculate new head # Calculate new head
head = snake[0] head = snake[0]
@@ -173,17 +196,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')
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.effect('eat')
score += 1 score += 1
food = get_new_food() food = get_new_food()
else: else:
@@ -209,17 +239,23 @@ 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, (Q)uit, (M)enu", 2, self.colors['green'])
self.stdscr.nodelay(0) self.stdscr.nodelay(0)
#if self.enable_music: self.music_pause()
while True: while True:
key = self.stdscr.getch() key = self.stdscr.getch()
if key == ord('r'): if key == ord('r'):
#if self.enable_music: self.music_unpause()
self.start_game() self.start_game()
return return
elif key == ord('q'): elif key == ord('q'):
# Game over, exit app! # Game over, exit app!
exit() self.exit_game()
elif key == ord('m'):
self.load()
return
def print_center(self, value, y_offset = 0, color = 3): def print_center(self, value, y_offset = 0, color = 3):
@@ -231,7 +267,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)
@@ -281,6 +317,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
@@ -308,12 +347,100 @@ class Game:
def refresh_screen(self): def refresh_screen(self):
self.stdscr.refresh() self.stdscr.refresh()
def exit_game(self):
self.queue.put('quit')
exit()
def effect(self, effect):
if self.enable_effects:
self.queue.put(effect)
def music_start(self):
self.music_started_once = True
self.queue.put('music.start')
def music_stop(self):
self.queue.put('music.stop')
def music_pause(self):
self.queue.put('music.pause')
def music_unpause(self):
self.queue.put('music.unpause')
def main(stdscr): def main(stdscr, queue):
game = Game(stdscr) game = Game(stdscr, queue)
game.load() game.load()
def sound_process(sound_queue):
# Initialize pygame mixer in the new process
pygame.mixer.init()
effects = {
'eat': pygame.mixer.Sound('effects/bing.mp3'),
'wall': pygame.mixer.Sound('effects/wall.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)
# Use .wav or .ogg for better compatibility
#effect = pygame.mixer.Sound('effects/bing.mp3')
#music_file = 'music/QonsVivaEveryone.mp3'
#music_file = 'music/Aztec.mp3'
#music_file = 'music/Snug_Neon_Artery.mp3'
music_file = 'music/bubbles.ogg'
#music_file = 'music/s.mp3'
while True:
if not sound_queue.empty():
command = sound_queue.get()
# Play effects if requested
for effect, sound in effects.items():
if command == effect:
sound.play()
# Play music
if command == 'music.start':
pygame.mixer.music.load(music_file)
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play(-1) # Play music indefinitely
elif command == 'music.stop':
pygame.mixer.music.stop()
elif command == 'music.pause':
pygame.mixer.music.pause();
elif command == 'music.unpause':
pygame.mixer.music.unpause();
# Quit came
elif command == 'quit':
break
# Small delay to prevent high CPU usage
time.sleep(0.1)
if __name__ == "__main__": if __name__ == "__main__":
game = curses.wrapper(main)
try:
# Handle CTRL+C (uvicore also handles with Aborted! but this catches other odd cases)
signal.signal(signal.SIGINT, lambda sig, frame: exit())
# Create a queue for communication
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)