commit:c83556a3ed05e70b0cc6871094bcae309e8aee66
author:chip
committer:chip
date:Tue Nov 13 11:43:11 2007 +0000
parents:025fb806d34246e4250e5f7bf22c3a18758caa37
Split out engine functionality, added sprite animation
diff --git a/Engine.py b/Engine.py
line changes: +65/-0
index 0000000..f591657
--- /dev/null
+++ b/Engine.py
@@ -0,0 +1,65 @@
+import random
+import sys
+import pygame
+from pygame.locals import *
+from Sprite import Sprite
+from Numeric import array,reshape
+
+try:
+    from OpenGL.GL import *
+    from OpenGL.GLU import *
+except:
+    print 'sprite_engine requires PyOpenGL'
+    raise SystemExit
+
+
+def init(resolution=(640,480)):
+	pygame.init()
+	pygame.display.set_mode(resolution, OPENGL|DOUBLEBUF|HWSURFACE)
+
+	# Set up the camera
+	glLoadIdentity()
+	glMatrixMode(GL_PROJECTION)
+	gluOrtho2D(0,resolution[0],0,resolution[1])
+
+	# And initialize things how we like in GL
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+	glEnable(GL_TEXTURE_2D)
+	glEnable(GL_BLEND)
+	glDisable(GL_DITHER)
+	glShadeModel(GL_FLAT)
+	glEnable(GL_CULL_FACE)
+	#glDepthFunc(GL_LEQUAL)
+	#glEnable(GL_DEPTH_TEST)
+	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)
+	glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST)
+	glEnableClientState(GL_VERTEX_ARRAY)
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY)
+
+fpsman = pygame.time.Clock()
+
+def engine(eventhandlers, updaters, drawers):
+	running = True
+	while running:
+		events = pygame.event.get()
+		for e in events:
+			if e.type == QUIT:
+				running = False
+			elif e.type == KEYDOWN:
+				if e.key == K_ESCAPE:
+					running = False
+			for h in eventhandlers:
+				h(e)
+
+		#clear screen and move camera
+		#glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
+		glClear(GL_COLOR_BUFFER_BIT)
+
+		for update in updaters:
+			update()
+
+		for draw in drawers:
+			draw()
+
+		pygame.display.flip()
+		fpsman.tick(60)

diff --git a/Sprite.py b/Sprite.py
line changes: +25/-4
index da58c32..695fc19
--- a/Sprite.py
+++ b/Sprite.py
@@ -19,14 +19,22 @@ class Sprite:
 	displaylist = None
 
 	def __init__(self, file, genlist=True):
-		d = TexMan.load(file)
-		self.texture = d['texture']
+		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.frames = [self.texture]
 		if genlist:
 			self.gen_displaylist()
 
+
 	def gen_displaylist(self):
 		if self.displaylist == None:
 			self.displaylist = glGenLists(1)
@@ -43,7 +51,8 @@ class Sprite:
 		index = array((0,1,2,3),'i')
 		glNewList(self.displaylist, GL_COMPILE)
 		glEnable(GL_TEXTURE_2D)
-		glBindTexture(GL_TEXTURE_2D, self.texture)
+		if len(self.frames) == 1:	# Static texture
+			glBindTexture(GL_TEXTURE_2D, self.frames[self.frameno])
 		glColor4fv(self.color)
 		glVertexPointerf(vertexarray)
 		glTexCoordPointerf(texcoordarray)
@@ -51,11 +60,23 @@ class Sprite:
 		glEndList()
 
 
+	def anim_start(self):
+		self.anim_t = pygame.time.get_ticks()
+		self.anim_period = int(1000/self.framerate)
+
+
 	def draw(self):
+		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(self.position[0], self.position[1], 0)
 		if self.rotation != 0:
 			glRotatef(self.rotation, 0, 0, -1)
+		if len(self.frames) > 1:
+			glBindTexture(GL_TEXTURE_2D, self.frames[self.frameno])
 		glCallList(self.displaylist)
 		if self.uparrow:
 			glDisable(GL_TEXTURE_2D)

diff --git a/TexMan.py b/TexMan.py
line changes: +4/-1
index bed22c3..f328f51
--- a/TexMan.py
+++ b/TexMan.py
@@ -5,6 +5,7 @@ from pygame.locals import *
 from Numeric import array,reshape,concatenate
 
 from util import *
+import config
 
 sprites = {}
 
@@ -18,6 +19,8 @@ def load(file):
         h = image.get_height()
         tw = n2ceil(w)
         th = n2ceil(h)
