changeset 439:723a3e67a223

Make pytouhou.game.sprite an extension type.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 10 Aug 2013 20:48:17 +0200
parents 43a8fed9a8d8
children b9d2db93972f
files pytouhou/game/item.py pytouhou/game/sprite.pxd pytouhou/game/sprite.py pytouhou/game/text.py pytouhou/ui/sprite.pxd pytouhou/ui/sprite.pyx
diffstat 6 files changed, 92 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/item.py
+++ b/pytouhou/game/item.py
@@ -14,7 +14,6 @@
 
 
 from math import cos, sin, atan2, pi
-from copy import copy
 
 from pytouhou.utils.interpolator import Interpolator
 
@@ -23,7 +22,7 @@ class Indicator(object):
     def __init__(self, item):
         self._item = item
 
-        self.sprite = copy(item._item_type.indicator_sprite)
+        self.sprite = item._item_type.indicator_sprite.copy()
         self.removed = False
 
         self.frame = 0
new file mode 100644
--- /dev/null
+++ b/pytouhou/game/sprite.pxd
@@ -0,0 +1,24 @@
+from pytouhou.utils.interpolator cimport Interpolator
+
+cdef class Sprite:
+    cdef public long width_override, height_override, blendfunc, frame
+    cdef public double angle
+    cdef public bint removed, changed, visible, force_rotation
+    cdef public bint automatic_orientation, allow_dest_offset, mirrored
+    cdef public bint corner_relative_placement
+    cdef public Interpolator scale_interpolator, fade_interpolator
+    cdef public Interpolator offset_interpolator, rotation_interpolator
+    cdef public Interpolator color_interpolator
+    cdef public tuple texcoords, dest_offset, texoffsets, rescale, scale_speed
+    cdef public tuple rotations_3d, rotations_speed_3d, color
+    cdef public unsigned char alpha
+    cdef public object anm, _rendering_data
+
+    cpdef fade(self, unsigned long duration, alpha, formula=*)
+    cpdef scale_in(self, unsigned long duration, sx, sy, formula=*)
+    cpdef move_in(self, unsigned long duration, x, y, z, formula=*)
+    cpdef rotate_in(self, unsigned long duration, rx, ry, rz, formula=*)
+    cpdef change_color_in(self, unsigned long duration, r, g, b, formula=*)
+    cpdef update_orientation(self, double angle_base=*, bint force_rotation=*)
+    cpdef Sprite copy(self)
+    cpdef update(self)
--- a/pytouhou/game/sprite.py
+++ b/pytouhou/game/sprite.py
@@ -12,20 +12,7 @@
 ## GNU General Public License for more details.
 ##
 
-
-from pytouhou.utils.interpolator import Interpolator
-
-
 class Sprite(object):
-    __slots__ = ('anm', 'removed', 'changed', 'width_override', 'height_override',
-                 'angle', 'force_rotation', 'scale_interpolator',
-                 'fade_interpolator', 'offset_interpolator',
-                 'rotation_interpolator', 'color_interpolator',
-                 'automatic_orientation', 'blendfunc', 'texcoords',
-                 'dest_offset', 'allow_dest_offset', 'texoffsets', 'mirrored',
-                 'rescale', 'scale_speed', 'rotations_3d',
-                 'rotations_speed_3d', 'corner_relative_placement', 'frame',
-                 'color', 'alpha', 'visible', '_rendering_data')
     def __init__(self, width_override=0, height_override=0):
         self.anm = None
         self.removed = False
@@ -64,31 +51,31 @@ class Sprite(object):
         self._rendering_data = None
 
 
-    def fade(self, duration, alpha, formula):
+    def fade(self, duration, alpha, formula=None):
         self.fade_interpolator = Interpolator((self.alpha,), self.frame,
                                               (alpha,), self.frame + duration,
                                               formula)
 
 
-    def scale_in(self, duration, sx, sy, formula):
+    def scale_in(self, duration, sx, sy, formula=None):
         self.scale_interpolator = Interpolator(self.rescale, self.frame,
                                                (sx, sy), self.frame + duration,
                                                formula)
 
 
-    def move_in(self, duration, x, y, z, formula):
+    def move_in(self, duration, x, y, z, formula=None):
         self.offset_interpolator = Interpolator(self.dest_offset, self.frame,
                                                 (x, y, z), self.frame + duration,
                                                 formula)
 
 
-    def rotate_in(self, duration, rx, ry, rz, formula):
+    def rotate_in(self, duration, rx, ry, rz, formula=None):
         self.rotation_interpolator = Interpolator(self.rotations_3d, self.frame,
                                                   (rx, ry, rz), self.frame + duration,
                                                   formula)
 
 
-    def change_color_in(self, duration, r, g, b, formula):
+    def change_color_in(self, duration, r, g, b, formula=None):
         self.color_interpolator = Interpolator(self.color, self.frame,
                                                (r, g, b), self.frame + duration,
                                                formula)
@@ -101,6 +88,44 @@ class Sprite(object):
             self.changed = True
 
 
