#! /usr/bin/env python # encoding: utf-8 import flappy from flappy.display import Sprite, Bitmap, BitmapData, Tilesheet from flappy.events import Event, MouseEvent from flappy.geom import Rectangle, Point import math import random from time import time WIDTH = 1000 HEIGHT = 600 START_PARASPRITES = 5 MAX_PARASPRITES = 1000 class ParaspritesExample(Sprite): def __init__(self): super(ParaspritesExample, self).__init__() background = Bitmap(BitmapData.load('./resources/ponyville.jpg')) background.width = WIDTH background.height = HEIGHT self.addChild(background) self.tile_layer = Sprite() self.addChild(self.tile_layer) parasprites_bd = BitmapData.load('./resources/parasprite_sheet.png') self.parasprites_ts = Tilesheet(parasprites_bd) twidth = parasprites_bd.width / 4.0 theight = parasprites_bd.height / 3.0 for i in range(3): for j in range(4): self.parasprites_ts.addTileRect( Rectangle(twidth * j, theight * i, twidth, theight), Point(twidth * 0.5, theight * 0.5)) self.parasprites = [ ] for i in range(START_PARASPRITES): self.parasprites.append( Parasprite( random.uniform(WIDTH * 0.1, WIDTH * 0.9), random.uniform(HEIGHT * 0.1, HEIGHT * 0.9), )) self.addEventListener(Event.ENTER_FRAME, self.on_enter_frame) self.tile_layer.addEventListener(MouseEvent.CLICK, self.on_click) self.old_time = time() def on_enter_frame(self, event): new_time = time() dt = new_time - self.old_time tilesheet_data = [] for parasprite in self.parasprites: parasprite.process(dt) tilesheet_data += parasprite.get_tile_data() self.tile_layer.graphics.clear() self.tile_layer.graphics.drawTiles( self.parasprites_ts, tilesheet_data, Tilesheet.TILE_ROTATION | \ Tilesheet.TILE_SCALE | \ Tilesheet.TILE_SMOOTH) self.old_time = new_time def on_click(self, event): if len(self.parasprites) <= MAX_PARASPRITES: self.parasprites.append(Parasprite(event.stageX, event.stageY)) class Parasprite(object): ANIM_TIME = 0.025 NFRAMES = 4 RADIUS = 25.0 def __init__(self, x, y): self.x, self.y = x, y self.frame_time = 0.0 self.frame = 0 self.anim_dir = 1 self.tileset = random.randint(0, 2) self.speed = random.uniform(80.0, 250.0) direction_angle = random.uniform(0.0, math.pi * 2.0) self.direction_x = math.cos(direction_angle) self.direction_y = math.sin(direction_angle) self.rotation = random.uniform(-math.pi * 0.2, math.pi * 0.2) self.scale = random.uniform(1.0, 1.2) self.radius = self.RADIUS * self.scale def process(self, dt): self.frame_time += dt if self.frame_time >= self.ANIM_TIME: self.frame_time = 0.0 self.frame += self.anim_dir if not (0 <= self.frame < self.NFRAMES): self.frame -= self.anim_dir self.anim_dir = -self.anim_dir self.x += self.speed * dt * self.direction_x self.y += self.speed * dt * self.direction_y if not (self.radius < self.x < (WIDTH - self.radius)): self.direction_x = -self.direction_x self.x = max(self.radius, min(WIDTH - self.radius, self.x)) if not (self.radius < self.y < (HEIGHT - self.radius)): self.direction_y = -self.direction_y self.y = max(self.radius, min(HEIGHT - self.radius, self.y)) def get_tile_data(self): return [ self.x, self.y, self.tileset * self.NFRAMES + self.frame, self.scale, self.rotation, ] if __name__ == '__main__': flappy.start(ParaspritesExample, width=WIDTH, height=HEIGHT, title=__file__)