Commit a8829692 authored by Nelso Jost's avatar Nelso Jost

NEW: added Path to rect collision and better dependency management

parent f565a7a4
# encoding: utf-8
from __future__ import print_function, division
try:
input = raw_input
except NameError:
pass
'''
Author: Nelso G. Jost (nelsojost@gmail.com)
Licence: GPLv3
Version: 0.0.1
Purpose: Tired of the recurrent dependencies hell? This script provides a
fairly simple but useful mechanism of checking and installing debian,
python and general system dependencies.
The idea is to define all your linux dependencies here, along with
their check and install commands. Then you can add the following
rule on your project's Makefile:
setup:
@ python .deps.py
Additionally, if you want to perform dependency checking before any
important task, say a 'run' target, just execute 'setup' before it:
run: setup
@ python run.py # or whatever your 'run' target code is
This script handle three kinds of dependencies:
* Debian: Check if any of the listed commands exists. If at least
one fails, then apt-get update and install'em.
* Python3: Check if any of the listed libs can be imported. If at
least one fails, then get/update pip3 and install'em.
* General: Those who do not fall on any of the former categories.
Execute check code and if fail, the install code.
'''
# =============================================================================
# setup your dependecies here:
#
DEPENDENCIES =\
{
# apt-get installable packages. Format: '<package>@<shell_command>'
#
'debian': ['dialog@dialog', 'curl@curl'],
# python's pip3 installable packages. Format: '<package>@<import_name>'
#
'pip3': ['pyserial@serial'],
# dependencies that cannot be handled by the former specs
#
'general': [
# specify a dependency with the following dict format:
# {
# 'name': str with a name to be printed,
# 'check': str with shell command for testing existence
# 'install': str with shell command for installing
# }
{
'name': 'python3-pygame',
'check': 'python3 -c "import pygame"',
'install': '''\
sudo apt-get update &&
sudo apt-get install python3-dev \
python3-numpy libsdl-dev libsdl-image1.2-dev libsdl-mixer1.2-dev \
libsdl-ttf2.0-dev libsmpeg-dev libportmidi-dev libavformat-dev \
libswscale-dev libjpeg-dev libfreetype6-dev mercurial &&
rm -rf pygame &&
hg clone https://bitbucket.org/pygame/pygame &&
cd pygame && python3 setup.py build &&
sudo python3 setup.py install && cd .. && rm -rf pygame
'''
},
{
'name': 'paigamu',
'check': 'python3 -c "import paigamu"',
'install': '''\
rm -rf paigamu paigamu.git paigamu.zip && \
wget -O paigamu.zip https://git.cta.if.ufrgs.br/ctautils/paigamu/repository/archive.zip && \
unzip paigamu.zip && \
cp -rf paigamu.git/paigamu . && \
rm -rf paigamu.git paigamu.zip
'''
},
{
'name': 'platformiowizard',
'check': '[ -f firmware/.scripts/platformio_wizard.py ]',
'install': 'cd firmware && python -c "$(wget -O- https://git.cta.if.ufrgs.br/ctautils/platformiowizard/raw/master/get-platformiowizard.py)"'
}
# {
# 'name': 'platformio',
# 'check': 'which platformio > /dev/null',
# 'install': 'sudo python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)"'
# }
]
}
# =============================================================================
import os
def install_debian_dependencies():
''' Test the existence of all commands on the dependency list.
If at least one fails, execute apt-get update & install all of them.
'''
for dep in DEPENDENCIES['debian']:
package, command = [x.strip() for x in dep.split('@')]
if os.system('which {} > /dev/null'.format(command)) != 0:
print('-' * 70)
print('There are some missing Debian dependencies!\n'
'Attempting to install them now. Root password maybe '
'required.')
input('Hit ENTER to continue...')
return os.system(
'sudo apt-get update && sudo apt-get install {}'
.format(' '.join(
[x[:x.find('@')].strip() for x in DEPENDENCIES['debian']])))
return
else:
print('[OK] {} is installed'.format(package))
def install_pip3_dependencies():
''' Test the importability of all listed python3 libs.
If at least one fails, get/update pip3 and install all of them.
'''
for dep in DEPENDENCIES['pip3']:
package, lib = [x.strip() for x in dep.split('@')]
if os.system('python3 -c "import {}"'.format(lib)) != 0:
return os.system('''
wget https://bootstrap.pypa.io/get-pip.py && \
sudo -H python3 get-pip.py && \
rm -rf get-pip.py && \
sudo -H pip3 install {}'''.format(' '.join(
[x[:x.find('@')].strip() for x in DEPENDENCIES['pip3']])))
else:
print('[OK] python3-{} is installed'.format(package))
def install_external_dependencies():
''' Simply run the 'check' command of the dependency and if fails (exit
code != 1) then execute the 'install' command.
'''
for dep in DEPENDENCIES['general']:
if os.system(dep['check']) != 0:
os.system(dep['install'])
else:
print('[OK] {} is installed'.format(dep['name']))
try:
install_debian_dependencies()
install_pip3_dependencies()
install_external_dependencies()
print('-'*70)
print('All dependencies checked!')
print('-'*70)
except:
print('\n\n[FAIL] Some dependencies could not be installed.')
.PHONY: paigamu setup run clean firmware
all: help
all: setup run
help:
@ echo "Usage: make <target> where target can be"
......@@ -9,57 +9,15 @@ help:
@ echo " firmware install joystick software on Arduino board"
@ echo " run execute the game"
setup:
@ python .depman.py
run:
python3 main.py
firmware:
firmware: setup
cd firmware && make
setup:
$(MAKE) check-pygame || $(MAKE) install-pygame
$(MAKE) install-paigamu
$(MAKE) install-python-deps
$(MAKE) install-platformiowizard
check-pygame:
@ (python3 -c "import pygame" && echo "[OK] pygame installed") || \
echo "[FAIL] pygame is not installed"
install-pygame:
sudo apt-get update && sudo apt-get install python3-dev \
python3-numpy libsdl-dev libsdl-image1.2-dev libsdl-mixer1.2-dev \
libsdl-ttf2.0-dev libsmpeg-dev libportmidi-dev libavformat-dev \
libswscale-dev libjpeg-dev libfreetype6-dev mercurial
rm -rf pygame
hg clone https://bitbucket.org/pygame/pygame
cd pygame && python3 setup.py build
sudo python3 setup.py install
rm -rf pygame
install-paigamu:
@ python3 -c "import paigamu" || ( \
rm -rf paigamu paigamu.git paigamu.zip && \
wget -O paigamu.zip https://git.cta.if.ufrgs.br/ctautils/paigamu/repository/archive.zip && \
unzip paigamu.zip && \
cp -rf paigamu.git/paigamu . && \
rm -rf paigamu.git paigamu.zip && $(MAKE) install-paigamu)
@ (python3 -c "import paigamu" && echo "[OK] paigamu installed") || \
echo "[FAIL] paigamu is not installed"
install-platformiowizard:
@ python -c "import os; raise SystemExit(not os.path.exists('firmware/Makefile'))" || (cd firmware && wget https://git.cta.if.ufrgs.br/ctautils/platformiowizard/raw/master/get-platformiowizard.py && python get-platformiowizard.py)
@ echo "[OK] platformiowizard installed"
install-pip3:
wget https://bootstrap.pypa.io/get-pip.py
sudo -H python3 get-pip.py
rm -rf get-pip.py
install-python-deps:
@ python3 -c "import serial" || ($(MAKE) install-pip3 && sudo -H pip3 install pyserial && $(MAKE) install-python-deps)
@ echo "[OK] pyserial installed"
clean:
rm -rf paigamu
cd firmware && rm -rf .scripts Makefile .build
......
......@@ -4,7 +4,9 @@ Jogo onde o usuário deve utilizar o respirômetro (sensor do projeto FISIOLOG)
## Instalação e uso
Um arquivo `Makefile` deverá estar presente na pasta raiz do projeto. Dentro desta pasta é possível executar os seguintes comandos para manutenção:
Um arquivo `Makefile` deverá estar presente na pasta raiz do projeto. Ele disponibiliza vários comandos para manutenção deste software através do programa `make` (execute dentro desta pasta).
* `make`: executa `setup` e `run` na sequencia.
* `make setup`: verifica e instala todas as dependências;
......
......@@ -8,8 +8,12 @@ class AppLabirintoGame(GameApp):
def on_setup(self):
self.main_scene = MainScene(app=self, surface=self.screen)
self.timer_fps = Timer(dt=1,
callback=lambda: pygame.display.set_caption(
'Labirinto (FPS: {:.2f})'.format(self.clock.get_fps())))
def on_gameloop(self):
self.timer_fps.update()
self.main_scene.update()
self.main_scene.draw()
......@@ -21,6 +25,7 @@ class AppLabirintoGame(GameApp):
class MainScene(Scene):
maze_speed = 150
def on_setup(self):
......@@ -29,22 +34,33 @@ class MainScene(Scene):
size=(50, 50),
left=100,
centery=self.rect.centery,
vel=(0, 200),
control_with='joystick',
keymap={'up': 'K_w', 'down': 'K_s'})
accel=Vec2D(0, 4*self.maze_speed),
keymap={'up': 'K_w', 'down': 'K_s'},
serial_joystick={'port': '/dev/ttyACM0', 'baud': 9600})
self['top_maze'] = MazeSprite(
points=[(0, 200), (200, 0), (400, 200), (600, 0), (800, 200)],
line_color='white',
vel=[-150, 0])
vel=[-self.maze_speed, 0])
self['top_maze'].shift(dy=50)
self['bottom_maze'] = MazeSprite(
points=[(0, 400), (200, 200), (400, 400), (600, 200), (800, 400)],
color_state='normal',
vel=[-150, 0])
vel=[-self.maze_speed, 0])
self['bottom_maze'].shift(dy=50)
def on_gameloop(self):
if self['top_maze'].collide_with_rect(self['player']):
self['top_maze'].color_state = 'colliding'
else:
self['top_maze'].color_state = 'normal'
if self['bottom_maze'].collide_with_rect(self['player']):
self['bottom_maze'].color_state = 'colliding'
else:
self['bottom_maze'].color_state = 'normal'
class MazeSprite(PathSprite):
running_x = True
......@@ -72,24 +88,31 @@ class MazeSprite(PathSprite):
class PlayerSprite(Sprite):
running = False
control_with = 'keyboard'
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.handle_controls = {'joystick': self.handle_joystick,
'keyboard': self.handle_keypress}\
[kwargs.get('control_with', 'keyboard')]
self.joystick_respirometro = JoystickRespirometro()
'keyboard': self.handle_keypress}
self.joystick_respirometro = JoystickRespirometro(
**self.serial_joystick)
if self.joystick_respirometro.enabled:
self.control_with = 'joystick'
else:
print("[FAIL] to open joystick respirometro at '{}'!"
"\nUsing keyboard controls instead.".format(
self.serial_joystick['port']))
def update(self):
self.handle_controls()
self.handle_controls[self.control_with]()
if self.running:
self.vel.y += self.app.dt * self.accel.y
self.y += self.app.dt * self.vel.y
# if self.path_collide(self.scene['top_maze']):
# self.scene['top_maze'].color_state = 'colliding'
# else:
# self.scene['top_maze'].color_state = 'normal'
if (self.vel.ymag >= self.scene.maze_speed):
self.vel.ymag = self.scene.maze_speed
def handle_keydown(self, event):
if event.key == pygame.K_DOWN:
......@@ -99,30 +122,29 @@ class PlayerSprite(Sprite):
def handle_keypress(self):
if self.app.is_key_pressed(self.keymap['down']):
self.vel.j, self.running = 1, True
if self.accel.j != 1:
self.accel.j = self.vel.j = 1
self.vel.ymag = 0
self.running = True
elif self.app.is_key_pressed(self.keymap['up']):
self.vel.j, self.running = -1, True
if self.accel.j != -1:
self.accel.j = self.vel.j = -1
self.vel.ymag = 0
self.running = True
else:
self.running = False
def handle_joystick(self):
_MAX_VEL = 150
self.joystick_respirometro.update()
if self.joystick_respirometro.inhaling():
self.accel.y = 1000
self.vel.j, self.running = 1, True
# print('inhaling', self.pos, self.vel, self.app.dt)
self.accel.j = self.vel.j = 1
self.running = True
elif self.joystick_respirometro.exhaling():
self.accel.y = -1000
self.vel.j, self.running = -1, True
# print('exhaling', self.pos, self.vel, self.app.dt)
self.accel.j = self.vel.j = -1
self.running = True
else:
self.running = False
# print('idle', self.pos, self.vel, self.app.dt)
if(self.vel.ymag > _MAX_VEL):
self.vel.ymag = _MAX_VEL
class JoystickRespirometro:
......@@ -130,18 +152,19 @@ class JoystickRespirometro:
_STATESR = {1: 'in', -1: 'ex', 0: 'idle'}
_AMPLITUDE = 2
def __init__(self):
def __init__(self, port, baud):
self._state = 0
self._last_read = 0
try:
self._sercon = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
print(self._sercon)
self._sercon = serial.Serial(port, rate, timeout=1)
self._enabled = True
self.timer = Timer(dt=0.2, callback=self.refresh)
except:
print("Unable to open serial port at '/dev/ttyACM0'. "
"Joystick will be disabled.")
self._enabled = False
self.timer = Timer(dt=0.2, callback=self.refresh)
@property
def enabled(self):
return self._enabled
def inhaling(self):
return self._state == self._STATES['in']
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment