#! /usr/bin/env python # Rayito objects # 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 class RtoObject(): """ Class for rayito objects. position: (x, y) of upper-left corner in pixels layer: layer number, high is up, low is down """ def __init__(self, position, layer = 0): self._position = [position[0], position[1]] self._layer = layer self._visible = False self._moving = False self._velocity = (0, 0) self._last_update = 0 def hide(self): self._visible = False def show(self): self._visible = True def move_to(self, newpos): self._position = [newpos[0], newpos[1]] def move_by(self, relpos): self._position[0] += relpos[0] self._position[1] += relpos[1] def change_layer(self, new_layer): self._layer = new_layer def get_layer(self): return self._layer def move_start(self, vel): # vel should be in pixels per millisecond self._moving = True self._velocity = vel def move_stop(self): self._moving = False def update(self, time): pixels_x = int(self._velocity[0]*(time - self._last_update)) pixels_y = int(self._velocity[1]*(time - self._last_update)) if self._moving: self._position[0] += pixels_x self._position[1] += pixels_y self._last_update = time self.update_specific(time) def update_specific(self, time): pass def render(self, screen): pass def is_pressed(self, pos): return False class RtoImage(RtoObject): """ Class for rayito images. image: pygame surface with the image position: (x, y) of upper-left corner in pixels layer: layer number, high is up, low is down """ def __init__(self, image, position, layer = 0): RtoObject.__init__(self, position, layer) self._image = image def scale_to(self, target_size): w = self._image.get_width() h = self._image.get_height() center = (self._position[0]+int(w/2), self._position[1]+int(h/2)) tmp = pygame.transform.scale(self._image, target_size) wtmp = tmp.get_width() htmp = tmp.get_height() self._position = [center[0]-int(wtmp/2), center[1]-int(htmp/2)] self._image = tmp del tmp def scale_by(self, ratio): w = self._image.get_width() h = self._image.get_height() center = (self._position[0]+int(w/2), self._position[1]+int(h/2)) tmp = pygame.transform.scale(self._image, (int(self._image.get_width()*ratio), int(self._image.get_height()*ratio))) wtmp = tmp.get_width() htmp = tmp.get_height() self._position = [center[0]-int(wtmp/2), center[1]-int(htmp/2)] self._image = tmp del tmp def flip_hor(self): tmp = pygame.transform.flip(self._image, True, False) self._image = tmp del tmp def flip_ver(self): tmp = pygame.transform.scale(self._image, False, True) self._image = tmp del tmp def rotate(self, angle): w = self._image.get_width() h = self._image.get_height() center = (self._position[0]+int(w/2), self._position[1]+int(h/2)) tmp = pygame.transform.rotate(self._image, angle) wtmp = tmp.get_width() htmp = tmp.get_height() self._position = [center[0]-int(wtmp/2), center[1]-int(htmp/2)] self._image = tmp del tmp def render(self, screen): if self._visible: screen.blit(self._image,self._position) class RtoDialog(RtoObject): """Class for rayito dialogs text: list with text to display; each element can have \n to separate lines font: pygame font to use bg_color: background color (R, G, B) fg_color: text color (R, G, B) position: (x, y) of upper-left corner in pixels layer: layer number, high is up, low is down """ def __init__(self, text, font, bg_color, fg_color, position, layer = 0): RtoObject.__init__(self, position, layer) self._font = font self._text = text self._ntexts = len(text) self._current_text = 0 self._bg_color = bg_color self._fg_color = fg_color # compute size self._width = 0 self._height = 0 for t in self._text: lines = t.split("\n") lh = 0 for l in lines: (w, h) = self._font.size(l) if w > self._width: self._width = w lh += h if lh > self._height: self._height = lh self._width += 10 self._height += 10 # create empty background self._bg = pygame.Surface((self._width, self._height)) self._bg.fill(self._bg_color) # render first line of text self.next_text() def next_text(self): if self._current_text == self._ntexts: self.hide() return False self._image = self._bg.copy() yline = 5 for l in self._text[self._current_text].split("\n"): text_img = self._font.render(l, 1, self._fg_color) textrect = text_img.get_rect() textrect.left = 5 textrect.top = yline self._image.blit(text_img, textrect) yline += self._font.get_height() self._current_text += 1 return True def render(self, screen): if self._visible: screen.blit(self._image, self._position) def restart(self): self._current_text = 0 self.next_text() class RtoButton(RtoObject): """Class for rayito buttons text: text to display; can have \n to separate lines font: pygame font to use bg_color: background color (R, G, B) fg_color: text color (R, G, B) position: (x, y) of upper-left corner in pixels layer: layer number, high is up, low is down """ def __init__(self, text, font, bg_color, fg_color, position, layer = 0): RtoObject.__init__(self, position, layer) self._font = font self._text = text self._bg_color = bg_color self._fg_color = fg_color # compute size self._width = 0 self._height = 0 lines = self._text.split("\n") for l in lines: (w, h) = self._font.size(l) if w > self._width: self._width = w self._height += h self._width += 10 self._height += 10 # create empty background self._image = pygame.Surface((self._width, self._height)) self._image.fill(self._bg_color) yline = 5 for l in self._text.split("\n"): text_img = self._font.render(l, 1, self._fg_color) textrect = text_img.get_rect() textrect.left = 5 textrect.top = yline self._image.blit(text_img, textrect) yline += h def render(self, screen): if self._visible: screen.blit(self._image, self._position) def is_pressed(self, pos): if pos[0] > self._position[0] \ and pos[0] < self._position[0] + self._width \ and pos[1] > self._position[1] \ and pos[1] < self._position[1] + self._height: return True else: return False class RtoSprite(RtoObject): """Class for rayito sprites. images: list with sprite images (each one a pygame surface) frames: list with image# for every frame next_frames: list with next frame from current one dxs: list with dx for current frame (in pixels) dys: list with dy for current frame (in pixels) position: (x, y) of upper-left corner in pixels layer: layer number, high is up, low is down """ def __init__(self, images, frames, next_frames, dxs, dys, position, layer = 0): RtoObject.__init__(self, position, layer) self._images = images self._frames = frames self._next_frames = next_frames self._dxs = dxs self._dys = dys self._frame = 0 self._image = self._images[self._frames[self._frame]] def update_specific(self, time): self._position[0] += self._dxs[self._frame] self._position[1] += self._dys[self._frame] self._frame = self._next_frames[self._frame] self._image = self._images[self._frames[self._frame]] self._last_update = time def render(self, screen): screen.blit(self._image, self._position) def update_frame(self, fr): self._frame = fr class RtoSound(): """Class for rayito sounds. sound: pygame.mixer.Sound object volume: volume (between 0 and 1) """ def __init__(self, sound, volume = 1): self._sound = sound self._volume = volume def play(self): self._sound.play() def set_volume(self, vol): if vol >= 0 and vol <= 1: self._sound.set_volume(vol) def update(self, time): pass