Compare commits

..

No commits in common. "401b2a8527c6bb1d562f2fb79b4cbcbe9e783bf3" and "639198e8de8bf8921dc5177cbc9ec45ad4be371d" have entirely different histories.

3 changed files with 52 additions and 192 deletions

View File

@ -10,12 +10,11 @@ from os.path import isfile, join
from inspect import isfunction
from xdg import BaseDirectory
from setproctitle import setproctitle
import pygame
import pyglet
import pyperclip
import random
import re
import requests
import textwrap
import webbrowser
# Global variable for speech provider
try:
@ -30,7 +29,6 @@ except ImportError:
print("No other speech providers found.")
exit()
import math
import numpy as np
import time
localConfig = configparser.ConfigParser()
@ -115,46 +113,20 @@ def read_config(readGlobal = False):
globalConfig.read_file(configfile)
except:
pass
def speak(text, interupt=True):
def speak(text, interupt = True):
if speechProvider == "speechd":
if interupt: spd.cancel()
if interupt == True: spd.cancel()
spd.say(text)
else:
if speechProvider == "accessible_output2":
s.speak(text, interrupt=True)
# Display the text on screen
screen = pygame.display.get_surface()
font = pygame.font.Font(None, 36)
# Wrap the text
maxWidth = screen.get_width() - 40 # Leave a 20-pixel margin on each side
wrappedText = textwrap.wrap(text, width=maxWidth // font.size('A')[0])
# Render each line
textSurfaces = [font.render(line, True, (255, 255, 255)) for line in wrappedText]
screen.fill((0, 0, 0)) # Clear screen with black
# Calculate total height of text block
totalHeight = sum(surface.get_height() for surface in textSurfaces)
# Start y-position (centered vertically)
currentY = (screen.get_height() - totalHeight) // 2
# Blit each line of text
for surface in textSurfaces:
textRect = surface.get_rect(center=(screen.get_width() // 2, currentY + surface.get_height() // 2))
screen.blit(surface, textRect)
currentY += surface.get_height()
pygame.display.flip()
def check_for_exit():
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
return True
return False
pygame.event.pump()
def exit_game():
if speechProvider == "speechd": spd.close()
pygame.mixer.music.stop()
pygame.quit()
exit()
# Close the pyglet window
pyglet.app.exit()
def initialize_gui(gameTitle):
# Check for, and possibly create, storm-games path
@ -169,101 +141,18 @@ def initialize_gui(gameTitle):
global gameName
gameName = gameTitle
setproctitle(str.lower(str.replace(gameTitle, " ", "")))
# start pygame
pygame.init()
# start the display (required by the event loop)
pygame.display.set_mode((800, 600))
pygame.display.set_caption(gameTitle)
# Set 32 channels for sound by default
pygame.mixer.pre_init(44100, -16, 2, 1024)
pygame.mixer.init()
pygame.mixer.set_num_channels(32)
# Reserve the cut scene channel
pygame.mixer.set_reserved(0)
# init pyglet window
window = pyglet.window.Window(500, 300, gameTitle)
# Load sounds from the sound directory and creates a list like {'bottle': 'bottle.ogg'}
try:
soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"])]
except Exception as e:
print("No sounds found.")
speak("No sounds found.", False)
#lets make a dict with pygame.mixer.Sound() objects {'bottle':<soundobject>}
soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"])]
# make a dict with pyglet media {'bottle':<soundobject>}
soundData = {}
for f in soundFiles:
soundData[f.split('.')[0]] = pygame.mixer.Sound("sounds/" + f)
soundData[f.split('.')[0]] = pyglet.media.load("sounds/" + f, streaming = False)
soundData['game-intro'].play()
time.sleep(soundData['game-intro'].get_length())
time.sleep(soundData['game-intro'].duration)
return soundData
def generate_tone(frequency, duration=0.1, sample_rate=44100, volume = 0.2):
t = np.linspace(0, duration, int(sample_rate * duration), False)
tone = np.sin(2 * np.pi * frequency * t)
stereo_tone = np.vstack((tone, tone)).T # Create a 2D array for stereo
stereo_tone = (stereo_tone * 32767).astype(np.int16)
stereo_tone = (stereo_tone * 32767 * volume).astype(np.int16) # Apply volume
stereo_tone = np.ascontiguousarray(stereo_tone) # Ensure C-contiguous array
return pygame.sndarray.make_sound(stereo_tone)
def x_powerbar():
clock = pygame.time.Clock()
screen = pygame.display.get_surface()
position = -50 # Start from the leftmost position
direction = 1 # Move right initially
barHeight = 20
while True:
frequency = 440 # A4 note
leftVolume = (50 - position) / 100
rightVolume = (position + 50) / 100
tone = generate_tone(frequency)
channel = tone.play()
channel.set_volume(leftVolume, rightVolume)
# Visual representation
screen.fill((0, 0, 0))
barWidth = screen.get_width() - 40 # Leave 20px margin on each side
pygame.draw.rect(screen, (100, 100, 100), (20, screen.get_height() // 2 - barHeight // 2, barWidth, barHeight))
markerPos = int(20 + (position + 50) / 100 * barWidth)
pygame.draw.rect(screen, (255, 0, 0), (markerPos - 5, screen.get_height() // 2 - barHeight, 10, barHeight * 2))
pygame.display.flip()
for event in pygame.event.get():
check_for_exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
channel.stop()
return position # This will return a value between -50 and 50
position += direction
if position > 50:
position = 50
direction = -1
elif position < -50:
position = -50
direction = 1
clock.tick(40) # Speed of bar
def y_powerbar():
clock = pygame.time.Clock()
screen = pygame.display.get_surface()
power = 0
direction = 1 # 1 for increasing, -1 for decreasing
barWidth = 20
while True:
frequency = 220 + (power * 5) # Adjust these values to change the pitch range
tone = generate_tone(frequency)
channel = tone.play()
# Visual representation
screen.fill((0, 0, 0))
barHeight = screen.get_height() - 40 # Leave 20px margin on top and bottom
pygame.draw.rect(screen, (100, 100, 100), (screen.get_width() // 2 - barWidth // 2, 20, barWidth, barHeight))
markerPos = int(20 + (100 - power) / 100 * barHeight)
pygame.draw.rect(screen, (255, 0, 0), (screen.get_width() // 2 - barWidth, markerPos - 5, barWidth * 2, 10))
pygame.display.flip()
for event in pygame.event.get():
check_for_exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
channel.stop()
return power
power += direction
if power >= 100 or power <= 0:
direction *= -1 # Reverse direction at limits
clock.tick(40)
def cut_scene(sounds, soundName):
pygame.event.clear()
pygame.mixer.stop()
@ -275,46 +164,45 @@ def cut_scene(sounds, soundName):
pygame.mixer.stop()
pygame.event.pump()
def calculate_volume_and_pan(player_pos, obj_pos):
distance = abs(player_pos - obj_pos)
max_distance = 12 # Maximum audible distance
if distance > max_distance:
return 0, 0, 0 # No sound if out of range
# Calculate volume (non-linear scaling for more noticeable changes)
volume = ((max_distance - distance) / max_distance) ** 1.5
# Determine left/right based on relative position
if player_pos < obj_pos:
# Object is to the right
left = max(0, 1 - (obj_pos - player_pos) / max_distance)
right = 1
elif player_pos > obj_pos:
# Object is to the left
left = 1
right = max(0, 1 - (player_pos - obj_pos) / max_distance)
def obj_play(sounds, soundName, playerPos, objPos):
distance = playerPos - objPos
if distance > 9 or distance < -9:
# The item is out of range, so play it at 0
left = 0
right = 0
elif distance == 0:
left = 0.9
right = 0.9
else:
# Player is on the object
left = right = 1
return volume, left, right
def obj_play(sounds, soundName, player_pos, obj_pos):
volume, left, right = calculate_volume_and_pan(player_pos, obj_pos)
if volume == 0:
return None # Don't play if out of range
# Play the sound on a new channel
angle = math.radians(distance * 5)
left = math.sqrt(2)/2.0 * (math.cos(angle) + math.sin(angle))
right = math.sqrt(2)/2.0 * (math.cos(angle) - math.sin(angle))
if left < 0: left *= -1
if right < 0: right *= -1
# x is the channel for the sound
x = sounds[soundName].play(-1)
# Apply the volume and pan
x.set_volume(volume * left, volume * right)
# Apply the position information to the channel
x.set_volume(left, right)
# return the channel so that it can be used in the update and stop functions.
return x
def obj_update(x, player_pos, obj_pos):
if x is None:
return None
volume, left, right = calculate_volume_and_pan(player_pos, obj_pos)
if volume == 0:
x.stop()
return None
# Apply the volume and pan
x.set_volume(volume * left, volume * right)
def obj_update(x, playerPos, objPos):
distance = playerPos - objPos
if distance > 9 or distance < -9:
left = 0
right = 0
elif distance == 0:
left = 0.9
right = 0.9
else:
angle = math.radians(distance * 5)
left = math.sqrt(2)/2.0 * (math.cos(angle) + math.sin(angle))
right = math.sqrt(2)/2.0 * (math.cos(angle) - math.sin(angle))
if left < 0: left *= -1
if right < 0: right *= -1
# Apply the position information to the channel
x.set_volume(left, right)
# return the channel
return x
def obj_stop(x):
@ -325,22 +213,6 @@ def obj_stop(x):
except:
return x
def play_ambiance(sounds, soundNames, probability, randomLocation = False):
# Check if any of the sounds in the list is already playing
for soundName in soundNames:
if pygame.mixer.find_channel(True) and pygame.mixer.find_channel(True).get_busy():
return
if random.randint(1, 100) > probability:
return
# Choose a random sound from the list
ambianceSound = random.choice(soundNames)
channel = sounds[ambianceSound].play()
if randomLocation and channel:
left_volume = random.random()
right_volume = random.random()
channel.set_volume(left_volume, right_volume)
return channel # Return the channel object for potential further manipulation
def play_random(sounds, soundName, pause = False, interrupt = False):
key = []
for i in sounds.keys():
@ -410,7 +282,7 @@ def learn_sounds(sounds):
loop = True
pygame.mixer.music.pause()
i = 0
soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"]) and (f.split('.')[0].lower() not in ["game-intro", "music_menu"]) and (not f.lower().startswith("_"))]
soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"]) and (f.split('.')[0].lower() not in ["game-intro", "music_menu"])]
# j keeps track of last spoken index so it isn't voiced on key up.
j = -1
while loop == True:
@ -445,12 +317,9 @@ def game_menu(sounds, *options):
if pygame.mixer.music.get_busy():
pygame.mixer.music.unpause()
else:
try:
pygame.mixer.music.load("sounds/music_menu.ogg")
pygame.mixer.music.set_volume(0.75)
pygame.mixer.music.play(-1)
except:
pass
pygame.mixer.music.load("sounds/music_menu.ogg")
pygame.mixer.music.set_volume(0.75)
pygame.mixer.music.play(-1)
i = 0
# j keeps track of last spoken index so it isn't voiced on key up.
j = -1

View File

@ -1,7 +0,0 @@
pygame>=2.0.0
pyperclip>=1.8.0
requests>=2.25.0
pyxdg>=0.27
setproctitle>=1.2.0
numpy>=1.19.0
accessible-output2>=0.14

View File

@ -1,2 +0,0 @@
-r requirements.txt
python-speechd>=0.11.1