Compare commits
5 Commits
f56f775541
...
d8775fb1a9
Author | SHA1 | Date | |
---|---|---|---|
d8775fb1a9 | |||
4045930bd9 | |||
d322949b5a | |||
b97d54f49d | |||
65365adc3d |
1
pocket_friends/game_files/elements/__init__.py
Normal file
1
pocket_friends/game_files/elements/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""Sub-module for use in the game. Helps with the drawing of various objects such as sprites and text boxes."""
|
@ -4,53 +4,78 @@ import json
|
|||||||
|
|
||||||
class SpriteSheet:
|
class SpriteSheet:
|
||||||
"""
|
"""
|
||||||
Imports a sprite sheet as separate pygame images given an image file and a json file.
|
Class to be used by sprites in order to give them a texture and an animation.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
images (list) List of all the sprites in the animation separated from the sprite sheet.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sprite_sheet, texture_json):
|
def __init__(self, sprite_sheet, texture_json):
|
||||||
|
"""
|
||||||
|
Creates a sprite sheet given a sprite image and its corresponding JSON file.
|
||||||
|
Args:
|
||||||
|
sprite_sheet (str): The path of the sprite sheet image component.
|
||||||
|
texture_json (str): The path of the sprite sheet JSON component, contains the number of frames in the
|
||||||
|
sprite sheet, and the width and height of an individual sprite from the sprite sheet.
|
||||||
|
"""
|
||||||
# Load in whole sprite sheet as one image.
|
# Load in whole sprite sheet as one image.
|
||||||
self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha()
|
sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha()
|
||||||
self.images = []
|
self.images = []
|
||||||
|
print(type(self.images))
|
||||||
|
|
||||||
# Get the sprite sheet json file.
|
# Get the sprite sheet json file.
|
||||||
with open(texture_json, 'r') as json_file:
|
with open(texture_json, 'r') as json_file:
|
||||||
self.img_attrib = json.load(json_file)
|
img_attrib = json.load(json_file)
|
||||||
json_file.close()
|
json_file.close()
|
||||||
|
|
||||||
# Count for how many images have been added in the image list
|
# Count for how many images have been added in the image list
|
||||||
image_count = 0
|
image_count = 0
|
||||||
|
|
||||||
# Get the sprite size as a tuple
|
# Get the sprite size as a tuple
|
||||||
sprite_size = self.img_attrib['width'], self.img_attrib['height']
|
sprite_size = img_attrib['width'], img_attrib['height']
|
||||||
|
|
||||||
# Iterate through every image location on the sprite sheet given the sprite size
|
# Iterate through every image location on the sprite sheet given the sprite size
|
||||||
for i in range(self.sprite_sheet.get_size()[1] // sprite_size[1]):
|
for i in range(sprite_sheet.get_size()[1] // sprite_size[1]):
|
||||||
i *= sprite_size[1]
|
i *= sprite_size[1]
|
||||||
for j in range(self.sprite_sheet.get_size()[0] // sprite_size[0]):
|
for j in range(sprite_sheet.get_size()[0] // sprite_size[0]):
|
||||||
j *= sprite_size[0]
|
j *= sprite_size[0]
|
||||||
|
|
||||||
# Create a new transparent surface
|
# Create a new transparent surface
|
||||||
sprite = pygame.Surface(sprite_size, pygame.SRCALPHA)
|
sprite = pygame.Surface(sprite_size, pygame.SRCALPHA)
|
||||||
# Blit the sprite onto the image
|
# Blit the sprite onto the image
|
||||||
sprite.blit(self.sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1]))
|
sprite.blit(sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1]))
|
||||||
# Add the image to the list of images
|
# Add the image to the list of images
|
||||||
self.images.append(sprite)
|
self.images.append(sprite)
|
||||||
|
|
||||||
image_count += 1
|
image_count += 1
|
||||||
|
|
||||||
# Break the loop if the specified number of frames has been reached.
|
# Break the loop if the specified number of frames has been reached.
|
||||||
if image_count >= self.img_attrib['frames']:
|
if image_count >= img_attrib['frames']:
|
||||||
break
|
break
|
||||||
if image_count >= self.img_attrib['frames']:
|
if image_count >= img_attrib['frames']:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
class SelectionEgg(pygame.sprite.Sprite):
|
class SelectionEgg(pygame.sprite.Sprite):
|
||||||
"""
|
"""
|
||||||
Class for the eggs on the egg selection screen.
|
Sprite to render the egg on the egg selection screen.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
egg_color (str): The color of the egg (also its name).
|
||||||
|
description (str): The description of the egg to be displayed when selected.
|
||||||
|
contentedness (int): How likely the egg is to stay happy, ranges from 0-5.
|
||||||
|
metabolism (int): How quickly the egg will get hungry, ranges from 0-5.
|
||||||
|
rect (pygame.Rect): Pygame rectangle used to position the egg on screen.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, egg_color, resources_dir):
|
def __init__(self, egg_color, resources_dir):
|
||||||
|
"""
|
||||||
|
Creates a SelectionEgg object given an egg color and a resource location.
|
||||||
|
Args:
|
||||||
|
egg_color (str): The color egg that should be rendered.
|
||||||
|
resources_dir (str): The path of the resources directory.
|
||||||
|
"""
|
||||||
pygame.sprite.Sprite.__init__(self)
|
pygame.sprite.Sprite.__init__(self)
|
||||||
|
|
||||||
self.egg_color = egg_color
|
self.egg_color = egg_color
|
||||||
@ -68,20 +93,21 @@ class SelectionEgg(pygame.sprite.Sprite):
|
|||||||
# Load the egg from the given color and get the bounding rectangle for the image.
|
# Load the egg from the given color and get the bounding rectangle for the image.
|
||||||
sprite_sheet = SpriteSheet(resources_dir + '/images/bloops/{0}/egg.png'.format(self.egg_color),
|
sprite_sheet = SpriteSheet(resources_dir + '/images/bloops/{0}/egg.png'.format(self.egg_color),
|
||||||
resources_dir + '/images/bloops/{0}/egg.json'.format(self.egg_color))
|
resources_dir + '/images/bloops/{0}/egg.json'.format(self.egg_color))
|
||||||
self.images = sprite_sheet.images
|
self._images = sprite_sheet.images
|
||||||
|
|
||||||
# Get the rectangle from the first image in the list
|
# Get the rectangle from the first image in the list
|
||||||
self.rect = self.images[0].get_rect()
|
self.rect = self._images[0].get_rect()
|
||||||
self.index = 0
|
print(type(self.rect))
|
||||||
self.image = self.images[self.index]
|
self._index = 0
|
||||||
|
self.image = self._images[self._index]
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""
|
"""
|
||||||
Updates the sprite object.
|
Update the sprite to the next animation frame.
|
||||||
"""
|
"""
|
||||||
# Animate the sprite
|
# Animate the sprite
|
||||||
self.index = (self.index + 1) % len(self.images)
|
self._index = (self._index + 1) % len(self._images)
|
||||||
self.image = self.images[self.index]
|
self.image = self._images[self._index]
|
||||||
|
|
||||||
|
|
||||||
class InfoText:
|
class InfoText:
|
@ -4,9 +4,11 @@ import json
|
|||||||
|
|
||||||
class SaveData:
|
class SaveData:
|
||||||
"""
|
"""
|
||||||
Class that represents the save data of the game.
|
Class used to read and write save data for the game
|
||||||
"""
|
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
attributes (dict): Dictionary containing all the attributes to read and write from a save file.
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Constructs the object with all starting values.
|
Constructs the object with all starting values.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
Module used to fake the RPi.GPIO module so that
|
Dummy module that contains empty functions and variables that exist in RPi.GPIO. This module is to be imported
|
||||||
the program can be run without the actual hardware.
|
if importing RPi.GPIO fails.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Constants used by RPi.GPIO
|
# Constants used by RPi.GPIO
|
||||||
@ -12,7 +12,11 @@ FALLING = 0
|
|||||||
def setmode(new_mode):
|
def setmode(new_mode):
|
||||||
"""
|
"""
|
||||||
Fake setmode function.
|
Fake setmode function.
|
||||||
:param new_mode:
|
Args:
|
||||||
|
new_mode:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -20,10 +24,14 @@ def setmode(new_mode):
|
|||||||
def setup(channel, mode, initial=None, pull_up_down=None):
|
def setup(channel, mode, initial=None, pull_up_down=None):
|
||||||
"""
|
"""
|
||||||
Fake setup function.
|
Fake setup function.
|
||||||
:param channel:
|
Args:
|
||||||
:param mode:
|
channel:
|
||||||
:param initial:
|
mode:
|
||||||
:param pull_up_down:
|
initial:
|
||||||
|
pull_up_down:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -31,10 +39,14 @@ def setup(channel, mode, initial=None, pull_up_down=None):
|
|||||||
def add_event_detect(channel, edge_type, callback=None, bouncetime=0):
|
def add_event_detect(channel, edge_type, callback=None, bouncetime=0):
|
||||||
"""
|
"""
|
||||||
Fake function to add a non-existent event detect.
|
Fake function to add a non-existent event detect.
|
||||||
:param channel:
|
Args:
|
||||||
:param edge_type:
|
channel:
|
||||||
:param callback:
|
edge_type:
|
||||||
:param bouncetime:
|
callback:
|
||||||
|
bouncetime:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -42,8 +54,11 @@ def add_event_detect(channel, edge_type, callback=None, bouncetime=0):
|
|||||||
def event_detected(channel):
|
def event_detected(channel):
|
||||||
"""
|
"""
|
||||||
Fake function to detect an event. Always returns false.
|
Fake function to detect an event. Always returns false.
|
||||||
:param channel:
|
Args:
|
||||||
:return:
|
channel:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -51,6 +66,10 @@ def event_detected(channel):
|
|||||||
def cleanup(channel=None):
|
def cleanup(channel=None):
|
||||||
"""
|
"""
|
||||||
Fake cleanup function.
|
Fake cleanup function.
|
||||||
:param channel:
|
Args:
|
||||||
|
channel:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
"""
|
"""Handle inputs from the GPIO pins on the Raspberry Pi and converting them to events to be used in other places (
|
||||||
Handle inputs from the GPIO pins on the Raspberry Pi and converting them to events to be used in other places (pygame, etc.)
|
pygame, etc.)"""
|
||||||
"""
|
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
|
||||||
# If the RPi.GPIO module is not found (aka the program is not running on a Pi), import the fake
|
# If the RPi.GPIO module is not found (aka the program is not running on a Pi), import the fake
|
||||||
# GPIO module instead to prevent a crash.
|
# GPIO module instead to prevent a crash.
|
||||||
|
|
||||||
|
ON_HARDWARE = None # Flag to tell other methods if the program is running on hardware or not
|
||||||
|
|
||||||
try:
|
try:
|
||||||
importlib.util.find_spec('RPi.GPIO')
|
importlib.util.find_spec('RPi.GPIO')
|
||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
|
ON_HARDWARE = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import pocket_friends.game_files.io.fake_gpio as GPIO
|
import pocket_friends.game_files.io.fake_gpio as GPIO
|
||||||
|
ON_HARDWARE = False
|
||||||
|
|
||||||
# Dictionary of all the buttons used and what their corresponding GPIO codes are
|
# Dictionary of all the buttons used and what their corresponding GPIO codes are
|
||||||
BUTTONS = {
|
BUTTONS = {
|
||||||
@ -24,9 +28,7 @@ BUTTONS = {
|
|||||||
|
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
"""
|
"""Prime the GPIO pins for reading the inputs of the buttons."""
|
||||||
Primes the GPIO pins for reading the inputs of the buttons.
|
|
||||||
"""
|
|
||||||
GPIO.setmode(GPIO.BOARD)
|
GPIO.setmode(GPIO.BOARD)
|
||||||
|
|
||||||
GPIO.setup(BUTTONS.get('a'), GPIO.IN)
|
GPIO.setup(BUTTONS.get('a'), GPIO.IN)
|
||||||
@ -47,16 +49,17 @@ def setup():
|
|||||||
|
|
||||||
|
|
||||||
def teardown():
|
def teardown():
|
||||||
"""
|
"""Clean up the GPIO handler."""
|
||||||
Cleans up the GPIO handler.
|
|
||||||
"""
|
|
||||||
GPIO.cleanup()
|
GPIO.cleanup()
|
||||||
|
|
||||||
|
|
||||||
def get_press(button):
|
def get_press(button):
|
||||||
"""
|
"""
|
||||||
Returns true if a button has changed from not pressed to pressed.
|
Checks if a given button code has been pressed and returns a bool depending on the state.
|
||||||
:param button: button to be detected
|
Args:
|
||||||
:return: True if the button is has been pressed, False otherwise
|
button: button to be detected
|
||||||
|
|
||||||
|
Returns: True if the button is has been pressed, False otherwise
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return GPIO.event_detected(button)
|
return GPIO.event_detected(button)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import pygame
|
import pygame
|
||||||
import importlib.util
|
|
||||||
import pocket_friends.game_files.io.gpio_handler as gpio_handler
|
import pocket_friends.game_files.io.gpio_handler as gpio_handler
|
||||||
|
|
||||||
|
|
||||||
@ -7,36 +6,40 @@ class InputHandler:
|
|||||||
"""
|
"""
|
||||||
Class that is implemented into surfaces in order to control the
|
Class that is implemented into surfaces in order to control the
|
||||||
pressing of buttons on both the real hardware and on a keyboard.
|
pressing of buttons on both the real hardware and on a keyboard.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
clock (pygame.time.Clock): Pygame clock used for input time calculations.
|
||||||
|
last_input_tick (int): The tick that the last input was registered on.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, pygame_clock):
|
def __init__(self, pygame_clock):
|
||||||
|
"""
|
||||||
|
Create a InputHandler object using a given Pygame clock.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pygame_clock (pygame.time.Clock): A pygame clock to use as the clock for input time calculations.
|
||||||
|
|
||||||
|
"""
|
||||||
self.clock = pygame_clock
|
self.clock = pygame_clock
|
||||||
|
|
||||||
# If not on actual hardware, fake the GPIO in order to get it working correctly.
|
|
||||||
try:
|
|
||||||
importlib.util.find_spec('RPi.GPIO')
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
self.on_hardware = True
|
|
||||||
except ImportError:
|
|
||||||
import pocket_friends.game_files.io.fake_gpio as GPIO
|
|
||||||
self.on_hardware = False
|
|
||||||
|
|
||||||
self.last_input_tick = 0
|
self.last_input_tick = 0
|
||||||
|
|
||||||
def create_event(self, pressed_button):
|
def create_event(self, pressed_button):
|
||||||
"""
|
"""
|
||||||
Creates a pygame event with a given keyboard code
|
Create a pygame event given a GPIO code and post it to the pygame event handler.
|
||||||
:param pressed_button:
|
Args:
|
||||||
|
pressed_button (int): The GPIO code to be registered and pressed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Register a button click so long as the last button click happened no less than two frames ago
|
# Register a button click so long as the last button click happened no less than two frames ago
|
||||||
if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2 or not self.on_hardware:
|
if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2 or not gpio_handler.ON_HARDWARE:
|
||||||
pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key': pressed_button}))
|
pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key': pressed_button}))
|
||||||
pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button}))
|
pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button}))
|
||||||
self.last_input_tick = pygame.time.get_ticks()
|
self.last_input_tick = pygame.time.get_ticks()
|
||||||
|
|
||||||
def handle_gpio(self):
|
def handle_gpio(self):
|
||||||
"""
|
"""
|
||||||
Handles getting GPIO button presses and making a pygame event when a press is detected.
|
Handle GPIO events and create events for them.
|
||||||
"""
|
"""
|
||||||
for pressed_button in gpio_handler.BUTTONS:
|
for pressed_button in gpio_handler.BUTTONS:
|
||||||
code = gpio_handler.BUTTONS.get(pressed_button)
|
code = gpio_handler.BUTTONS.get(pressed_button)
|
||||||
@ -45,10 +48,8 @@ class InputHandler:
|
|||||||
if gpio_handler.get_press(code):
|
if gpio_handler.get_press(code):
|
||||||
self.create_event(code)
|
self.create_event(code)
|
||||||
|
|
||||||
def keyboard_handler(self):
|
def handle_keyboard(self):
|
||||||
"""
|
"""Handle keyboard presses and generate corresponding GPIO codes to create events."""
|
||||||
Simulates key presses to GPIO button presses. Also handles quitting the game.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press.
|
# Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press.
|
||||||
for keyboard_event in pygame.event.get():
|
for keyboard_event in pygame.event.get():
|
||||||
@ -73,10 +74,8 @@ class InputHandler:
|
|||||||
running = False
|
running = False
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""
|
"""Run either the GPIO handler or the keyboard handler to check for input and create events."""
|
||||||
Run the input handler and check for inputs.
|
if gpio_handler.ON_HARDWARE:
|
||||||
"""
|
|
||||||
if self.on_hardware:
|
|
||||||
self.handle_gpio()
|
self.handle_gpio()
|
||||||
else:
|
else:
|
||||||
self.keyboard_handler()
|
self.handle_keyboard()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import pygame
|
import pygame
|
||||||
from . import sprites
|
from ..elements import sprites
|
||||||
import pocket_friends.game_files.io.gpio_handler as gpio_handler
|
import pocket_friends.game_files.io.gpio_handler as gpio_handler
|
||||||
from ..io.input_handler import InputHandler
|
from ..io.input_handler import InputHandler
|
||||||
|
|
||||||
|
@ -1,12 +1,22 @@
|
|||||||
import pygame
|
import pygame
|
||||||
from . import sprites
|
from ..elements import sprites
|
||||||
import pocket_friends.game_files.io.gpio_handler as gpio_handler
|
import pocket_friends.game_files.io.gpio_handler as gpio_handler
|
||||||
from .sprites import SelectionEgg
|
|
||||||
from ..io.input_handler import InputHandler
|
from ..io.input_handler import InputHandler
|
||||||
|
|
||||||
|
|
||||||
class Surface(pygame.Surface):
|
class Surface(pygame.Surface):
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
def __init__(self, window_size, resources_dir, game_fps, **kwargs):
|
def __init__(self, window_size, resources_dir, game_fps, **kwargs):
|
||||||
|
"""
|
||||||
|
|
||||||
|
Args:
|
||||||
|
window_size:
|
||||||
|
resources_dir:
|
||||||
|
game_fps:
|
||||||
|
**kwargs:
|
||||||
|
"""
|
||||||
super().__init__(window_size, pygame.SRCALPHA)
|
super().__init__(window_size, pygame.SRCALPHA)
|
||||||
self.name = 'selection_info'
|
self.name = 'selection_info'
|
||||||
self.running = True
|
self.running = True
|
||||||
|
Loading…
Reference in New Issue
Block a user