#! /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 . # # 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 = list() 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 while self._timeline.get_time(self._tl_index) <= \ time - self._loop_time - self._pause_time: ev = self._timeline.get_event(self._tl_index) ob = self._timeline.get_object(self._tl_index) pa = self._timeline.get_params(self._tl_index) try: if pa == None: getattr(ob,ev)() else: getattr(ob,ev)(pa) except: print("Event " + ev + " not defined in object " + str(ob)) if ev == 'show': self._active_objects.append(ob) self._active_objects.sort(key=lambda ob:ob.get_layer()) elif ev == 'hide': self._active_objects.remove(ob) elif ev == 'pause': self.pause() # 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) # 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