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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
#! /usr/bin/env python
# Rayito player
# Copyright (C) 2011 Gabriel Eirea
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Contact information:
# Gabriel Eirea geirea@gmail.com
# Ceibal Jam http://ceibaljam.org
import pygame
import RtoObject
import RtoTimeLine
class RtoPlayer():
""" Class for rayito player.
RtoPlayer(size, position, timeline, loop = False)
where:
size = canvas size
position = upper-left coordinates in the screen
timeline = RtoTimeLine object with objects and events
loop = boolean that indicates whether the player loops or not
bg_image = pygame surface with background image
bg_color = background color to use if image not present
"""
def __init__(self, size, position, timeline, loop = False,
bg_image = None, bg_color = (0, 0, 0)):
self._size = size
self._position = position
self._timeline = timeline
self._finished = False
self._canvas = pygame.Surface(size)
self._last_update = 0
self._active_objects = set()
self._tl_index = 0
self._tl_length = self._timeline.get_length()
self._loop = loop
self._loop_time = 0
self._bg_image = bg_image
self._bg_color = bg_color
self._paused = True
self._pause_time = 0
self._start_pause = pygame.time.get_ticks()
def pause(self):
self._start_pause = pygame.time.get_ticks()
self._paused = True
def play(self):
self._pause_time += pygame.time.get_ticks() - self._start_pause
self._paused = False
def is_finished(self):
return self._finished
def is_paused(self):
return self._paused
def update(self, time):
""" Update the player at one time step.
Reads all events between last call and current call, executes
the actions, updates the objects, and renders all active objects on
the canvas.
"""
if self._paused or self._finished:
return
# read events between last_update and time
# TODO: must be generalized
while self._timeline.get_time(self._tl_index) <= \
time - self._loop_time - self._pause_time:
if self._timeline.get_event(self._tl_index) == 'show':
self._active_objects.add(self._timeline.get_object(self._tl_index))
self._timeline.get_object(self._tl_index).show()
elif self._timeline.get_event(self._tl_index) == 'hide':
self._active_objects.remove(self._timeline.get_object(self._tl_index))
self._timeline.get_object(self._tl_index).hide()
elif self._timeline.get_event(self._tl_index) == 'move_by':
self._timeline.get_object(self._tl_index).move_by(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'move_to':
self._timeline.get_object(self._tl_index).move_to(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'scale_by':
self._timeline.get_object(self._tl_index).scale_by(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'scale_to':
self._timeline.get_object(self._tl_index).scale_to(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'flip_hor':
self._timeline.get_object(self._tl_index).flip_hor()
elif self._timeline.get_event(self._tl_index) == 'flip_ver':
self._timeline.get_object(self._tl_index).flip_ver()
elif self._timeline.get_event(self._tl_index) == 'rotate':
self._timeline.get_object(self._tl_index).rotate(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'move_start':
self._timeline.get_object(self._tl_index).move_start(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'move_stop':
self._timeline.get_object(self._tl_index).move_stop()
elif self._timeline.get_event(self._tl_index) == 'next_text':
self._timeline.get_object(self._tl_index).next_text()
elif self._timeline.get_event(self._tl_index) == 'restart':
self._timeline.get_object(self._tl_index).restart()
elif self._timeline.get_event(self._tl_index) == 'update_frame':
self._timeline.get_object(self._tl_index).update_frame(
self._timeline.get_params(self._tl_index))
elif self._timeline.get_event(self._tl_index) == 'pause':
self.pause()
elif self._timeline.get_event(self._tl_index) == 'play':
self._timeline.get_object(self._tl_index).play()
# update index and check boundary
self._tl_index += 1
if self._tl_index == self._tl_length:
if self._loop:
self._tl_index = 0
self._loop_time = time
else:
self._finished = True
break
# update all active objects
for obj in self._active_objects:
obj.update(time - self._loop_time - self._pause_time)
# update time and return
self._last_update = time
def render(self, screen):
# erase canvas
# TODO: can be optimized with dirty rectangles
if self._bg_image:
self._canvas.blit(self._bg_image, (0,0))
else:
self._canvas.fill(self._bg_color)
# TODO: order active objects by layer
# render active objects on canvas
for obj in self._active_objects:
obj.render(self._canvas)
# render canvas on screen
screen.blit(self._canvas, self._position)
def new_timeline(self, timeline, loop = False):
self._timeline = timeline
self._finished = False
self._active_objects = set()
self._tl_index = 0
self._tl_length = self._timeline.get_length()
self._loop = loop
self._loop_time = 0
self._paused = True
self._pause_time = 0
self._start_pause = pygame.time.get_ticks()
def pressed(self, pos):
pos_in_canvas = (pos[0]-self._position[0], pos[1]-self._position[1])
for obj in self._active_objects:
if obj.is_pressed(pos_in_canvas):
return obj # assuming only one object at pos
return None
if __name__ == "__main__":
pass
|