Commit fe6d69cb authored by Nelso Jost's avatar Nelso Jost
Browse files

NEW: testes iniciais com o sample pygame

parents
Este repositório contém diversos samples minimalistas que ilustram o funcionamento de frameworks gráficos que possivelmente serão adotados para desenvolvimento dos jogos relacionados ao projeto Fisiolog.
# Pygame Sample
Contém um pequeno projeto demonstração escrito em Python + Pygame para um jogo simples onde o player é controlado por um elemento de hardware: sensor na placa Arduino. A posição do player é atualizada com base na resposta do sensor lida pela porta serial.
O arquivo Makefile presente neste diretório contém diversos comandos para manutenção do software, descrita a seguir.
## Firmware
Além do código Python, este diretório inclui também um firmware minimalista para ser instalado na placa Arduino e utilizado em conjunto com o jogo.
`/firmware/pot/pot.ino`
Pode ser instalado via IDE do Arduino ou pelo terminal como segue:
* Primeiramente, certifique-se de ter Ino Tools no sistema. Caso não tenha, instale-o:
```
$ make install-ino
```
* Verifique o nome do modelo da Arduino que você deseja compilar:
```
$ make list-inomodels
```
* Edite a variável INOMODEL no topo do Makefile para conter o nome correto da placa para a qual será feito o build e upload.
* Tendo uma vez tudo preparado, basta fazer build e upload com:
```
$ make firmware
```
## Dependências Python
Este software requer as seguintes bibliotecas de Python:
* `pyserial`
* `pygame`
Ambas suportam Python 2 e Python 3, mas este projeto busca utilizar Python 3 por padrão. Caso opte por Python 2, substitua o "3" por "2" nos comandos seguintes.
* Certifique-se de ter o gerenciador de packages pip instalado no sistema:
```
$ make install-pip3
```
OBS: Requer o programa `curl` presente no sistema. Instale com `$ sudo apt-get install curl`.
* Instale dependencias possíveis via pip3:
```
$ make install-py3-deps
```
* Instale Pygame para Python 3 (requer compilação de submódulos C):
```
$ make install-pygame-py3
```
## Execução
Escolha o interpretador a utilizar na variável PYBIN do Makefile e simplesmente execute com:
```
$ make run
```
INOMODEL=atmega328
INODIR=.ino
PYBIN=python3
.PHONY: firmware
all: run
run:
${PYBIN} main.py
install-pip2:
curl https://bootstrap.pypa.io/get-pip.py | sudo python
install-pip3:
curl https://bootstrap.pypa.io/get-pip.py | sudo python3
install-ino: install-pip
sudo pip2 install ino
install-py2-deps:
sudo pip2 install pyserial
install-py3-deps:
sudo pip3 install pyserial
install-pygame-py2:
sudo apt-get install python-pygame
install-pygame-py3:
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
hg clone https://bitbucket.org/pygame/pygame
cd pygame && python3 setup.py build
cd pygame && sudo python3 setup.py install
rm -rf pygame
list-inomodels:
ino list-models
firmware:
cd firmware && rm -rf ${INODIR} && mkdir -p ${INODIR} && cd ${INODIR} && ino init && cp -rf ../pot/pot.ino src/sketch.ino && ino build -m ${INOMODEL} && ino upload -m ${INOMODEL}
clean:
rm -rf firmware/${INODIR}
rm -rf __pycache__
rm -rf *.pyc
serial:
cd firmware && ino serial
#define POT_PIN 0
char command;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available()) {
command = Serial.read();
if (command == 'p')
{
Serial.println(analogRead(POT_PIN));
}
}
}
import pygame
from subpixelsurface import *
class AppGame:
RESOLUTION = [640, 480]
FRAMERATE = 60
background_color = (0, 0, 0)
def on_setup(self):
pass
def on_gameloop(self):
pass
def on_keydown_event(self, event):
if event.key == pygame.K_ESCAPE:
self.quit()
def run(self):
pygame.init()
self.screen = pygame.display.set_mode(self.RESOLUTION)
self.clock = pygame.time.Clock()
self.on_setup()
while True:
self.dt = self.clock.tick(self.FRAMERATE) / 1000.0
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.quit()
elif event.type == pygame.KEYDOWN:
self.on_keydown_event(event)
self.on_gameloop()
pygame.display.update()
def quit(self):
pygame.quit()
raise SystemExit(0)
class Sprite:
running = True
def __init__(self, app, size, color, pos=(0, 0), vel=(0, 0)):
self.app = app
self.surface = pygame.Surface(size)
self.surface.fill(color)
self.surface.convert()
self.subpixel_surf = SubPixelSurface(self.surface)
self.pos, self.vel, self.size = list(pos), list(vel), tuple(size)
@property
def w(self):
return self.size[0]
@property
def h(self):
return self.size[1]
@property
def x(self):
return self.pos[0]
@x.setter
def x(self, value):
self.pos[0] = value
@property
def y(self):
return self.pos[1]
@y.setter
def y(self, value):
self.pos[1] = value
def run(self, dt):
# if not self.running: return
self.pos[0] += dt * self.vel[0]
self.pos[1] += dt * self.vel[1]
def draw(self, surface):
surface.blit(self.surface, self.pos)
# def draw(self, surface):
# surface.blit(self.subpixel_surf.at(self.x, self.y), self.pos)
def rectcollide_with(self, sprite):
return (self.x < sprite.x + sprite.w and
self.x + self.w > sprite.x and
self.y < sprite.y + sprite.h and
self.y + self.h > sprite.y)
import pygame
import serial
import random
from gameobjects import *
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.01)
print(ser)
class AppBreathingGame(AppGame):
RESOLUTION = [640, 480]
FRAMERATE = 0
background_color = (0, 0, 0)
def on_setup(self):
self.player = Player(app=self, size=[50, 50], color=[0, 255, 0],
pos=[150, 200],
vel=[0, 0])
self.asteroid = Asteroid(app=self, size=[50, 50], color=[255, 0, 0],
pos=[400, 300],
vel=[-300, 0])
def on_gameloop(self):
self.player.update()
self.asteroid.update()
self.screen.fill(self.background_color)
self.player.draw(self.screen)
self.asteroid.draw(self.screen)
class Player(Sprite):
si, sf = 500, 600
H = 480
def update(self):
self.run(self.app.dt)
self.read_serial()
def read_serial(self):
try:
ser.write(b'p')
n = int(ser.readline())
self.y = self.H * (1.0 - (self.sf - n)/(self.sf - self.si))
print(n, self.y)
except:
pass
class Asteroid(Sprite):
def update(self):
self.run(self.app.dt)
# print(self.x, self.y, self.pos)
if self.x < 0:
self.init_pos()
if self.rectcollide_with(self.app.player):
print(self.pos)
# print('BOOM!')
def init_pos(self):
self.x = self.app.RESOLUTION[0]
self.y = random.randint(0, self.app.RESOLUTION[1] - self.w)
if __name__ == '__main__':
AppBreathingGame().run()
# font: http://www.pygame.org/project-Sub-pixel+surface-413-.html
import pygame
from pygame.locals import *
from math import floor
# Try to import Numpy, or Numeric
try:
import numpy as Numeric
BYTE = "u1"
DWORD = "u4"
except ImportError:
try:
import Numeric
except ImportError as e:
print("Requires NumPy or Numeric!")
raise e
BYTE = Numeric.UnsignedInt8
DWORD = Numeric.Int32
class SubPixelSurface(object):
def __init__(self, surface, x_level=3, y_level=None):
"""Creates a sub pixel surface object.
surface -- A PyGame surface
x_level -- Number of sub-pixel levels in x
y_level -- Number of sub-pixel levels in y (same as x if omited)
"""
self.x_level = x_level
self.y_level = y_level or x_level
w, h = surface.get_size()
ow, oh = w, h
w += 2
h += 2
surf_array_rgb = Numeric.zeros((w, h, 3), BYTE)
surf_array_rgb[1:ow+1:, 1:oh+1:, ::] = pygame.surfarray.array3d(surface)
surf_array_a = Numeric.zeros((w, h), BYTE)
surf_array_a[1:ow+1:, 1:oh+1:] = pygame.surfarray.array_alpha(surface)
surf_array_rgb[0,::] = surf_array_rgb[1,::]
surf_array_rgb[::,0] = surf_array_rgb[::,1]
surf_array_rgb[w-1,::] = surf_array_rgb[w-2,::]
surf_array_rgb[::,h-1] = surf_array_rgb[::,h-2]
s = Numeric.zeros(surf_array_rgb.shape[:2]+(4,), DWORD)
s[::-1, ::, :3] = surf_array_rgb
s[::-1, ::, 3] = surf_array_a
x_steps = [float(n) / self.x_level for n in range(self.x_level)]
y_steps = [float(n) / self.y_level for n in range(self.y_level)]
self.surfaces = []
for frac_y in y_steps:
row = []
self.surfaces.append(row)
for frac_x in x_steps:
row.append( SubPixelSurface._generate(s, frac_x, frac_y) )
@staticmethod
def _generate(s, frac_x, frac_y):
frac_x, frac_y = frac_y, frac_x
frac_x = 1. - frac_x
sa = int( (1.-frac_x) * (1.-frac_y) * 255. )
sb = int( (1.-frac_x) * frac_y * 255. )
sc = int( frac_x * (1.-frac_y) * 255. )
sd = int( (frac_x * frac_y) * 255. )
a = s[ :-1:, :-1:] * sa
b = s[ 1::, :-1:] * sb
c = s[ :-1:, 1:: ] * sc
d = s[ 1::, 1:: ] * sd
a += b
a += c
a += d
a >>= 8
rgba_data = a.astype(BYTE).tostring()
pygame_surface = pygame.image.fromstring(rgba_data, a.shape[:2][::-1], "RGBA")
pygame_surface = pygame.transform.rotate(pygame_surface, 270)
return pygame_surface
def at(self, x, y):
"""Gets a sub-pixel surface for a given coordinate.
x -- X coordinate
y -- Y coordinate
"""
surf_x = int( (x - floor(x)) * self.x_level )
surf_y = int( (y - floor(y)) * self.y_level )
return self.surfaces[surf_y][surf_x]
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.1)
print(ser)
time.sleep(1.5)
def loop():
while True:
ser.write(b'p')
print(ser.readline())
time.sleep(0.01)
loop()
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