+    def copy(self):
+        sprite = Sprite(self.width_override, self.height_override)
+
+        sprite.blendfunc = self.blendfunc
+        sprite.frame = self.frame
+        sprite.angle = self.angle
+
+        sprite.removed = self.removed
+        sprite.changed = self.changed
+        sprite.visible = self.visible
+        sprite.force_rotation = self.force_rotation
+        sprite.automatic_orientation = self.automatic_orientation
+        sprite.allow_dest_offset = self.allow_dest_offset
+        sprite.mirrored = self.mirrored
+        sprite.corner_relative_placement = self.corner_relative_placement
+
+        sprite.scale_interpolator = self.scale_interpolator
+        sprite.fade_interpolator = self.fade_interpolator
+        sprite.offset_interpolator = self.offset_interpolator
+        sprite.rotation_interpolator = self.rotation_interpolator
+        sprite.color_interpolator = self.color_interpolator
+
+        sprite.texcoords = self.texcoords
+        sprite.dest_offset = self.dest_offset
+        sprite.texoffsets = self.texoffsets
+        sprite.rescale = self.rescale
+        sprite.scale_speed = self.scale_speed
+        sprite.rotations_3d = self.rotations_3d
+        sprite.rotations_speed_3d = self.rotations_speed_3d
+        sprite.color = self.color
+
+        sprite.alpha = self.alpha
+        sprite.anm = self.anm
+        sprite._rendering_data = self._rendering_data
+
+        return sprite
+
+
     def update(self):
         self.frame += 1
 
@@ -122,7 +147,7 @@ class Sprite(object):
 
         if self.fade_interpolator:
             self.fade_interpolator.update(self.frame)
-            self.alpha = int(self.fade_interpolator.values[0])
+            self.alpha = self.fade_interpolator.values[0]
             self.changed = True
 
         if self.scale_interpolator:
--- a/pytouhou/game/text.py
+++ b/pytouhou/game/text.py
@@ -12,8 +12,6 @@
 ## GNU General Public License for more details.
 ##
 
-from copy import copy
-
 from pytouhou.game.sprite import Sprite
 from pytouhou.vm.anmrunner import ANMRunner
 from pytouhou.utils.interpolator import Interpolator
@@ -70,7 +68,7 @@ class GlyphCollection(Widget):
     def set_length(self, length):
         current_length = len(self.glyphes)
         if length > current_length:
-            self.glyphes.extend(Glyph(copy(self.ref_sprite),
+            self.glyphes.extend(Glyph(self.ref_sprite.copy(),
                                       (self.x + self.xspacing * i, self.y))
                                 for i in range(current_length, length))
         elif length < current_length:
--- a/pytouhou/ui/sprite.pxd
+++ b/pytouhou/ui/sprite.pxd
@@ -1,1 +1,3 @@
-cpdef object get_sprite_rendering_data(object sprite)
+from pytouhou.game.sprite cimport Sprite
+
+cpdef object get_sprite_rendering_data(Sprite sprite)
--- a/pytouhou/ui/sprite.pyx
+++ b/pytouhou/ui/sprite.pyx
@@ -13,21 +13,25 @@
 ##
 
 
-from math import pi
+from libc.math cimport M_PI as pi
 
 from pytouhou.utils.matrix cimport Matrix
 
 
-cpdef object get_sprite_rendering_data(object sprite):
+cpdef object get_sprite_rendering_data(Sprite sprite):
     cdef Matrix vertmat
+    cdef double tx, ty, tw, th, sx, sy, rx, ry, rz, tox, toy
+    cdef object tmp1, tmp2
 
     if not sprite.changed:
         return sprite._rendering_data
 
-    vertmat = Matrix([-.5,  .5,  .5, -.5,
-                      -.5, -.5,  .5,  .5,
-                       .0,  .0,  .0,  .0,
-                       1.,  1.,  1.,  1.])
+    tmp1 = .5
+    tmp2 = -.5
+    vertmat = Matrix([tmp2, tmp1, tmp1, tmp2,
+                      tmp2, tmp2, tmp1, tmp1,
+                      0,    0,    0,    0,
+                      1,    1,    1,    1])
 
     tx, ty, tw, th = sprite.texcoords
     sx, sy = sprite.rescale
@@ -44,20 +48,19 @@ cpdef object get_sprite_rendering_data(o
     elif sprite.force_rotation:
         rz += sprite.angle
 
-    if (rx, ry, rz) != (0., 0., 0.):
-        if rx:
-            vertmat.rotate_x(-rx)
-        if ry:
-            vertmat.rotate_y(ry)
-        if rz:
-            vertmat.rotate_z(-rz) #TODO: minus, really?
+    if rx:
+        vertmat.rotate_x(-rx)
+    if ry:
+        vertmat.rotate_y(ry)
+    if rz:
+        vertmat.rotate_z(-rz) #TODO: minus, really?
     if sprite.allow_dest_offset:
         vertmat.translate(sprite.dest_offset[0], sprite.dest_offset[1], sprite.dest_offset[2])
     if sprite.corner_relative_placement: # Reposition
-        vertmat.translate(width / 2., height / 2., 0.)
+        vertmat.translate(width / 2, height / 2, 0)
 
-    x_1 = 1. / sprite.anm.size[0]
-    y_1 = 1. / sprite.anm.size[1]
+    x_1 = 1 / <double>sprite.anm.size[0]
+    y_1 = 1 / <double>sprite.anm.size[1]
     tox, toy = sprite.texoffsets
     uvs = (tx * x_1 + tox,
            (tx + tw) * x_1 + tox,
@@ -71,4 +74,3 @@ cpdef object get_sprite_rendering_data(o
     sprite.changed = False
 
     return sprite._rendering_data
-