From 68ad08be464289821b986787437624f85d767709 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Tue, 15 Sep 2020 19:35:59 -0400 Subject: [PATCH] moved the libstormgames.py file to __init__.py so you can just import libstormgames. --- __init__.py | 389 +++++++++++++++++++++++++++++++++++++++++++++++ libstormgames.py | 389 ----------------------------------------------- 2 files changed, 389 insertions(+), 389 deletions(-) mode change 100644 => 100755 __init__.py delete mode 100755 libstormgames.py diff --git a/__init__.py b/__init__.py old mode 100644 new mode 100755 index e69de29..9353949 --- a/__init__.py +++ b/__init__.py @@ -0,0 +1,389 @@ +#!/bin/python +# -*- coding: utf-8 -*- +"""Standard initializations and functions shared by all games.""" + +from sys import exit +import configparser +import os +from os import listdir +from os.path import isfile, join +from inspect import isfunction +from xdg import BaseDirectory +from setproctitle import setproctitle +import pygame +import pyperclip +import random +import re +import requests +import webbrowser +# Global variable for speech provider +try: + import speechd + spd = speechd.Client() + speechProvider = "speechd" +except ImportError: + import accessible_output2.outputs.auto + s = accessible_output2.outputs.auto.Auto() + speechProvider = "accessible_output2" +except ImportError: + print("No other speech providers found.") + exit() +import math +import time + +localConfig = configparser.ConfigParser() +globalConfig = configparser.ConfigParser() + +class scoreboard(): + 'Handles scores and top 10' + + def __init__(self, startingScore = 0): + read_config() + try: + localConfig.add_section("scoreboard") + except: + pass + self.score = startingScore + self.oldScores = [] + for i in range(1, 11): + try: + self.oldScores.insert(i - 1, localConfig.getint("scoreboard", str(i))) + except: + pass + self.oldScores.insert(i - 1, 0) + for i in range(1, 11): + if self.oldScores[i - 1] == None: + self.oldScores[i - 1] = 0 + + def __del__(self): + self.Update_Scores() + try: + write_config() + except: + pass + + def Decrease_Score(self, points = 1): + self.score -= points + + def Get_High_Score(self, position = 1): + return self.oldScores[position - 1] + + def Get_Score(self): + return self.score + + def Increase_Score(self, points = 1): + self.score += points + + def New_High_Score(self): + for i, j in enumerate(self.oldScores): + if self.score > j: return i + 1 + return None + + def Update_Scores(self): + # Update the scores + for i, j in enumerate(self.oldScores): + if self.score > j: + self.oldScores.insert(i, self.score) + break + # Only keep the top 10 scores. + self.oldScores = self.oldScores[:10] + # Update the scoreboard section of the games config file. + for i, j in enumerate(self.oldScores): + localConfig.set("scoreboard", str(i + 1), str(j)) + + +def write_config(writeGlobal = False): + if writeGlobal == False: + with open(gamePath + "/config.ini", 'w') as configfile: + localConfig.write(configfile) + else: + with open(globalPath + "/config.ini", 'w') as configfile: + globalConfig.write(configfile) + +def read_config(readGlobal = False): + if readGlobal == False: + try: + with open(gamePath + "/config.ini", 'r') as configfile: + localConfig.read_file(configfile) + except: + pass + else: + try: + with open(globalPath + "/config.ini", 'r') as configfile: + globalConfig.read_file(configfile) + except: + pass + +def speak(text, interupt = True): + if speechProvider == "speechd": + if interupt == True: spd.cancel() + spd.say(text) + else: + if speechProvider == "accessible_output2": + s.speak(text, interrupt=True) + + +def exit_game(): + if speechProvider == "speechd": spd.close() + pygame.mixer.music.stop() + pygame.quit() + exit() + +def initialize_gui(gameTitle): + # Check for, and possibly create, storm-games path + global globalPath + global gamePath + globalPath = BaseDirectory.xdg_config_home + "/storm-games" + gamePath = globalPath + "/" + str.lower(str.replace(gameTitle, " ", "-")) + if not os.path.exists(gamePath): os.makedirs(gamePath) + # Seed the random generator to the clock + random.seed() + # Set game's name + 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((320, 200)) + pygame.display.set_caption(gameTitle) + # Set 32 channels for sound by default + pygame.mixer.init() + pygame.mixer.set_num_channels(32) + # Reserve the cut scene channel + pygame.mixer.set_reserved(0) + # Load sounds from the sound directory and creates a list like that {'bottle': 'bottle.ogg'} + soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"])] + #lets make a dict with pygame.mixer.Sound() objects {'bottle':} + soundData = {} + for f in soundFiles: + soundData[f.split('.')[0]] = pygame.mixer.Sound("sounds/" + f) + soundData['game-intro'].play() + time.sleep(soundData['game-intro'].get_length()) + return soundData + +def cut_scene(sounds, soundName): + pygame.event.clear() + pygame.mixer.stop() + c = pygame.mixer.Channel(0) + c.play(sounds[soundName]) + while pygame.mixer.get_busy(): + event = pygame.event.poll() + if event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_RETURN, pygame.K_SPACE]: + pygame.mixer.stop() + pygame.event.pump() + +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: + 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 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, 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): + # Tries to stop a playing object channel + try: + x.stop() + return None + except: + return x + +def play_random(sounds, soundName, pause = False, interrupt = False): + key = [] + for i in sounds.keys(): + if re.match("^" + soundName + ".*", i): + key.append(i) + randomKey = random.choice(key) + if interrupt == False: + sounds[randomKey].play() + else: + cut_scene(sounds, randomKey) + # Cut scenes override the pause option + return + if pause == True: + time.sleep(sounds[randomKey].get_length()) + +def instructions(): + # Read in the instructions file + try: + with open('files/instructions.txt', 'r') as f: + info = f.readlines() + except: + info = ["Instructions file is missing."] + display_text(info) + +def credits(): + # Read in the credits file. + try: + with open('files/credits.txt', 'r') as f: + info = f.readlines() + # Add the header + info.insert(0, gameName + ": brought to you by Storm Dragon") + except: + info = ["Credits file is missing."] + display_text(info) + +def display_text(text): + i = 0 + text.insert(0, "Press space to read the whole text. Use up and down arrows to navigate the text line by line. Press c to copy the current line to the clipboard or t to copy the entire text. Press enter or escape when you are done reading.") + text.append("End of text.") + speak(text[i]) + while True: + event = pygame.event.wait() + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: return + if event.key == pygame.K_DOWN and i < len(text) - 1: i = i + 1 + if event.key == pygame.K_UP and i > 0: i = i - 1 + if event.key == pygame.K_SPACE: + speak(' '.join(text[1:])) + else: + speak(text[i]) + if event.key == pygame.K_c: + try: + pyperclip.copy(text[i]) + speak("Copied " + text[i] + " to the clipboard.") + except: + speak("Failed to copy the text to the clipboard.") + if event.key == pygame.K_t: + try: + pyperclip.copy(' '.join(text[1:-1])) + speak("Copied entire message to the clipboard.") + except: + speak("Failed to copy the text to the clipboard.") + event = pygame.event.clear() + time.sleep(0.001) + +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"])] + # j keeps track of last spoken index so it isn't voiced on key up. + j = -1 + while loop == True: + if i != j: + speak(soundFiles[i][:-4]) + j = i + event = pygame.event.wait() + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: return "menu" + if event.key == pygame.K_DOWN and i < len(soundFiles) - 1: + pygame.mixer.stop() + i = i + 1 + if event.key == pygame.K_UP and i > 0: + pygame.mixer.stop() + i = i - 1 + if event.key == pygame.K_RETURN: + try: + soundName = soundFiles[i][:-4] + pygame.mixer.stop() + sounds[soundName].play() + continue + except: + j = -1 + speak("Could not play sound.") + continue + event = pygame.event.clear() + time.sleep(0.001) + +def game_menu(sounds, *options): + loop = True + pygame.mixer.stop() + if pygame.mixer.music.get_busy(): + pygame.mixer.music.unpause() + else: + 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 + while loop == True: + if i != j: + speak(options[i]) + j = i + event = pygame.event.wait() + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: exit_game() + if event.key == pygame.K_DOWN and i < len(options) - 1: + i = i + 1 + try: + sounds['menu-move'].play() + except: + pass + if options[i] != "donate": pygame.mixer.music.unpause() + if event.key == pygame.K_UP and i > 0: + i = i - 1 + try: + sounds['menu-move'].play() + except: + pass + if options[i] != "donate": pygame.mixer.music.unpause() + if event.key == pygame.K_HOME and i != 0: + i = 0 + try: + sounds['menu-move'].play() + except: + pass + if options[i] != "donate": pygame.mixer.music.unpause() + if event.key == pygame.K_END and i != len(options) - 1: + i = len(options) -1 + try: + sounds['menu-move'].play() + except: + pass + if options[i] != "donate": pygame.mixer.music.unpause() + if event.key == pygame.K_RETURN: + try: + j = -1 + try: + sounds['menu-select'].play() + time.sleep(sounds['menu-select'].get_length()) + except: + pass + eval(options[i] + "()") + continue + except: + j = -1 + return options[i] + continue + event = pygame.event.clear() + time.sleep(0.001) + +def donate(): + pygame.mixer.music.pause() + webbrowser.open('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=stormdragon2976@gmail.com&lc=US&item_name=Donation+to+Storm+Games&no_note=0&cn=¤cy_code=USD&bn=PP-DonationsBF:btn_donateCC_LG.gif:NonHosted') diff --git a/libstormgames.py b/libstormgames.py deleted file mode 100755 index 9353949..0000000 --- a/libstormgames.py +++ /dev/null @@ -1,389 +0,0 @@ -#!/bin/python -# -*- coding: utf-8 -*- -"""Standard initializations and functions shared by all games.""" - -from sys import exit -import configparser -import os -from os import listdir -from os.path import isfile, join -from inspect import isfunction -from xdg import BaseDirectory -from setproctitle import setproctitle -import pygame -import pyperclip -import random -import re -import requests -import webbrowser -# Global variable for speech provider -try: - import speechd - spd = speechd.Client() - speechProvider = "speechd" -except ImportError: - import accessible_output2.outputs.auto - s = accessible_output2.outputs.auto.Auto() - speechProvider = "accessible_output2" -except ImportError: - print("No other speech providers found.") - exit() -import math -import time - -localConfig = configparser.ConfigParser() -globalConfig = configparser.ConfigParser() - -class scoreboard(): - 'Handles scores and top 10' - - def __init__(self, startingScore = 0): - read_config() - try: - localConfig.add_section("scoreboard") - except: - pass - self.score = startingScore - self.oldScores = [] - for i in range(1, 11): - try: - self.oldScores.insert(i - 1, localConfig.getint("scoreboard", str(i))) - except: - pass - self.oldScores.insert(i - 1, 0) - for i in range(1, 11): - if self.oldScores[i - 1] == None: - self.oldScores[i - 1] = 0 - - def __del__(self): - self.Update_Scores() - try: - write_config() - except: - pass - - def Decrease_Score(self, points = 1): - self.score -= points - - def Get_High_Score(self, position = 1): - return self.oldScores[position - 1] - - def Get_Score(self): - return self.score - - def Increase_Score(self, points = 1): - self.score += points - - def New_High_Score(self): - for i, j in enumerate(self.oldScores): - if self.score > j: return i + 1 - return None - - def Update_Scores(self): - # Update the scores - for i, j in enumerate(self.oldScores): - if self.score > j: - self.oldScores.insert(i, self.score) - break - # Only keep the top 10 scores. - self.oldScores = self.oldScores[:10] - # Update the scoreboard section of the games config file. - for i, j in enumerate(self.oldScores): - localConfig.set("scoreboard", str(i + 1), str(j)) - - -def write_config(writeGlobal = False): - if writeGlobal == False: - with open(gamePath + "/config.ini", 'w') as configfile: - localConfig.write(configfile) - else: - with open(globalPath + "/config.ini", 'w') as configfile: - globalConfig.write(configfile) - -def read_config(readGlobal = False): - if readGlobal == False: - try: - with open(gamePath + "/config.ini", 'r') as configfile: - localConfig.read_file(configfile) - except: - pass - else: - try: - with open(globalPath + "/config.ini", 'r') as configfile: - globalConfig.read_file(configfile) - except: - pass - -def speak(text, interupt = True): - if speechProvider == "speechd": - if interupt == True: spd.cancel() - spd.say(text) - else: - if speechProvider == "accessible_output2": - s.speak(text, interrupt=True) - - -def exit_game(): - if speechProvider == "speechd": spd.close() - pygame.mixer.music.stop() - pygame.quit() - exit() - -def initialize_gui(gameTitle): - # Check for, and possibly create, storm-games path - global globalPath - global gamePath - globalPath = BaseDirectory.xdg_config_home + "/storm-games" - gamePath = globalPath + "/" + str.lower(str.replace(gameTitle, " ", "-")) - if not os.path.exists(gamePath): os.makedirs(gamePath) - # Seed the random generator to the clock - random.seed() - # Set game's name - 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((320, 200)) - pygame.display.set_caption(gameTitle) - # Set 32 channels for sound by default - pygame.mixer.init() - pygame.mixer.set_num_channels(32) - # Reserve the cut scene channel - pygame.mixer.set_reserved(0) - # Load sounds from the sound directory and creates a list like that {'bottle': 'bottle.ogg'} - soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"])] - #lets make a dict with pygame.mixer.Sound() objects {'bottle':} - soundData = {} - for f in soundFiles: - soundData[f.split('.')[0]] = pygame.mixer.Sound("sounds/" + f) - soundData['game-intro'].play() - time.sleep(soundData['game-intro'].get_length()) - return soundData - -def cut_scene(sounds, soundName): - pygame.event.clear() - pygame.mixer.stop() - c = pygame.mixer.Channel(0) - c.play(sounds[soundName]) - while pygame.mixer.get_busy(): - event = pygame.event.poll() - if event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_RETURN, pygame.K_SPACE]: - pygame.mixer.stop() - pygame.event.pump() - -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: - 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 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, 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): - # Tries to stop a playing object channel - try: - x.stop() - return None - except: - return x - -def play_random(sounds, soundName, pause = False, interrupt = False): - key = [] - for i in sounds.keys(): - if re.match("^" + soundName + ".*", i): - key.append(i) - randomKey = random.choice(key) - if interrupt == False: - sounds[randomKey].play() - else: - cut_scene(sounds, randomKey) - # Cut scenes override the pause option - return - if pause == True: - time.sleep(sounds[randomKey].get_length()) - -def instructions(): - # Read in the instructions file - try: - with open('files/instructions.txt', 'r') as f: - info = f.readlines() - except: - info = ["Instructions file is missing."] - display_text(info) - -def credits(): - # Read in the credits file. - try: - with open('files/credits.txt', 'r') as f: - info = f.readlines() - # Add the header - info.insert(0, gameName + ": brought to you by Storm Dragon") - except: - info = ["Credits file is missing."] - display_text(info) - -def display_text(text): - i = 0 - text.insert(0, "Press space to read the whole text. Use up and down arrows to navigate the text line by line. Press c to copy the current line to the clipboard or t to copy the entire text. Press enter or escape when you are done reading.") - text.append("End of text.") - speak(text[i]) - while True: - event = pygame.event.wait() - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: return - if event.key == pygame.K_DOWN and i < len(text) - 1: i = i + 1 - if event.key == pygame.K_UP and i > 0: i = i - 1 - if event.key == pygame.K_SPACE: - speak(' '.join(text[1:])) - else: - speak(text[i]) - if event.key == pygame.K_c: - try: - pyperclip.copy(text[i]) - speak("Copied " + text[i] + " to the clipboard.") - except: - speak("Failed to copy the text to the clipboard.") - if event.key == pygame.K_t: - try: - pyperclip.copy(' '.join(text[1:-1])) - speak("Copied entire message to the clipboard.") - except: - speak("Failed to copy the text to the clipboard.") - event = pygame.event.clear() - time.sleep(0.001) - -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"])] - # j keeps track of last spoken index so it isn't voiced on key up. - j = -1 - while loop == True: - if i != j: - speak(soundFiles[i][:-4]) - j = i - event = pygame.event.wait() - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE: return "menu" - if event.key == pygame.K_DOWN and i < len(soundFiles) - 1: - pygame.mixer.stop() - i = i + 1 - if event.key == pygame.K_UP and i > 0: - pygame.mixer.stop() - i = i - 1 - if event.key == pygame.K_RETURN: - try: - soundName = soundFiles[i][:-4] - pygame.mixer.stop() - sounds[soundName].play() - continue - except: - j = -1 - speak("Could not play sound.") - continue - event = pygame.event.clear() - time.sleep(0.001) - -def game_menu(sounds, *options): - loop = True - pygame.mixer.stop() - if pygame.mixer.music.get_busy(): - pygame.mixer.music.unpause() - else: - 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 - while loop == True: - if i != j: - speak(options[i]) - j = i - event = pygame.event.wait() - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE: exit_game() - if event.key == pygame.K_DOWN and i < len(options) - 1: - i = i + 1 - try: - sounds['menu-move'].play() - except: - pass - if options[i] != "donate": pygame.mixer.music.unpause() - if event.key == pygame.K_UP and i > 0: - i = i - 1 - try: - sounds['menu-move'].play() - except: - pass - if options[i] != "donate": pygame.mixer.music.unpause() - if event.key == pygame.K_HOME and i != 0: - i = 0 - try: - sounds['menu-move'].play() - except: - pass - if options[i] != "donate": pygame.mixer.music.unpause() - if event.key == pygame.K_END and i != len(options) - 1: - i = len(options) -1 - try: - sounds['menu-move'].play() - except: - pass - if options[i] != "donate": pygame.mixer.music.unpause() - if event.key == pygame.K_RETURN: - try: - j = -1 - try: - sounds['menu-select'].play() - time.sleep(sounds['menu-select'].get_length()) - except: - pass - eval(options[i] + "()") - continue - except: - j = -1 - return options[i] - continue - event = pygame.event.clear() - time.sleep(0.001) - -def donate(): - pygame.mixer.music.pause() - webbrowser.open('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=stormdragon2976@gmail.com&lc=US&item_name=Donation+to+Storm+Games&no_note=0&cn=¤cy_code=USD&bn=PP-DonationsBF:btn_donateCC_LG.gif:NonHosted')