Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2012-05-02 04:31:23 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2012-05-02 04:31:23 (GMT)
commit6d9cbdc157e0b7d0a0fdf807ec8dfb2d510f2edb (patch)
tree68d50bd790e210614e222c234811edf7ce997623
parent86a0f2454fa3a9b255cabdcd3f7ab362746925d0 (diff)
Start movement of character in play mode
Now the character does not walk all time left and right, but wait to a click, and go to the place, if the click is over a lateral wall or over a door, the character walk and later the map change to the new selected vision. Is not working all right now. When the character go to the left the svg is not rendered. A posible solution using to ImageSurfaces to cache te rendering is commented in character.py Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org>
-rw-r--r--character.py59
-rw-r--r--mapnav.py96
-rw-r--r--stateview.py3
3 files changed, 122 insertions, 36 deletions
diff --git a/character.py b/character.py
index cf3c2ce..a4daa5c 100644
--- a/character.py
+++ b/character.py
@@ -1,3 +1,5 @@
+import logging
+
import gtk
from gtk import gdk
import gobject
@@ -10,7 +12,7 @@ class Sprite(object):
self.svg_file = svg_file
self.cel_width, self.cel_height = cel_width, cel_height
self.current_animation = None
- self.flip_x = None
+ self.direction = 1
self._animation_data = animation_data
self._current_data = None
@@ -20,13 +22,30 @@ class Sprite(object):
def load_svg(self):
self._svg = rsvg.Handle(file=self.svg_file)
-
- def change_animation(self, animation_name, flip_x=1):
+ self._svg_width = self._svg.props.width
+ """
+ # create a cache with the image rendered
+ self.cache = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ self._svg.props.width, self._svg.props.height)
+ self.cache_context = cairo.Context(self.cache)
+ self._svg.render_cairo(self.cache_context)
+ self.cache.flush()
+
+ # and another with a flipped render
+ self.cache_inv = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ self._svg.props.width, self._svg.props.height)
+ self.cache_inv_context = cairo.Context(self.cache_inv)
+ self.cache_inv_context.scale(-1, 1)
+ self._svg.render_cairo(self.cache_inv_context)
+ self.cache_inv.flush()
+ """
+
+ def change_animation(self, animation_name, direction=1):
self.current_animation = animation_name
self._current_data = self._animation_data[animation_name]
self._animation_index = 0
- self.flip_x = flip_x
- if flip_x == -1:
+ #self.direction = direction
+ if self.direction == -1:
self._current_data = list(reversed(self._current_data))
def next_frame(self):
@@ -37,18 +56,22 @@ class Sprite(object):
def draw(self, context, dx, dy):
cel_x, cel_y = self._current_data[self._animation_index]
- context.scale(self.flip_x, 1)
-
+ context.scale(self.direction, 1)
+ #if self.direction == 1:
+ # context.set_source_surface(self.cache)
+ #else:
+ # context.set_source_surface(self.cache_inv)
context.translate(dx, dy)
- context.translate(-cel_x * self.cel_width * self.flip_x,
+ context.translate(-cel_x * self.cel_width * self.direction,
-cel_y * self.cel_height)
- context.rectangle(cel_x * self.cel_width * self.flip_x,
+ context.rectangle(cel_x * self.cel_width * self.direction,
cel_y * self.cel_height,
self.cel_width, self.cel_height)
- if self.flip_x == -1:
- context.translate(-900, 0)
+ if self.direction == -1:
+ context.translate(-self._svg_width, 0)
context.clip()
+ #context.paint()
self._svg.render_cairo(context)
@@ -67,11 +90,12 @@ class Character(object):
self.sprite.change_animation('walk')
self.pos = [0, 0]
- self.direction = -1 # -1 for left, 1 for right
+ self.direction = 1 # -1 for left, 1 for right
def update(self):
+ self.sprite.direction = self.direction
self.sprite.next_frame()
-
+ """
if self.direction == 1 and self.pos[0] > 600:
self.pos[0] += self.sprite.cel_width
self.direction = -1
@@ -81,18 +105,19 @@ class Character(object):
self.direction = 1
self.sprite.change_animation('walk')
else:
- self.pos[0] += self.speed * self.direction
+ """
+ self.pos[0] += self.speed * self.direction
return (self.pos[0],
self.pos[1] - self.sprite.cel_height + 10,
self.sprite.cel_width, self.sprite.cel_height)
def draw(self, context):
# draw char
- dx, dy = self.pos[0], \
- self.pos[1] - self.sprite.cel_height + 10
+ dx, dy = self.pos[0], self.pos[1] - self.sprite.cel_height + 10
# for debug write a rectangle around
- context.rectangle(dx, dy, self.sprite.cel_width, self.sprite.cel_height)
+ context.rectangle(dx, dy, self.sprite.cel_width,
+ self.sprite.cel_height)
stroke = (0, 0, 0)
context.set_source_rgb(*stroke)
context.stroke()
diff --git a/mapnav.py b/mapnav.py
index 8fd51e7..7cfb473 100644
--- a/mapnav.py
+++ b/mapnav.py
@@ -70,12 +70,15 @@ class MapNavView(gtk.DrawingArea):
self.connect('button_release_event', self.__button_release_event_cb)
self._character = Character(self)
+ self._is_walking = False
def size_allocate_cb(widget, allocation):
self.calculate_sizes(allocation.width, allocation.height)
if self.view_mode == self.MODE_PLAY:
character_y = allocation.height - self._grid_size
self._character.pos = [0, character_y]
+ self._character.direction = 1
+ self._character.change_animation('stand', flip_x=1)
self.disconnect(self._setup_handle)
self._setup_handle = self.connect('size_allocate',
@@ -85,13 +88,6 @@ class MapNavView(gtk.DrawingArea):
if self.view_mode == self.MODE_PLAY:
cell = style.GRID_CELL_SIZE / 2
self._state_view = StateView(self._model, cell, cell, cell)
- gobject.timeout_add(100, self._update_timer)
-
- def _update_timer(self):
- if self.is_drawable():
- rect = self._character.update()
- self.queue_draw_area(*rect)
- return True
def clear_cache(self):
self.cache_info = {}
@@ -176,11 +172,70 @@ class MapNavView(gtk.DrawingArea):
self.selected.y = event.y
self.update_wall_info(self.x, self.y, self.direction)
- if self.view_mode == self.MODE_EDIT:
+ if self.view_mode == self.MODE_PLAY and not self._is_walking:
# verify doors
+ if info_walls['have_door'] != []:
+ door_x = self._get_door_x()
+ door_y = self._get_door_y()
+ door_width = self._grid_size * self._door_width
+ door_height = self._grid_size * self._door_height
+ if door_x < event.x < door_x + door_width and \
+ door_y < event.y < door_y + door_height:
+ logging.error('Door clicked')
+ new_x, new_y, new_direction = self._game_map.cross_door(
+ self.x, self.y, self.direction)
+ self._move_character(door_x + door_width / 2, new_x,
+ new_y, new_direction)
+ # verify lateral walls
+ if event.x < self._grid_size:
+ logging.error('Left wall clicked')
+ new_x, new_y, new_direction = self._game_map.go_left(self.x,
+ self.y, self.direction)
+ self._move_character(0, new_x, new_y, new_direction)
+
+ elif event.x > self._width - self._grid_size:
+ logging.error('Right wall clicked')
+ new_x, new_y, new_direction = self._game_map.go_right(self.x,
+ self.y, self.direction)
+ self._move_character(self._width, new_x, new_y,
+ new_direction)
+ else:
+ self._move_character(event.x, self.x, self.y, self.direction)
+
+ def _move_character(self, character_destination, new_map_x, new_map_y,
+ new_map_direction):
+ """
+ Move the character to the next position,
+ if needed, because the character is going to another wall or
+ to a door, change the map view position
+ """
+ character_pos = self._character.pos[0]
+ if character_destination < character_pos:
+ self._character.direction = -1
+ else:
+ self._character.direction = 1
+ self._character_destination = character_destination
+ self._new_map_position = (new_map_x, new_map_y, new_map_direction)
+ gobject.timeout_add(100, self._update_timer)
- # verify lateral doors
- pass
+ def _update_timer(self):
+ self._is_walking = True
+ if self.is_drawable():
+ rect = self._character.update()
+ self.queue_draw_area(*rect)
+ finish = abs(self._character_destination - self._character.pos[0]) < \
+ self._character.speed
+ if finish:
+ self._is_walking = False
+ if (self.x, self.y, self.direction) != self._new_map_position:
+ self.x, self.y, self.direction = self._new_map_position
+ self.emit('position-changed', self.x, self.y, self.direction)
+ if self._character.pos[0] >= self._width - self._grid_size:
+ self._character.pos[0] = self._grid_size
+ elif self._character.pos[0] < self._grid_size:
+ self._character.pos[0] = self._width - self._grid_size
+ self.queue_draw()
+ return not finish
def __motion_notify_event_cb(self, widget, event):
if self.view_mode == self.MODE_EDIT:
@@ -345,13 +400,8 @@ class MapNavView(gtk.DrawingArea):
ctx.stroke()
if info_walls['have_door'] != []:
- if self.direction in ('N', 'W'):
- # door is at rigth of the wall
- x = self._width - self._grid_size * (self._door_width + 2)
- else:
- x = self._grid_size * 2
-
- self.draw_door(ctx, x, info_walls['have_door'])
+ x_door = self._get_door_x()
+ self.draw_door(ctx, x_door, info_walls['have_door'])
if info_walls['wall_cw']:
ctx.move_to(self._width - self._grid_size, 0)
@@ -446,8 +496,18 @@ class MapNavView(gtk.DrawingArea):
RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE)
ctx.stroke()
+ def _get_door_x(self):
+ if self.direction in ('N', 'W'):
+ # door is at rigth of the wall
+ return self._width - self._grid_size * (self._door_width + 2)
+ else:
+ return self._grid_size * 2
+
+ def _get_door_y(self):
+ return self._height - self._grid_size * (self._door_height + 1)
+
def draw_door(self, ctx, x, doors):
- y = self._height - self._grid_size * (self._door_height + 1)
+ y = self._get_door_y()
ctx.rectangle(x, y, self._grid_size * self._door_width,
self._grid_size * self._door_height)
fill = (style.Color('#8B6914').get_rgba())
diff --git a/stateview.py b/stateview.py
index 931ea3f..3a6624b 100644
--- a/stateview.py
+++ b/stateview.py
@@ -11,6 +11,7 @@ import cairo
import rsvg
import model
import math
+import logging
class StateView():
@@ -38,7 +39,7 @@ class StateView():
replied_questions = len(state['replied_questions'])
scale = float(self._svg_width) / float(self._cell_size)
- print "scale", scale
+ logging.error('draw stateview scale %s', scale)
ctx.save()
ctx.translate(self._x, self._y)
for n in range(cant_questions):