diff --git a/.gitignore b/.gitignore index f21358b..965b584 100644 --- a/.gitignore +++ b/.gitignore @@ -128,8 +128,8 @@ dmypy.json # Pyre type checker .pyre/ -# Save file -/save.json - # pocket-friends compile script /compile.bat + +# save file +/pocket_friends/game_files/save.json diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..f10dc56 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +recursive-include pocket_friends * \ No newline at end of file diff --git a/README.md b/README.md index 8f969e4..106cfb2 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,23 @@ Pocket Friends is a game where you raise your own little pocket friend! These pocket friends, called bloops, are great little companions to have! You can feed them, play with them, and watch them grow up! ~~You can download the latest release of Pocket Friends on the [releases page.](https://github.com/nickedyer/pocket-friends/releases)~~ -There are currently no releases of the game. +There are currently no releases of the game. To install the current version on GitHub, follow the instructions below. + +--- + +## Installing From Source + +Since this game is made in Python, it is fairly easy to set up and install as long as you have Python installed. +Ensure you also have pip installed, as it is required to install Pocket Friends as well. + +### You must have Python 3.6 or greater to install Pocket Friends. + +Once you have Python installed, getting Pocket Friends installed is easy; just install it using pip and you're ready to go! + +`pip install git+https://github.com/nickedyer/pocket-friends.git` + +Now that the game is installed, just run it like you would any other Python program. + +`python -m pocket_friends` + +...and that's it! You now have the latest dev build of Pocket Friends installed on your system! \ No newline at end of file diff --git a/data/__init__.py b/data/__init__.py deleted file mode 100644 index 975cbfa..0000000 --- a/data/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Imports classes for running the game.""" diff --git a/data/development/__init__.py b/data/development/__init__.py deleted file mode 100644 index 2b19ec2..0000000 --- a/data/development/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Initializes all classes needed for the development environment, and faking GPIO inputs.""" diff --git a/pocket_friends/__init__.py b/pocket_friends/__init__.py new file mode 100644 index 0000000..f0ccdbb --- /dev/null +++ b/pocket_friends/__init__.py @@ -0,0 +1 @@ +__version__ = 'dev_0.0.1' diff --git a/pocket_friends.py b/pocket_friends/__main__.py similarity index 68% rename from pocket_friends.py rename to pocket_friends/__main__.py index 3ee8203..60a496c 100644 --- a/pocket_friends.py +++ b/pocket_friends/__main__.py @@ -3,12 +3,13 @@ Launch script for Pocket Friends. """ import pygame import sys -from data.game import main as game_main -from data.development.dev_menu import main as dev_menu_main +from pocket_friends.game_files.game import main as game_main +from pocket_friends.development.dev_menu import main as dev_menu_main -enable_dev = False +__version__ = '0.0.1' if __name__ == '__main__': + enable_dev = False # enable dev mode if --dev argument is passed if len(sys.argv) > 0: diff --git a/data/development/FakeGPIO.py b/pocket_friends/development/FakeGPIO.py similarity index 94% rename from data/development/FakeGPIO.py rename to pocket_friends/development/FakeGPIO.py index c974005..23a82c6 100644 --- a/data/development/FakeGPIO.py +++ b/pocket_friends/development/FakeGPIO.py @@ -1,6 +1,6 @@ """ Module used to fake the RPi.GPIO module so that -the game can be run without the actual hardware. +the hardware can be run without the actual hardware. """ # Constants used by RPi.GPIO diff --git a/pocket_friends/development/__init__.py b/pocket_friends/development/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/data/development/button_test.py b/pocket_friends/development/button_test.py similarity index 96% rename from data/development/button_test.py rename to pocket_friends/development/button_test.py index b89813b..f9c7ee5 100644 --- a/data/development/button_test.py +++ b/pocket_friends/development/button_test.py @@ -2,7 +2,7 @@ Module to test the GPIO input on the Raspberry Pi. """ from collections import deque -from ..gpio_handler import Constants, GPIOHandler +from ..hardware.gpio_handler import Constants, GPIOHandler def button_test(): diff --git a/data/development/dev_menu.py b/pocket_friends/development/dev_menu.py similarity index 89% rename from data/development/dev_menu.py rename to pocket_friends/development/dev_menu.py index 916f663..24e2fe4 100644 --- a/data/development/dev_menu.py +++ b/pocket_friends/development/dev_menu.py @@ -1,22 +1,20 @@ """ -Development menu for the game on Raspberry Pi. NOTE: THIS DOES NOTHING ON A COMPUTER! +Development menu for the hardware on Raspberry Pi. NOTE: THIS DOES NOTHING ON A COMPUTER! """ -import data.game +import pocket_friends.game_files.game import importlib.util import os import pygame import time from .button_test import button_test from .menus import Menu -from ..gpio_handler import GPIOHandler, Constants - -dev_version = '0.0.1' +from ..hardware.gpio_handler import GPIOHandler, Constants try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO except ImportError: - import data.development.FakeGPIO as GPIO + import pocket_friends.development.FakeGPIO as GPIO # Global variable to keep track of the current menu. menu = 'main' @@ -40,10 +38,10 @@ def clear_screen(): def start_game(): """ - Cleans the GPIO and starts the game. + Cleans the GPIO and starts the hardware. """ GPIOHandler.teardown() - data.game.main() + pocket_friends.game_files.game.main() pygame.quit() GPIOHandler.setup() @@ -95,7 +93,7 @@ def main(): # The following defines all of the options in the various different menus. - main_menu = Menu('Pocket Friends Dev Menu {0}\nGame Version {1}'.format(dev_version, data.game.version)) + main_menu = Menu('Pocket Friends Dev Menu') main_menu.add_option(Menu.Option('Start Game', start_game)) main_menu.add_option(Menu.Option('Button Test', run_button_test)) main_menu.add_option(Menu.Option('Restart Dev Menu', quit_with_error)) diff --git a/data/development/menus.py b/pocket_friends/development/menus.py similarity index 100% rename from data/development/menus.py rename to pocket_friends/development/menus.py diff --git a/pocket_friends/game_files/__init__.py b/pocket_friends/game_files/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/data/game.py b/pocket_friends/game_files/game.py similarity index 86% rename from data/game.py rename to pocket_friends/game_files/game.py index b45bbba..d720e57 100644 --- a/data/game.py +++ b/pocket_friends/game_files/game.py @@ -1,21 +1,33 @@ """ -Main file for the entire game. Controls everything except for GPIO input. +Main file for the entire hardware. Controls everything except for GPIO input. """ from collections import deque import importlib.util import json import os +from pathlib import Path +import pocket_friends import pygame from pygame.locals import * -from .gpio_handler import Constants, GPIOHandler +from ..hardware.gpio_handler import Constants, GPIOHandler -version = '0.0.1' +# FPS for the entire game to run at. game_fps = 16 +# Gets the directory of the script for importing and the save directory +script_dir = os.path.dirname(__file__) +save_dir = os.path.join(Path.home(), '.pocket_friends') + +# Tries to make the save directory. Does nothing if it already exists. +try: + os.mkdir(save_dir) +except FileExistsError: + pass + class FileHandler: """ - Class that handles the game attributes and save files. + Class that handles the hardware attributes and save files. """ def __init__(self): @@ -33,7 +45,7 @@ class FileHandler: """ Writes attributes of class to "save.json" file. """ - with open('save.json', 'w') as save_file: + with open(save_dir + '/save.json', 'w') as save_file: json.dump(self.attributes, save_file) save_file.close() @@ -43,7 +55,7 @@ class FileHandler: """ # Open up the save file and read it into self.attributes. try: - with open('save.json', 'r') as save_file: + with open(save_dir + '/save.json', 'r') as save_file: self.attributes = json.load(save_file) save_file.close() @@ -69,7 +81,7 @@ class SelectionEgg(pygame.sprite.Sprite): def __init__(self, egg_color): pygame.sprite.Sprite.__init__(self) - image_directory = 'resources/images/egg_images/{0}'.format(egg_color) + image_directory = script_dir + '/resources/images/egg_images/{0}'.format(egg_color) # Load the egg from the given color and get the bounding rectangle for the image. self.images = [] @@ -108,19 +120,19 @@ try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO except ImportError: - import data.development.FakeGPIO as GPIO + import pocket_friends.development.FakeGPIO as GPIO def game(): """ - Starts the game. + Starts the hardware. """ pygame.init() # Hide the cursor for the Pi display. pygame.mouse.set_visible(False) - # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the + # The hardware is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. rendered_size = 80 screen_size = 800 @@ -129,14 +141,14 @@ def game(): surface = pygame.Surface((rendered_size, rendered_size)) # Only really useful for PCs. Does nothing on the Raspberry Pi. - pygame.display.set_caption('Pocket Friends') + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) clock = pygame.time.Clock() - # Font used for small text in the game. Bigger text is usually image files. - small_font = pygame.font.Font('resources/fonts/5Pts5.ttf', 10) + # Font used for small text in the hardware. Bigger text is usually image files. + small_font = pygame.font.Font(script_dir + '/resources/fonts/5Pts5.ttf', 10) - # Default game state when the game first starts. + # Default hardware state when the hardware first starts. game_state = 'title' running = True file_handler = FileHandler() @@ -147,7 +159,7 @@ def game(): # Start the GPIO handler to take in buttons from the RPi HAT. GPIOHandler.setup() - # Dev code used to exit the game. Default Down, Down, Up, Up, Down, Down, Up, Up, A, A, B + # Dev code used to exit the hardware. Default Down, Down, Up, Up, Down, Down, Up, Up, A, A, B dev_code = deque() for button in [Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), Constants.buttons.get('j_u'), Constants.buttons.get('j_u'), Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), @@ -177,9 +189,9 @@ def game(): def draw_bg(): """ - Draws the main game background image onto a given surface. + Draws the main hardware background image onto a given surface. """ - bg_image = pygame.image.load('resources/images/bg.png').convert() + bg_image = pygame.image.load(script_dir + '/resources/images/bg.png').convert() surface.blit(bg_image, (0, 0)) def log_button(pressed_button): @@ -226,7 +238,7 @@ def game(): def keyboard_handler(): """ - Simulates key presses to GPIO button presses. Also handles quitting the game. + Simulates key presses to GPIO button presses. Also handles quitting the hardware. """ nonlocal running @@ -254,10 +266,10 @@ def game(): def pre_handler(): """ - Runs at the beginning of each loop, handles drawing the background, controlling game speed, and + Runs at the beginning of each loop, handles drawing the background, controlling hardware speed, and controlling the GPIO button inputs and keyboard handler """ - # Regulate the speed of the game. + # Regulate the speed of the hardware. clock.tick(game_fps) # Handle all inputs for both debugging and real GPIO button presses. @@ -274,11 +286,11 @@ def game(): pre_handler() # Draw the title image in the middle of the screen. - title_image = pygame.image.load('resources/images/title.png').convert_alpha() + title_image = pygame.image.load(script_dir + '/resources/images/title.png').convert_alpha() surface.blit(title_image, (0, 0)) draw() - # Show the title for 1 second then move on to the initialization phase of the game. + # Show the title for 1 second then move on to the initialization phase of the hardware. pygame.time.wait(1000) game_state = 'init' @@ -294,8 +306,8 @@ def game(): # Read the save file. file_handler.read_save() - # Determines if it is a new game or not by looking at the evolution stage. If it is -1, the egg has - # not been created yet, and the game sends you to the egg selection screen. If not, the game sends + # Determines if it is a new hardware or not by looking at the evolution stage. If it is -1, the egg has + # not been created yet, and the hardware sends you to the egg selection screen. If not, the hardware sends # you to the playground. if file_handler.attributes['evolution_stage'] == -1: game_state = 'egg_select' @@ -419,7 +431,7 @@ def game(): submenu = 'egg_info' # Draws the cursor on screen. - cursor = pygame.image.load('resources/images/clock_selector.png').convert_alpha() + cursor = pygame.image.load(script_dir + '/resources/images/clock_selector.png').convert_alpha() surface.blit(cursor, get_cursor_coords(selected)) draw() @@ -430,7 +442,7 @@ def game(): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == Constants.buttons.get('a'): - # Go to an invalid game state if continuing. + # Go to an invalid hardware state if continuing. game_state = None if event.key == Constants.buttons.get('b'): # Go back to the egg selection screen. @@ -446,17 +458,17 @@ def game(): game_state = None else: - # Error screen. This appears when an invalid game state has been selected. + # Error screen. This appears when an invalid hardware state has been selected. all_sprites.empty() - frames_passed = 0 # Counter for frames, helps ensure the game isnt frozen. + frames_passed = 0 # Counter for frames, helps ensure the hardware isnt frozen. while running and game_state != 'title': pre_handler() # Draw the error screen - error_screen = pygame.image.load('resources/images/debug/invalid.png').convert_alpha() + error_screen = pygame.image.load(script_dir + '/resources/images/debug/invalid.png').convert_alpha() surface.blit(error_screen, (0, -8)) # Counts the frames passed. Resets every second. @@ -479,7 +491,7 @@ def game(): def main(): """ - Calls the game() function to start the game. + Calls the hardware() function to start the hardware. """ game() diff --git a/resources/fonts/5Pts5.ttf b/pocket_friends/game_files/resources/fonts/5Pts5.ttf similarity index 100% rename from resources/fonts/5Pts5.ttf rename to pocket_friends/game_files/resources/fonts/5Pts5.ttf diff --git a/resources/images/bg.png b/pocket_friends/game_files/resources/images/bg.png similarity index 100% rename from resources/images/bg.png rename to pocket_friends/game_files/resources/images/bg.png diff --git a/resources/images/clock_selector.png b/pocket_friends/game_files/resources/images/clock_selector.png similarity index 100% rename from resources/images/clock_selector.png rename to pocket_friends/game_files/resources/images/clock_selector.png diff --git a/resources/images/debug/invalid.png b/pocket_friends/game_files/resources/images/debug/invalid.png similarity index 100% rename from resources/images/debug/invalid.png rename to pocket_friends/game_files/resources/images/debug/invalid.png diff --git a/resources/images/egg_images/blue/blue.png b/pocket_friends/game_files/resources/images/egg_images/blue/blue.png similarity index 100% rename from resources/images/egg_images/blue/blue.png rename to pocket_friends/game_files/resources/images/egg_images/blue/blue.png diff --git a/resources/images/egg_images/dev_egg/dev_egg_0.png b/pocket_friends/game_files/resources/images/egg_images/dev_egg/dev_egg_0.png similarity index 100% rename from resources/images/egg_images/dev_egg/dev_egg_0.png rename to pocket_friends/game_files/resources/images/egg_images/dev_egg/dev_egg_0.png diff --git a/resources/images/egg_images/dev_egg/dev_egg_1.png b/pocket_friends/game_files/resources/images/egg_images/dev_egg/dev_egg_1.png similarity index 100% rename from resources/images/egg_images/dev_egg/dev_egg_1.png rename to pocket_friends/game_files/resources/images/egg_images/dev_egg/dev_egg_1.png diff --git a/resources/images/egg_images/green/green.png b/pocket_friends/game_files/resources/images/egg_images/green/green.png similarity index 100% rename from resources/images/egg_images/green/green.png rename to pocket_friends/game_files/resources/images/egg_images/green/green.png diff --git a/resources/images/egg_images/indigo/indigo.png b/pocket_friends/game_files/resources/images/egg_images/indigo/indigo.png similarity index 100% rename from resources/images/egg_images/indigo/indigo.png rename to pocket_friends/game_files/resources/images/egg_images/indigo/indigo.png diff --git a/resources/images/egg_images/orange/orange.png b/pocket_friends/game_files/resources/images/egg_images/orange/orange.png similarity index 100% rename from resources/images/egg_images/orange/orange.png rename to pocket_friends/game_files/resources/images/egg_images/orange/orange.png diff --git a/resources/images/egg_images/rainbow/rainbow.png b/pocket_friends/game_files/resources/images/egg_images/rainbow/rainbow.png similarity index 100% rename from resources/images/egg_images/rainbow/rainbow.png rename to pocket_friends/game_files/resources/images/egg_images/rainbow/rainbow.png diff --git a/resources/images/egg_images/red/red.png b/pocket_friends/game_files/resources/images/egg_images/red/red.png similarity index 100% rename from resources/images/egg_images/red/red.png rename to pocket_friends/game_files/resources/images/egg_images/red/red.png diff --git a/resources/images/egg_images/violet/violet.png b/pocket_friends/game_files/resources/images/egg_images/violet/violet.png similarity index 100% rename from resources/images/egg_images/violet/violet.png rename to pocket_friends/game_files/resources/images/egg_images/violet/violet.png diff --git a/resources/images/egg_images/white/white.png b/pocket_friends/game_files/resources/images/egg_images/white/white.png similarity index 100% rename from resources/images/egg_images/white/white.png rename to pocket_friends/game_files/resources/images/egg_images/white/white.png diff --git a/resources/images/egg_images/yellow/yellow.png b/pocket_friends/game_files/resources/images/egg_images/yellow/yellow.png similarity index 100% rename from resources/images/egg_images/yellow/yellow.png rename to pocket_friends/game_files/resources/images/egg_images/yellow/yellow.png diff --git a/resources/images/icon.png b/pocket_friends/game_files/resources/images/icon.png similarity index 100% rename from resources/images/icon.png rename to pocket_friends/game_files/resources/images/icon.png diff --git a/resources/images/promotional.png b/pocket_friends/game_files/resources/images/promotional.png similarity index 100% rename from resources/images/promotional.png rename to pocket_friends/game_files/resources/images/promotional.png diff --git a/resources/images/title.png b/pocket_friends/game_files/resources/images/title.png similarity index 100% rename from resources/images/title.png rename to pocket_friends/game_files/resources/images/title.png diff --git a/pocket_friends/hardware/__init__.py b/pocket_friends/hardware/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/data/gpio_handler.py b/pocket_friends/hardware/gpio_handler.py similarity index 97% rename from data/gpio_handler.py rename to pocket_friends/hardware/gpio_handler.py index 185df5a..f8cd603 100644 --- a/data/gpio_handler.py +++ b/pocket_friends/hardware/gpio_handler.py @@ -8,7 +8,7 @@ try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO except ImportError: - import data.development.FakeGPIO as GPIO + import pocket_friends.development.FakeGPIO as GPIO class Constants: diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..bb178df --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +import setuptools +import pocket_friends + +with open('requirements.txt') as fh: + required = fh.read().splitlines() + +with open('README.md', 'r') as fh: + long_description = fh.read() + +setuptools.setup( + name='Pocket Friends', + version=pocket_friends.__version__, + author='Nicholas Dyer', + description='A virtual friend for you to take care of and have fun with!', + license='GNU GPL-3.0', + long_description=long_description, + long_description_content_type='text/markdown', + url='https://github.com/nickedyer/pocket-friends', + packages=setuptools.find_packages(), + # https://pypi.org/classifiers/ + classifiers=[ + ], + install_requires=required, + python_requires='>=3.6', + include_package_data=True, +)