+	if config.square_textures:
+		tw = th = max(tw,th)
         newImage = pygame.Surface((tw,th), SRCALPHA, 32);
         newImage.fill((255,255,255,0))
         newImage.blit(image, (0,0));
@@ -36,5 +39,5 @@ def load(file):
 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
 	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
 
-	sprites[file] = {'texture':texture,'pixels':pixels,'size':(w,h),'tsize':(tw,th)}
+	sprites[file] = {'texture':texture,'size':(w,h),'tsize':(tw,th)}
 	return sprites[file]

diff --git a/bouncetest.py b/bouncetest.py
line changes: +18/-47
index b600609..3b2d46e
--- a/bouncetest.py
+++ b/bouncetest.py
@@ -5,6 +5,7 @@ import sys
 import pygame
 from pygame.locals import *
 from Sprite import Sprite
+import Engine
 from Numeric import array,reshape
 
 try:
@@ -21,46 +22,17 @@ resolution = (640,480)
 
 spritefile = 'img/ball.png'
 try:
-	spritefile = sys.argv[1]
+	spritefile = sys.argv[1:]
 except IndexError:
 	pass
 
-#initialize pygame and setup an opengl display
-pygame.init()
-pygame.display.set_mode(resolution, OPENGL|DOUBLEBUF|HWSURFACE)
-#pygame.display.set_mode(resolution, DOUBLEBUF)
-pygame.display.set_caption("bouncetest [loading]")
-
-
-#setup the camera
-glLoadIdentity()
-glMatrixMode(GL_PROJECTION)
-gluOrtho2D(0,resolution[0],0,resolution[1])
-
-glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
-glEnable(GL_TEXTURE_2D)
-glEnable(GL_BLEND)
-glDisable(GL_DITHER)
-glShadeModel(GL_FLAT)
-glEnable(GL_CULL_FACE)
-#glDepthFunc(GL_LEQUAL)
-#glEnable(GL_DEPTH_TEST)
-glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)
-glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST)
-glEnableClientState(GL_VERTEX_ARRAY)
-glEnableClientState(GL_TEXTURE_COORD_ARRAY)
-
-# POLYGON STIPPLING!?
-#stipple = array([[n % 2 for n in range(0,32)] + [n % 2 for n in range(1,33)] for m in range(0,16)])
-#stipple = reshape(stipple, (32,32))
-#glPolygonStippleub(stipple)
-#glEnable(GL_POLYGON_STIPPLE)
-
 class Bouncer:
 	def __init__(self):
 		self.velocity = [random.uniform(-10,10),random.uniform(-10,10)]
 		self.sprite = Sprite(spritefile,False)
-		self.sprite.color = (random.random(),random.random(),random.random(), 0.5)
+		self.sprite.framerate = 9.0
+		self.sprite.anim_start()
+		#self.sprite.color = (random.random(),random.random(),random.random(), 0.5)
 		self.sprite.position = [random.randrange(0,resolution[0]),random.randrange(0,resolution[1])]
 		self.sprite.gen_displaylist()
 		self.draw = self.sprite.draw
@@ -84,32 +56,31 @@ class Bouncer:
 		self.sprite.position[0] += self.velocity[0]
 		self.sprite.position[1] += self.velocity[1]
 
+Engine.init(resolution)
+
 bouncers = []
-for i in range(0,2000):
+for i in range(0,100):
 	h = Bouncer()
 	bouncers.append(h)
 
 pygame.display.set_caption("bouncetest")
-fpsman = pygame.time.Clock()
-n = 0
-while 1:
-	event = pygame.event.poll()
-	if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
-	    break
-
-	#clear screen and move camera
-	#glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
-	glClear(GL_COLOR_BUFFER_BIT)
 
+def update():
 	for b in bouncers:
 		b.update()
+
+def draw():
+	for b in bouncers:
 		b.draw()
 
-	pygame.display.flip()
-	fpsman.tick(60)
+n = 0
+def fpsthing():
+	global n
 	n += 1
 	if n == 100:
-		fps = "%0.1f FPS" % fpsman.get_fps()
+		fps = "%0.1f FPS" % Engine.fpsman.get_fps()
 		pygame.display.set_caption("bouncetest [%s]" % fps)
 		print fps
 		n = 0
+
+Engine.engine([],[update,fpsthing],[draw])

diff --git a/config.py b/config.py
line changes: +3/-0
index 0000000..4871102
--- /dev/null
+++ b/config.py
@@ -0,0 +1,3 @@
+# If your card has trouble with non-square textures (my TNT seems to), set this
+# to true to make all textures square
+square_textures = True