ENTRY | DOWNLOAD | MANUAL | ONGOING | |
SpriteThe idea behind sprites is to offer a simple way of creating something like sub-worlds within the main world. Each sprite has its own local coordinate system, mouse events, lights and materials and can in many respects be treated like the main world. Just as the main world, a sprite has an onDraw() which gets called on every frame. The convenience of using sprites is that transformations can be made in relation to the sprite and not the world. By using sprites, a moon would only need to know how to move in relation to the earth sprite and would not have to care about its orbit overlapping with the orbit of the earth. Sprites are also a convenient way of checking whether the mouse is over a specific graphical object. Each sprite fires various mouse events that precisely reflect how the mouse is interacting with the content of the sprite.
Redraw Event:
onDraw() Mouse Events: onMouseMove() onMouseButtonUp() onMouseButtonDown() onMouseIn() onMouseOut() onMouseDrag() Relevant examples: sprite.py , sprite_all.py solarsystem.py ALL In Contextfrom slut import * class Atlantis(World): def onSetup(self): self.name = "Sprite" self.width = 800 self.height = 300 Disc(self, 'sprite1') p2 = Disc(self, 'sprite2') p2.moveBy(-0.5, 0.0, -1.5) p2.enableMouseEvents() class Disc(Sprite): def onDraw(self): disc(0, 0, 0, 1) def onMouseIn(self, event): print "The mouse has been moved over the sprite" print "with name: " + self.name atlantis = Atlantis() atlantis.run() Sprites may also be nested in other sprites resulting in a 3D-modeler-typical scene graph (or DAG). Sprites are added to the scene by simply instancing them. Since the first argument is a reference to the world (or another sprite) they know how to add themselves to the scene. In many cases it is customary not to manually assign the sprite instance to a variable but to use the dictionary where the world keeps track of them: self.sprites. This dictionary uses the sprite's name as the key to the sprite instance. ASpriteClass(self, 'sprite1') theNewSprite = self.sprites['sprite1'] On the other hand there are occasions in which it makes sense to use a separate variable to hold the reference to the new sprite: anewsprite = ASpriteClass(self, 'sprite1') theNewSprite = anewsprite Sprite objects are usually instanced from a custom class (like Disc in the above example) that defines the characteristics (what it draws, how it reacts to the mouse) of that sprite. The only requirement for that custom sprite class is that it inherits from slut.sprite.Sprite. Just as shapes that are drawn directly in the world, shapes in a sprite are redrawn multiple times a second via repeated calls to onDraw(). Once a sprite has been added to the scene it can be moved, rotated and scaled as a whole. Transformation methods come in two flavors--relative and absolute. Relative methods always operate on the sprite by adding to the current position/scale while absolute methods take the passed (x, y, z) values and make them the new position/scale. The passed arguments are units of the coordinate system where the sprite was created. This is either the world or another sprite. Arguments for rotation and orbiting methods are always in degrees (with 360 being one rotation). spriteobject.moveBy(-2.5, 0.0, 0.0) spriteobject.rotTo(0.0, 180.0, 0.0) spriteobject.orbitTo(0.0, 90.0, 0.0) The above code snippet moves the sprite (along the x-axis) -2.5 units away from the origin, then rotates the sprite around its own y-axis by 180 degrees, and finally orbits it around the origin by 90 degrees (on an ecliptic that is perpendicular to the y-axis).
Note:
Orbiting always occurs around the origin of
the coordinate system where the sprite was created. If the sprite
was not moved away from the origin, orbiting is equivalent to
rotation.
Alternatively, transformation arguments can be specified with Tween and Thrust objects. |
|
Initiated by Stephan Hechenberger Thanks to CADRE's 103 |