6
.gitignore
vendored
@ -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
|
||||
|
1
MANIFEST.in
Normal file
@ -0,0 +1 @@
|
||||
recursive-include pocket_friends *
|
21
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!
|
@ -1 +0,0 @@
|
||||
"""Imports classes for running the game."""
|
@ -1 +0,0 @@
|
||||
"""Initializes all classes needed for the development environment, and faking GPIO inputs."""
|
1
pocket_friends/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__version__ = 'dev_0.0.1'
|
@ -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:
|
@ -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
|
0
pocket_friends/development/__init__.py
Normal file
@ -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():
|
@ -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))
|
0
pocket_friends/game_files/__init__.py
Normal file
@ -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()
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 631 B After Width: | Height: | Size: 631 B |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 807 B After Width: | Height: | Size: 807 B |
Before Width: | Height: | Size: 610 B After Width: | Height: | Size: 610 B |
Before Width: | Height: | Size: 820 B After Width: | Height: | Size: 820 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 864 B After Width: | Height: | Size: 864 B |
Before Width: | Height: | Size: 740 B After Width: | Height: | Size: 740 B |
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 736 B After Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 312 B |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
0
pocket_friends/hardware/__init__.py
Normal file
@ -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:
|
26
setup.py
Normal file
@ -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,
|
||||
)
|