To support the display of a large number of images at once, Ren'Py supports a sprite system. This system allows one to create sprites, where each sprite contains a displayable. The sprites can then have their location on the screen and vertical ordering changed.
If one ignores performance, the sprite system is conceptually similar
Transform()s. Sprites are much
faster than transforms, but also less flexible. The big performance
improvement of sprites is that each Displayable is rendered only once
per frame, even if that Displayable is used by many sprites. The limitation
is that Sprites only allow one to change their xoffset and yoffset, rather
than the many properties that a Transform has.
To use the sprite system, create a SpriteManager object, and then call its create method to create new particles. As necessary, update the xoffset, yoffset, and zorder fields of each sprite to move it around the screen. By supplying update and event arguments to SpriteManager, you can have the sprites change over time, and react to user input.
This represents a sprite that is managed by the SpriteManager. It contains
fields that control the placement of the sprite on the screen. Sprites
should not be created directly. Instead, they should be created by
The fields of a sprite object are:
The methods of a Sprite object are:
Destroys this sprite, preventing it from being displayed and removing it from the SpriteManager.
Changes the Displayable associated with this sprite to d.
SpriteManager(update=None, event=None, predict=None, ignore_time=False, **properties) link
This displayable manages a collection of sprites, and displays them at the fastest speed possible.
After being rendered once (before the update function is called), SpriteManagers have the following fields:
The width and height of this SpriteManager, in pixels.
SpriteManagers have the following methods:
Creates a new Sprite for the displayable d, and adds it to this SpriteManager.
Causes this SpriteManager to be redrawn in delay seconds.
SnowBlossom(d, count=10, border=50, xspeed=(20, 50), yspeed=(100, 200), start=0, fast=False, horizontal=False) link
The snowblossom effect moves multiple instances of a sprite up, down, left or right on the screen. When a sprite leaves the screen, it is returned to the start.
The SnowBlossom class is an easy-to use way of placing falling things on the screen.
image snow = SnowBlossom("snow.png", count=100)
This example shows how a SpriteManager can be used to create complex behaviors. In this case, it shows 400 particles, and has them avoid the mouse.
init python: import math def repulsor_update(st): # If we don't know where the mouse is, give up. if repulsor_pos is None: return .01 px, py = repulsor_pos # For each sprite... for i in repulsor_sprites: # Compute the vector between it and the mouse. vx = i.x - px vy = i.y - py # Get the vector length, normalize the vector. vl = math.hypot(vx, vy) if vl >= 150: continue # Compute the distance to move. distance = 3.0 * (150 - vl) / 150 # Move i.x += distance * vx / vl i.y += distance * vy / vl # Ensure we stay on the screen. if i.x < 2: i.x = 2 if i.x > repulsor.width - 2: i.x = repulsor.width - 2 if i.y < 2: i.y = 2 if i.y > repulsor.height - 2: i.y = repulsor.height - 2 return .01 # On an event, record the mouse position. def repulsor_event(ev, x, y, st): store.repulsor_pos = (x, y) label repulsor_demo: python: # Create a sprite manager. repulsor = SpriteManager(update=repulsor_update, event=repulsor_event) repulsor_sprites = [ ] repulsor_pos = None # Ensure we only have one smile displayable. smile = Image("smile.png") # Add 400 sprites. for i in range(400): repulsor_sprites.append(repulsor.create(smile)) # Position the 400 sprites. for i in repulsor_sprites: i.x = renpy.random.randint(2, 798) i.y = renpy.random.randint(2, 598) del smile del i # Add the repulsor to the screen. show expression repulsor as repulsor "..." hide repulsor # Clean up. python: del repulsor del repulsor_sprites del repulsor_pos