Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/character.py
blob: d0f64e223817ff0a4dfd91ca8ff26da5ef515b8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from gi.repository import Gtk
import cairo
from gi.repository import Rsvg

from sugar3.graphics import style

class Sprite(object):
    def __init__(self, svg_file, cel_width, cel_height, animation_data):
        self.svg_file = svg_file
        self.cel_width, self.cel_height = cel_width, cel_height
        self.current_animation = None
        self.direction = 1

        self._animation_data = animation_data
        self._current_data = None
        self._animation_index = None

        self.load_svg()

    def load_svg(self):
        self._svg = Rsvg.Handle.new_from_file(self.svg_file)
        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.cache_inv_context.translate(-self._svg.props.width, 0)
        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
        if self.direction == -1:
            self._current_data = list(reversed(self._current_data))

    def next_frame(self):
        if self._animation_index + 1 == len(self._current_data):
            self._animation_index = 0
        else:
            self._animation_index += 1

    def draw(self, context, dx, dy):
        cel_x, cel_y = self._current_data[self._animation_index]

        # another context to draw only one cell
        self.one_cell = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                self.cel_width, self._svg.props.height)
        self.one_cell_context = cairo.Context(self.one_cell)

        if self.direction == 1:
            self.one_cell_context.set_source_surface(self.cache,
                    -cel_x * self.cel_width, 0)
        else:
            self.one_cell_context.set_source_surface(self.cache_inv,
                    -cel_x * self.cel_width, 0)

        self.one_cell_context.paint()

        context.translate(dx, dy)
        context.set_source_surface(self.one_cell)
        context.rectangle(0, 0, self.cel_width, self.cel_height)
        context.clip()
        context.paint()


class Character(object):
    def __init__(self, drawing_area):
        super(Character, self).__init__()
        self._drawing_area = drawing_area
        self.speed = 10
        animation_data = {
            'stand': [(0, 0)],
            'walk': [(1, 0), (2, 0), (3, 0), (4, 0),
                     (5, 0), (6, 0), (7, 0), (8, 0)],
        }
        self.sprite = Sprite("images/char_walking.svg",
                             100, 160, animation_data)
        self.sprite.change_animation('walk')

        self.pos = [0, 0]
        self.direction = 1  # -1 for left, 1 for right

    def update(self):
        self.sprite.direction = self.direction
        self.sprite.next_frame()
        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
        context.save()

        # for debug write a rectangle around
        """
        context.rectangle(dx, dy, self.sprite.cel_width,
                self.sprite.cel_height)
        stroke = (0, 0, 0)
        context.set_source_rgb(*stroke)
        context.stroke()
        """
        self.sprite.draw(context, dx, dy)
        context.restore()

def draw(dr, ctx, character):
    character.draw(ctx)


def main():
    def _destroy_cb(widget, data=None):
        Gtk.main_quit()

    window = Gtk.Window()
    window.resize(600, 160)
    window.connect("destroy", _destroy_cb)
    dr = Gtk.DrawingArea()
    character = Character(dr)
    character.pos = [style.GRID_CELL_SIZE, 140]
    dr.connect('draw', draw, character)
    window.add(dr)
    window.show_all()

    Gtk.main()


if __name__ == "__main__":
    main()