gpio input translated to command events
This commit is contained in:
parent
ac9c5cdf4c
commit
f0b77551b6
60
OPEN-GAME
60
OPEN-GAME
|
@ -1,42 +1,38 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from os import environ, execvp, chdir, getcwd
|
||||
from os.path import exists, join, dirname
|
||||
from sys import version_info, argv
|
||||
import sys, os
|
||||
|
||||
def can_import(module_name):
|
||||
try:
|
||||
__import__(module_name)
|
||||
except ImportError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
def ignore_sighup():
|
||||
"""
|
||||
Ignore hangup signal (that is thrown when launching from systemd?).
|
||||
Taken from https://stackoverflow.com/questions/57205271/how-to-display-pygame-framebuffer-using-systemd-service
|
||||
"""
|
||||
import signal
|
||||
def handler(signum, frame):
|
||||
pass
|
||||
signal.signal(signal.SIGHUP, handler)
|
||||
|
||||
def is_python_3():
|
||||
return version_info[0] >= 3
|
||||
# Change directory to the directory of the program launching the script (usually this script "OPEN-GAME").
|
||||
if "--go-to-dir" in sys.argv:
|
||||
os.chdir(os.path.dirname(sys.argv[0]))
|
||||
|
||||
def is_current_version(file_name):
|
||||
version = map(int, file_name.replace("python", "").split("."))
|
||||
return version == list(version_info)[:2]
|
||||
# Use the KMS video driver. This works for newer versions of Raspberry Pi with the KMS overlay
|
||||
# enabled, SDL 2, and Pygame 2.
|
||||
if "--kms" in sys.argv:
|
||||
os.putenv("SDL_VIDEODRIVER", "kmsdrm")
|
||||
|
||||
def launch_alternative(alternatives):
|
||||
for alternative in alternatives:
|
||||
if not is_current_version(alternative):
|
||||
for root in environ["PATH"].split(":"):
|
||||
if exists(join(root, alternative)):
|
||||
execvp(alternative, [alternative] + argv)
|
||||
# Use the framebuffer display. This only works with Pygame 1.9.6 (and SDL 1.2).
|
||||
if "--fb" in sys.argv:
|
||||
os.putenv("SDL_VIDEODRIVER", "fbcon")
|
||||
os.putenv("SDL_FBDEV", "/dev/fb0")
|
||||
|
||||
def move_to_executable():
|
||||
chdir(dirname(argv[0]))
|
||||
# Ignore hangup signal. This may be necessary when launching from systemd.
|
||||
if "--ignore-hangup" in sys.argv:
|
||||
ignore_sighup()
|
||||
|
||||
if is_python_3():
|
||||
launch_alternative(["python2", "python2.7", "python2.6"])
|
||||
|
||||
if not can_import("pygame"):
|
||||
launch_alternative(["python2.7", "python2.6"])
|
||||
|
||||
if "--go-to-dir" in argv:
|
||||
move_to_executable()
|
||||
# Import GPIO library if requested
|
||||
if "--gpio" in sys.argv:
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
from electric_sieve.ElectricSieve import ElectricSieve
|
||||
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from os import environ, execvp, chdir, getcwd
|
||||
from os.path import exists, join, dirname
|
||||
from sys import version_info, argv
|
||||
|
||||
def can_import(module_name):
|
||||
try:
|
||||
__import__(module_name)
|
||||
except ImportError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def is_python_3():
|
||||
return version_info[0] >= 3
|
||||
|
||||
def is_current_version(file_name):
|
||||
version = map(int, file_name.replace("python", "").split("."))
|
||||
return version == list(version_info)[:2]
|
||||
|
||||
def launch_alternative(alternatives):
|
||||
for alternative in alternatives:
|
||||
if not is_current_version(alternative):
|
||||
for root in environ["PATH"].split(":"):
|
||||
if exists(join(root, alternative)):
|
||||
execvp(alternative, [alternative] + argv)
|
||||
|
||||
def move_to_executable():
|
||||
chdir(dirname(argv[0]))
|
||||
|
||||
if is_python_3():
|
||||
launch_alternative(["python2", "python2.7", "python2.6"])
|
||||
|
||||
if not can_import("pygame"):
|
||||
launch_alternative(["python2.7", "python2.6"])
|
||||
|
||||
if "--go-to-dir" in argv:
|
||||
move_to_executable()
|
||||
|
||||
from electric_sieve.ElectricSieve import ElectricSieve
|
||||
|
||||
os.putenv("SDL_FBDEV", "/dev/fb0")
|
||||
os.putenv("SDL_VIDEODRIVER", "fbcon")
|
||||
os.putenv("SDL_NOMOUSE", "1")
|
||||
ElectricSieve().run()
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os
|
||||
|
||||
def ignore_sighup():
|
||||
"""
|
||||
Ignore hangup signal (that is thrown when launching from systemd?).
|
||||
Taken from https://stackoverflow.com/questions/57205271/how-to-display-pygame-framebuffer-using-systemd-service
|
||||
"""
|
||||
import signal
|
||||
def handler(signum, frame):
|
||||
pass
|
||||
signal.signal(signal.SIGHUP, handler)
|
||||
|
||||
# Change directory to the directory of the program launching the script (usually this script "OPEN-GAME").
|
||||
if "--go-to-dir" in sys.argv:
|
||||
os.chdir(os.path.dirname(sys.argv[0]))
|
||||
|
||||
# Use the KMS video driver. This works for newer versions of Raspberry Pi with the KMS overlay
|
||||
# enabled, SDL 2, and Pygame 2.
|
||||
os.putenv("SDL_VIDEODRIVER", "kmsdrm")
|
||||
# ignore_sighup()
|
||||
|
||||
from electric_sieve.ElectricSieve import ElectricSieve
|
||||
|
||||
ElectricSieve().run()
|
19
README.md
19
README.md
|
@ -1,12 +1,12 @@
|
|||
Electric Sieve
|
||||
==============
|
||||
|
||||
Avoid touching the triangles with the rods. Chain successes to send acid deeper into the Earth.
|
||||
Avoid touching the triangles with the rods
|
||||
|
||||
Controls
|
||||
--------
|
||||
|
||||
* L/R - Scroll sieve
|
||||
* Left/Right - Scroll sieve
|
||||
* Down - Increase fall speed
|
||||
* F11 - Full screen
|
||||
|
||||
|
@ -20,4 +20,17 @@ Running
|
|||
-------
|
||||
|
||||
* Windows - double-click "scale-sieve" EXE
|
||||
* Linux/Mac - run "./scale-sieve" on the command line
|
||||
* Linux/Mac - run `./OPEN-GAME` on the command line
|
||||
|
||||
Raspberry Pi
|
||||
------------
|
||||
|
||||
Add `--gpio` to the command line to read input from buttons wired to the Raspberry Pi (the buttons should be wired to GPIO 17 and 27).
|
||||
|
||||
Headless
|
||||
--------
|
||||
|
||||
If running on Linux without X-Windows (for example, Raspberry Pi Lite OS), there are two options for launching
|
||||
|
||||
* add `--kms` to the command line if the newer KMS driver and Pygame 2 are being used
|
||||
* add `--fb` to use the framebuffer if using Pygame 1
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
from random import randint, randrange, choice
|
||||
from time import time
|
||||
from operator import itemgetter
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
from pygame import Surface, PixelArray, Rect
|
||||
from pygame.draw import aalines, polygon
|
||||
|
@ -25,12 +25,19 @@ class ElectricSieve(Game):
|
|||
PIN_LED_DOWN = 23
|
||||
|
||||
def __init__(self):
|
||||
self.initialize_gpio()
|
||||
if self.gpio_enabled():
|
||||
self.initialize_gpio()
|
||||
Game.__init__(self)
|
||||
self.background = Surface(self.display.screen.get_size())
|
||||
self.background.fill((255, 80, 190))
|
||||
self.title.activate()
|
||||
|
||||
def gpio_enabled(self):
|
||||
"""
|
||||
@return True if GPIO mode was requested at launch, False otherwise
|
||||
"""
|
||||
return "--gpio" in sys.argv
|
||||
|
||||
def initialize_gpio(self):
|
||||
"""
|
||||
Set pin numbering mode to GPIO, initialize all buttons to input pullup.
|
||||
|
@ -38,9 +45,25 @@ class ElectricSieve(Game):
|
|||
# Use GPIO numbering
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
|
||||
# Set all button pins to pullup
|
||||
# Set button pins to pullup and attach to each a callback that runs on press or release
|
||||
for pin in self.PIN_BUTTON_UP, self.PIN_BUTTON_DOWN:
|
||||
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
GPIO.add_event_detect(pin, GPIO.BOTH, self.gpio_input)
|
||||
|
||||
def gpio_input(self, pin):
|
||||
"""
|
||||
Translate GPIO input into PGFW commands, so Raspberry Pi wired controllers be used for input. The pin will be checked for a low
|
||||
signal, meaning the pin has been connected to ground, which is translated to a button press. If the low signal is not detected, it
|
||||
is translated to a button release. Usually called as a callback by `GPIO.add_event_detect` but can be called directly.
|
||||
|
||||
@param pin Raspberry Pi pin number as read by the RPi.GPIO library
|
||||
"""
|
||||
cancel = not (GPIO.input(pin) == GPIO.LOW)
|
||||
if pin == ElectricSieve.PIN_BUTTON_UP:
|
||||
self.input.post_command("left", cancel=cancel)
|
||||
elif pin == ElectricSieve.PIN_BUTTON_DOWN:
|
||||
self.input.post_command("right", cancel=cancel)
|
||||
self.input.post_any_command(id=pin, cancel=cancel)
|
||||
|
||||
def set_children(self):
|
||||
Game.set_children(self)
|
||||
|
@ -131,8 +154,6 @@ class Strip(Sprite):
|
|||
|
||||
def __init__(self, parent):
|
||||
Sprite.__init__(self, parent)
|
||||
GPIO.add_event_detect(ElectricSieve.PIN_BUTTON_UP, GPIO.BOTH, self.respond)
|
||||
GPIO.add_event_detect(ElectricSieve.PIN_BUTTON_DOWN, GPIO.BOTH, self.respond)
|
||||
self.deactivate()
|
||||
self.display_surface = self.get_display_surface()
|
||||
self.delegate = self.get_game().delegate
|
||||
|
@ -151,30 +172,17 @@ class Strip(Sprite):
|
|||
pass
|
||||
|
||||
def respond(self, event):
|
||||
if type(event) == int:
|
||||
pressed = "pressed" if GPIO.input(event) == GPIO.LOW else "released"
|
||||
print(f"pin {event} {pressed}")
|
||||
"""
|
||||
Translate input events into movement of the sieve object. This function is usually set as a callback, but it can be called directly.
|
||||
|
||||
@param event `pygame.event.Event` with input
|
||||
"""
|
||||
if self.active:
|
||||
move = False
|
||||
if type(event) == int:
|
||||
if event == ElectricSieve.PIN_BUTTON_UP:
|
||||
direction = self.LEFT
|
||||
move = True
|
||||
elif event == ElectricSieve.PIN_BUTTON_DOWN:
|
||||
direction = self.RIGHT
|
||||
move = True
|
||||
active = GPIO.input(event) == GPIO.LOW
|
||||
else:
|
||||
compare = self.delegate.compare
|
||||
if compare(event, "left") or compare(event, "left", True):
|
||||
direction = self.LEFT
|
||||
move = True
|
||||
elif compare(event, "right") or compare(event, "right", True):
|
||||
direction = self.RIGHT
|
||||
move = True
|
||||
active = not event.cancel
|
||||
if move:
|
||||
self.hshifts[direction].active = active
|
||||
compare = self.delegate.compare
|
||||
if compare(event, "left") or compare(event, "left", True):
|
||||
self.hshifts[self.LEFT].active = not event.cancel
|
||||
elif compare(event, "right") or compare(event, "right", True):
|
||||
self.hshifts[self.RIGHT].active = not event.cancel
|
||||
|
||||
def activate(self):
|
||||
self.active = True
|
||||
|
|
Loading…
Reference in New Issue