Commit 37d1b33e authored by Nelso Jost's avatar Nelso Jost
Browse files

ADD: basic map editor

parent 28c992a0
......@@ -3,3 +3,4 @@ paigamu
firmware/Makefile
firmware/.scripts
build
.build
[serial]
baud = 9600
port = /dev/ttyACM0
[joystickrespirometro]
serial_port = /dev/ttyACM0
baud_rate = 9600
[maze]
cycle = //---\\---
y0 = 300
dx = 100
dy = 100
width = 200
speed = 120
line_color = white
[player]
color = green
size = (50, 50)
left = 100
[keymap]
# key names from http://www.pygame.org/docs/ref/key.html (ignore prefix "K_")
move_player_up = w
move_player_down = d
reset_player_centery = SPACE
......@@ -2,87 +2,88 @@ from paigamu import *
import serial
import configparser
import ast
class ConfigIni(dict):
def __init__(self, filename):
self.parser = configparser.ConfigParser()
self.parser.read(filename)
self.update(**{section_name:
{k: self.safe_eval(v) for k,v in dict(section).items()}
for section_name, section in self.parser.items()})
def safe_eval(self, expr):
expr = expr.strip()
if expr[0] in '{([\'\"0123456789':
return ast.literal_eval(expr)
return expr
class AppLabirintoGame(GameApp):
RESOLUTION = (640, 480)
RESOLUTION = (800, 600)
FRAMERATE = 0
CONFIG_FILENAME = 'config.ini'
def on_setup(self):
self.config = configparser.ConfigParser()
self.config.read('config.ini')
self.config = ConfigIni(self.CONFIG_FILENAME)
self.config['keymap'] = {k: getattr(pygame, 'K_' + v)
for k, v in self.config['keymap'].items()}
print(self.config)
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())))
self.main_scene = MainScene(app=self, surface=self.screen)
self.joystick_respirometro = JoystickRespirometro(
**self.config['joystickrespirometro'])
if self.joystick_respirometro.enabled:
self.main_scene['player'].control_with = 'joystick'
else:
print("Using keyboard controls instead.")
def on_gameloop(self):
self.timer_fps.update()
self.main_scene.update()
self.main_scene.draw()
def on_keydown_event(self, event):
if event.key == pygame.K_SPACE:
if event.key == self.config['keymap']['reset_player_centery']:
self.main_scene['player'].centery = self.main_scene.rect.centery
# self.main_scene['player'].handle_keydown()
if event.key == pygame.K_DOWN:
self.main_scene['player'].y += 50
if event.key == pygame.K_UP:
self.main_scene['player'].y -= 50
class MainScene(Scene):
maze_speed = 150
def is_keymap_pressed(self, name):
return self.is_key_pressed(self.config['keymap'][name])
class MainScene(Scene):
def on_setup(self):
self['player'] = PlayerSprite(
color='green',
size=(50, 50),
left=100,
centery=self.rect.centery,
accel=Vec2D(0, 4*self.maze_speed),
keymap={'up': 'K_w', 'down': 'K_s'},
serial_joystick=dict(self.app.config['serial']))
self['top_maze'] = MazeSprite(
points=[(0, 200), (200, 0), (400, 200), (600, 0), (800, 200)],
line_color='white',
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=[-self.maze_speed, 0])
self['bottom_maze'].shift(dy=50)
self['top_maze'] = MazeSprite(**self.app.config['maze'])
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'
self['bottom_maze'] = MazeSprite(yshift=1, **self.app.config['maze'])
if self['bottom_maze'].collide_with_rect(self['player']):
self['bottom_maze'].color_state = 'colliding'
else:
self['bottom_maze'].color_state = 'normal'
self['player'] = PlayerSprite(
centery=self.rect.centery,
accel=Vec2D(0, 4*self['top_maze'].speed),
**self.app.config['player'])
class MazeSprite(PathSprite):
running_x = True
yshift = 0
COLORS = {'normal': Color('white'), 'colliding': Color('red')}
color_state = 'normal'
def update(self):
self.run(self.app.dt)
if self[-1].x <= self.scene.rect.right:
self.append(Vec2D(self[-1].x + 200, self[-2].y))
if self[1].x <= self.scene.rect.left:
del self[0]
@property
def line_color(self):
return self.COLORS[self.color_state]
......@@ -91,6 +92,37 @@ class MazeSprite(PathSprite):
def line_color(self, value):
pass
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
kwargs['points'] = self.get_cycle_points()
super().__init__(**kwargs)
self.vel = Vec2D(-self.speed, 0)
def update(self):
self.run(self.app.dt)
if self[-1].x < self.scene.rect.right:
self.extend(self.get_cycle_points(x0=self.scene.rect.right))
if self[1].x < self.scene.rect.left:
del self[0]
self.color_state = 'colliding' if self.collide_with_rect(
self.scene['player']) else 'normal'
def get_cycle_points(self, x0=0):
points = [Vec2D(x0, self.y0 + (self.width if self.yshift else 0))]
for c in self.cycle:
last = points[-1]
if c == '/':
new = (last[0] + self.dx, last[1] - self.dy)
if c == '\\':
new = (last[0] + self.dx, last[1] + self.dy)
if c == '-':
new = (last[0] + self.dx, last[1])
points.append(Vec2D(*new))
return points
class PlayerSprite(Sprite):
running = False
......@@ -98,41 +130,27 @@ class PlayerSprite(Sprite):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.handle_controls = {'joystick': self.handle_joystick,
'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']))
self.control_handlers = {'joystick': self.handle_joystick,
'keyboard': self.handle_keypress}
def update(self):
self.handle_controls[self.control_with]()
self.control_handlers[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.vel.ymag >= self.scene.maze_speed):
self.vel.ymag = self.scene.maze_speed
def handle_keydown(self, event):
if event.key == pygame.K_DOWN:
self.vel.j, self.running = 1, True
if event.key >= pygame.K_UP:
self.vel.j, self.running = -1, True
if (self.vel.ymag >= self.scene['top_maze'].speed):
self.vel.ymag = self.scene['top_maze'].speed
def handle_keypress(self):
if self.app.is_key_pressed(self.keymap['down']):
if self.app.is_keymap_pressed('move_player_down'):
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']):
elif self.app.is_keymap_pressed('move_player_up'):
if self.accel.j != -1:
self.accel.j = self.vel.j = -1
self.vel.ymag = 0
......@@ -141,28 +159,26 @@ class PlayerSprite(Sprite):
self.running = False
def handle_joystick(self):
self.joystick_respirometro.update()
self.app.joystick_respirometro.update()
if self.joystick_respirometro.inhaling():
self.accel.j = self.vel.j = 1
self.running = True
elif self.joystick_respirometro.exhaling():
if self.app.joystick_respirometro.inhaling():
self.accel.j = self.vel.j = -1
self.running = True
elif self.app.joystick_respirometro.exhaling():
self.accel.j = self.vel.j = 1
self.running = True
else:
self.running = False
class JoystickRespirometro:
_STATES = {'in': 1, 'ex': -1, 'idle': 0}
_STATESR = {1: 'in', -1: 'ex', 0: 'idle'}
_AMPLITUDE = 2
AMPLITUDE = 2
def __init__(self, port, baud):
def __init__(self, serial_port, baud_rate):
self._state = 0
self._last_read = 0
try:
self._sercon = serial.Serial(port, baud, timeout=1)
self._sercon = serial.Serial(serial_port, baud_rate, timeout=1)
self._enabled = True
self.timer = Timer(dt=0.2, callback=self.refresh)
except Exception as e:
......@@ -174,10 +190,10 @@ class JoystickRespirometro:
return self._enabled
def inhaling(self):
return self._state == self._STATES['in']
return self._state == 'in'
def exhaling(self):
return self._state == self._STATES['ex']
return self._state == 'ex'
def refresh(self):
if not self._enabled: return
......@@ -187,18 +203,18 @@ class JoystickRespirometro:
except Exception as e:
print('[SerialReadError] {}: {}'.format(e.__class__.__name__, e))
return
dv = (read - self._last_read)
self._last_read = read
if dv > self._AMPLITUDE:
self._state = self._STATES['ex']
elif dv < -self._AMPLITUDE:
self._state = self._STATES['in']
if dv > self.AMPLITUDE:
self._state = 'in'
elif dv < -self.AMPLITUDE:
self._state = 'ex'
else:
self._state = self._STATES['idle']
self._last_read = read
self._state = 'idle'
print(read, dv, self._STATESR[self._state])
print(read, dv, self._state)
def update(self):
if self._enabled:
......
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