from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
from pygame.locals import *
from Numeric import array
from util import *
import TexMan
LEFT = -1
BOTTOM = -1
CENTER = 0
RIGHT = 1
TOP = 1
class Sprite:
frames = None
frameno = 0
animating = False
anim_t = 0
size = (0,0)
displaylists = None
showup = False
showhitbox = False
def __init__(self, file, position=(0,0), scale=1.0, rotation=0,
mirror=False, flip=False, color=(1.0,1.0,1.0,1.0),
framerate=0.0, gravity=(LEFT,BOTTOM)):
self.frames = []
d = None
if type(file) == type([]):
d = TexMan.load(file[0])
self.frames.append(d['texture'])
for f in file[1:]:
self.frames.append(TexMan.load(f)['texture'])
else:
d = TexMan.load(file)
self.frames.append(d['texture'])
self.size = d['size']
self.tsize = d['tsize']
self.rotation = rotation
self.mirror = mirror
self.flip = flip
self.color = color
self.setFramerate(framerate)
self.scale = scale
self.position = position
self.gravity = gravity
self.fixHitbox()
self.gen_displaylist()
def gen_displaylist(self):
if self.displaylists == None:
n = glGenLists(len(self.frames))
self.displaylists = range(n,n+len(self.frames))
c = [0,0]
for i in range(0,2):
if self.gravity[i] == LEFT:
c[i] = 0
elif self.gravity[i] == CENTER:
c[i] = -self.size[i]/2
elif self.gravity[i] == RIGHT:
c[i] = -self.size[i]
else:
print "Invalid gravity:",x
c[i] = 0
if self.mirror:
c[0] -= self.tsize[0] - self.size[0]
if self.flip:
c[1] -= self.tsize[1] - self.size[1]
vertexarray = array(
((c[0],c[1],0),(c[0]+self.tsize[0],c[1],0),
(c[0]+self.tsize[0],c[1]+self.tsize[1],0),
(c[0],c[1]+self.tsize[1],0))
,'f')
if self.flip and self.mirror:
texcoordarray = array(
((1.0,1.0),(0.0,1.0),(0.0,0.0),(1.0,0.0))
,'f')
elif self.flip:
texcoordarray = array(
((0.0,1.0),(1.0,1.0),(1.0,0.0),(0.0,0.0))
,'f')
elif self.mirror:
texcoordarray = array(
((1.0,0.0),(0.0,0.0),(0.0,1.0),(1.0,1.0))
,'f')
else:
texcoordarray = array(
((0.0,0.0),(1.0,0.0),(1.0,1.0),(0.0,1.0))
,'f')
index = array((0,1,2,3),'i')
for i in range(0,len(self.frames)):
glNewList(self.displaylists[i], GL_COMPILE)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.frames[i])
glColor4fv(self.color)
glVertexPointer(3, GL_FLOAT, 0, vertexarray)
glTexCoordPointer(2, GL_FLOAT, 0, texcoordarray)
glDrawArrays(GL_QUADS, 0, 4)
glEndList()
def setPosition(self, x, y):
self.position = (x,y)
self.hitbox.topleft = (x + self.hitbox_offset[0], y + self.hitbox_offset[1])
def setColor(self, r, g, b, a = 1.0):
self.color = (r,g,b,a)
self.gen_displaylist()
def setScale(self, scale):
self.scale = scale
self.fixHitbox()
def fixHitbox(self):
self.hitbox_offset = [0,0]
for i in range(0,2):
if self.gravity[i] == -1:
self.hitbox_offset[i] = 0
elif self.gravity[i] == 0:
self.hitbox_offset[i] = -(self.size[i] * self.scale) / 2
elif self.gravity[i] == 1:
self.hitbox_offset[i] = -(self.size[i] * self.scale)
self.hitbox = pygame.Rect((self.position[0] + self.hitbox_offset[0], self.position[1] + self.hitbox_offset[1]), (self.size[0] * self.scale, self.size[1] * self.scale))
def setGravity(self, xg, yg, genlist=True):
if self.gravity != (xg,yg):
self.gravity = (xg,yg)
if genlist:
self.gen_displaylist()
self.fixHitbox()
def setFramerate(self, rate):
self.framerate = rate
if self.framerate != 0.0:
self.anim_period = int(1000/rate)
if self.anim_t == 0:
self.reset()
else:
self.stop()
def reset(self):
self.anim_t = pygame.time.get_ticks()
self.frameno = 0
def play(self):
if len(self.frames) > 1:
self.animating = True
def stop(self):
self.animating = False
def draw(self):
self.drawAt(self.position)
def drawAt(self,pos):
if self.animating:
now = pygame.time.get_ticks()
dt = now - self.anim_t
if dt > self.anim_period:
self.frameno = (self.frameno + int(dt / self.anim_period)) % len(self.frames)
self.anim_t = now
glPushMatrix()
glTranslatef(pos[0], pos[1], 0.0)
if self.rotation != 0:
glRotatef(self.rotation, 0.0, 0.0, -1.0)
if self.scale != 1.0:
glScalef(self.scale, self.scale, 1.0)
glCallList(self.displaylists[self.frameno])
if self.showup:
glDisable(GL_TEXTURE_2D)
glColor3f(0.0, 0.0, 1.0)
glBegin(GL_TRIANGLES)
glVertex(-5, 0, 0)
glVertex(0, 20, 0)
glVertex(5, 0, 0)
glEnd()
glPopMatrix()
if self.showhitbox:
glDisable(GL_TEXTURE_2D)
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_LINE_LOOP)
glVertex(self.hitbox.left, self.hitbox.bottom, 0)
glVertex(self.hitbox.left, self.hitbox.top, 0)
glVertex(self.hitbox.right, self.hitbox.top, 0)
glVertex(self.hitbox.right, self.hitbox.bottom, 0)
glEnd()