Compare commits
	
		
			56 Commits
		
	
	
		
			devel
			...
			e2c69e3af7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e2c69e3af7 | ||
| 
						 | 
					da17b71c28 | ||
| 
						 | 
					1cb57391d8 | ||
| 
						 | 
					7f62e6ccca | ||
| 
						 | 
					943e2acf53 | ||
| 
						 | 
					c242fc6832 | ||
| 
						 | 
					6d2c6e04d8 | ||
| 
						 | 
					97431c0c74 | ||
| 
						 | 
					4a15f951f0 | ||
| 
						 | 
					5a791510ea | ||
| 
						 | 
					7cbbc64d27 | ||
| 
						 | 
					b479811a98 | ||
| 
						 | 
					d5d737d0c0 | ||
| 
						 | 
					dd246db5be | ||
| 
						 | 
					21216f361a | ||
| 
						 | 
					68e72f5d81 | ||
| 
						 | 
					80fe2caff3 | ||
| 
						 | 
					2df86c9c76 | ||
| 
						 | 
					5fa90f9e84 | ||
| 
						 | 
					658709ebce | ||
| 
						 | 
					d5c79c0770 | ||
| 
						 | 
					24f9a126d4 | ||
| 
						 | 
					c316d4e570 | ||
| 
						 | 
					e66655d75f | ||
| 
						 | 
					c5406d5089 | ||
| 
						 | 
					b5b472eebe | ||
| 
						 | 
					9f03de15b8 | ||
| 
						 | 
					428a48678d | ||
| 
						 | 
					9a6d6374f9 | ||
| 
						 | 
					df386cbbd9 | ||
| 
						 | 
					38522aee78 | ||
| 
						 | 
					0e9c52f5e1 | ||
| 
						 | 
					fabf48ff42 | ||
| 
						 | 
					0c73e98876 | ||
| 
						 | 
					0ef11785ec | ||
| 
						 | 
					58ab5aa854 | ||
| 
						 | 
					155ed6ec39 | ||
| 
						 | 
					68ad08be46 | ||
| 
						 | 
					536659338e | ||
| 
						 | 
					37aa764d68 | ||
| 
						 | 
					84a722bb8e | ||
| 
						 | 
					b897abf0a3 | ||
| 
						 | 
					678af54346 | ||
| 
						 | 
					d456b8b3b3 | ||
| 
						 | 
					c5c32943e2 | ||
| 
						 | 
					34d89ca54b | ||
| 
						 | 
					e8bf4f9565 | ||
| 
						 | 
					dd350c0285 | ||
| 
						 | 
					ae93e02e69 | ||
| 
						 | 
					21c0795ea9 | ||
| 
						 | 
					67d2315cef | ||
| 
						 | 
					b6afb5450e | ||
| 
						 | 
					42266d4b6c | ||
| 
						 | 
					54842bac29 | ||
| 
						 | 
					08f06699c8 | ||
| 
						 | 
					7ef11be54c | 
							
								
								
									
										1016
									
								
								__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										1016
									
								
								__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										273
									
								
								libstormgames.py
									
									
									
									
									
								
							
							
						
						
									
										273
									
								
								libstormgames.py
									
									
									
									
									
								
							@@ -1,273 +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 time
 | 
			
		||||
 | 
			
		||||
localConfig = configparser.ConfigParser()
 | 
			
		||||
globalConfig = configparser.ConfigParser()
 | 
			
		||||
 | 
			
		||||
class scoreboard():
 | 
			
		||||
    'Handles scores and top 10'
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.oldScores = []
 | 
			
		||||
        for i in range(9):
 | 
			
		||||
            try:
 | 
			
		||||
                self.oldScores[i] = read_config("scoreboard", i)
 | 
			
		||||
            except:
 | 
			
		||||
                self.oldScores[i] = 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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(section, value, readGlobal = False):
 | 
			
		||||
    if readGlobal == False:
 | 
			
		||||
        with open(gamePath + "config.ini", 'r') as configfile:
 | 
			
		||||
            return localConfig.read(section, value)
 | 
			
		||||
    else:
 | 
			
		||||
        with open(globalPath + "config.ini", 'r') as configfile:
 | 
			
		||||
            return globalConfig.read(section, value)
 | 
			
		||||
        
 | 
			
		||||
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':<soundobject>}
 | 
			
		||||
    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 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
 | 
			
		||||
    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_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')
 | 
			
		||||
							
								
								
									
										8
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
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
 | 
			
		||||
wxpython
 | 
			
		||||
							
								
								
									
										2
									
								
								requirements_linux.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								requirements_linux.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
-r requirements.txt
 | 
			
		||||
python-speechd>=0.11.1
 | 
			
		||||
		Reference in New Issue
	
	Block a user