Added surfaces and rudimentary platforming engine
class Sprite:
frames = None
- framerate = 0.0
frameno = 0
animating = False
anim_t = 0
- color = (1.0,1.0,1.0,1.0)
- position = (0,0)
size = (0,0)
- scale = 1.0
- rotation = 0
- gravity = (LEFT, BOTTOM)
uparrow = False
displaylists = None
- def __init__(self, file, genlist=True):
+ 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.position = position
+ self.scale = scale
+ self.rotation = rotation
+ self.mirror = mirror
+ self.flip = flip
+ self.color= color
+ self.setFramerate(framerate)
+ self.gravity = gravity
+
self.frames = []
d = None
if type(file) == type([]):
d = TexMan.load(file)
self.frames.append(d['texture'])
self.size = d['size']
+ self.rect = pygame.Rect(self.position, self.size)
self.tsize = d['tsize']
- print "size:",self.size
- print "tsize:",self.tsize
- if genlist:
- self.gen_displaylist()
+
+ self.gen_displaylist()
def gen_displaylist(self):
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')
- texcoordarray = array(
- ((1.0,0.0),(1.0,1.0),(0.0,1.0),(0.0,0.0))
- ,'f')
+ if self.flip and self.mirror:
+ texcoordarray = array(
+ ((0.0,0.0),(0.0,1.0),(1.0,1.0),(1.0,0.0))
+ ,'f')
+ elif self.flip:
+ texcoordarray = array(
+ ((0.0,1.0),(0.0,0.0),(1.0,0.0),(1.0,1.0))
+ ,'f')
+ elif self.mirror:
+ texcoordarray = array(
+ ((1.0,1.0),(1.0,0.0),(0.0,0.0),(0.0,1.0))
+ ,'f')
+ else:
+ texcoordarray = array(
+ ((1.0,0.0),(1.0,1.0),(0.0,1.0),(0.0,0.0))
+ ,'f')
index = array((0,1,2,3),'i')
for i in range(0,len(self.frames)):
glNewList(self.displaylists[i], GL_COMPILE)
glDrawArrays(GL_QUADS, 0, 4)
glEndList()
+
+ def setPosition(self, x, y):
+ self.position = (x,y)
+ self.rect.move_ip(x,y)
+
+
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
def reset(self):
self.anim_t = pygame.time.get_ticks()
+ self.frameno = 0
def play(self):
def draw(self):
+ self.drawAt(self.position)
+
+
+ def drawAt(self,pos):
if self.animating:
now = pygame.time.get_ticks()
dt = now - self.anim_t
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)
+ glTranslatef(pos[0], pos[1], 0)
if self.rotation != 0:
glRotatef(self.rotation, 0, 0, -1)
if self.scale != 1.0:
+import pygame
+from OpenGL.GL import *
+import math
+
+class Surface:
+ fuzz = 20
+ def __init__(self, p1, p2):
+ self.p1 = p1
+ self.p2 = p2
+ self.dx = p2[0] - p1[0]
+ self.dy = p2[1] - p1[1]
+ try:
+ self.m_x = float(self.dy) / float(self.dx)
+ except ZeroDivisionError:
+ self.m_x = 1e999
+ self.b_x = p1[1] - self.m_x * p1[0]
+ try:
+ self.m_y = float(self.dx) / float(self.dy)
+ except ZeroDivisionError:
+ self.m_y = 1e999
+ self.b_y = p1[0] - self.m_y * p1[1]
+
+ # A collision rect for fast collision culling. Only surfaces
+ # whose initial rect collision check passes will run the
+ # detailed check
+ self.rect = pygame.Rect(p1,(self.dx,self.dy))
+ self.rect.normalize()
+ self.rect.width += 1
+ self.rect.height += 1
+ # Expand the collision rect for nearly horizontal or vertical
+ # surfaces
+ if abs(self.m_x) < 0.2: # 5:1 ratio or more
+ self.rect.height += 2*self.fuzz
+ self.rect.top -= self.fuzz
+ elif abs(self.m_y) < 0.2: # 1:5 ratio or less
+ self.rect.width += 2*self.fuzz
+ self.rect.left -= self.fuzz
+
+
+ def collide(self, point):
+ if self.rect.collidepoint(point[0],point[1]):
+ if self.m_x > -1.0 and self.m_x < 1.0:
+ if self.dx > 0:
+ if point[1] < self.m_x * point[0] + self.b_x:
+ return True
+ else:
+ if point[1] > self.m_x * point[0] + self.b_x:
+ return True
+ else:
+ if self.dy > 0:
+ if point[0] > self.m_y * point[1] + self.b_y:
+ return True
+ else:
+ if point[0] < self.m_y * point[1] + self.b_y:
+ return True
+ return False
+
+
+ def draw(self):
+ angle = math.atan(self.m_x)
+ if self.dx < 0 or self.dy < 0:
+ arrow = (angle+3*math.pi/2) % (2*math.pi)
+ else:
+ arrow = (angle+math.pi/2) % (2*math.pi)
+ anglepoint = (math.cos(arrow) * 10, math.sin(arrow) * 10)
+ glPushMatrix()
+ glDisable(GL_TEXTURE_2D)
+ glColor3f(1.0,1.0,1.0)
+ glBegin(GL_LINES)
+ glVertex3f(self.p1[0],self.p1[1],0)
+ glVertex3f(self.p2[0],self.p2[1],0)
+ glVertex3f(self.rect.centerx, self.rect.centery, 0)
+ glVertex3f(self.rect.centerx + anglepoint[0], self.rect.centery + anglepoint[1], 0)
+ glEnd()
+ glPopMatrix()
+
+
+class Solid:
+ def __init__(self, p1, p2):
+ self.rect = pygame.Rect(p1,(p2[0]-p1[0],p2[1]-p1[1]))
+
+
+ def collide(self, point):
+ return self.rect.collidepoint(point[0],point[1])
+
+
+class SurfaceSet:
+ surfaces = None
+
+ def __init__(self, file = None):
+ self.surfaces = []
+ if file is not None:
+ self.parse(file)
+
+
+ def parse(self, file):
+ self.surfaces = []
+
+ mf = (1,1)
+ f = open(file,'r')
+ for line in f:
+ args = line.split()
+ if not args:
+ continue
+ cmd = args[0]
+ args = args[1:]
+ if cmd == 'tilesize':
+ mf = (int(args[0]),int(args[1]))
+ elif cmd == 'surface':
+ p1 = (int(args[0])*mf[0],int(args[1])*mf[1])
+ p2 = (int(args[2])*mf[0],int(args[3])*mf[1])
+ self.surfaces.append(Surface(p1,p2))
+ elif cmd == 'solid':
+ p1 = (int(args[0])*mf[0],int(args[1])*mf[1])
+ p2 = (int(args[2])*mf[0],int(args[3])*mf[1])
+ self.surfaces.append(Solid(p1,p2))
+ f.close()
+
+
+ def collide(self,point):
+ colliders = filter(lambda x: x.rect.collidepoint(point), self.surfaces)
+ if not colliders:
+ return False
+ if filter(lambda x: not x, [c.collide(point) for c in colliders]):
+ return False
+ return True
+
+
+ def draw(self):
+ for s in self.surfaces:
+ s.draw()
+
+
+ def append(self, s):
+ return self.surfaces.append(s)
+
+
+ def remove(self, s):
+ return self.surfaces.remove(s)
tile 8 0
tile 9 0
+tile 3 1
tile 4 1
tile 4 2
tile 4 3
tile 6 1
tile 6 2
+solid 0 2 1 3
+surface 0 1 2 1
+surface 2 1 4 2
+solid 2 0 4 1
+surface 4 2 4 5
+surface 4 5 5 5
+surface 5 5 5 1
+surface 5 1 6 1
+surface 6 1 6 3
+surface 6 3 7 3
+surface 7 3 7 1
+surface 7 1 10 1
+
tilesize 1 1
texture img/ByteIco.png
tile 263 263
+#!/usr/bin/env python
+
+import pygame
+from Sprite import *
+from Collage import *
+from Surface import *
+import Engine
+
+#resolution = (1280,1024)
+resolution = (640,480)
+#resolution = (320,240)
+
+Engine.init(resolution)
+
+pygame.display.set_caption("platformtest")
+
+ground = Collage('data/example1')
+ground.position = [0,0]
+surfaces = SurfaceSet('data/example1')
+stars = Collage('data/stars')
+stars.position = [0,0]
+candelabra = Sprite(['Sprites/candelabra_short/cand_s_1.png','Sprites/candelabra_short/cand_s_2.png','Sprites/candelabra_short/cand_s_3.png','Sprites/candelabra_short/cand_s_4.png'])
+candelabra.position = [64, 64]
+candelabra.setScale(2.0)
+candelabra.setGravity(CENTER, BOTTOM)
+candelabra.setFramerate(10.0)
+candelabra.play()
+
+player_l = Sprite(['img/richter%d.png' % n for n in range(0,8)],
+ framerate=10.0, scale=2.0, gravity=(CENTER,BOTTOM))
+player_r = Sprite(['img/richter%d.png' % n for n in range(0,8)], mirror=True,
+ framerate=10.0, scale=2.0, gravity=(CENTER,BOTTOM))
+
+
+def moveObject(pos, delta):
+ npos = list(pos)
+ npos[0] += delta[0]
+ npos[1] += delta[1]
+ if surfaces.collide(npos):
+ npos[1] += 1
+ if surfaces.collide(npos):
+ return pos
+ else:
+ return npos
+ else:
+ return npos
+
+
+class gamestate:
+ face = 1
+ direction = [0,0]
+ vgravity = 0
+ position = [32,64]
+
+
+def input(e):
+ if e.type == pygame.KEYDOWN:
+ if e.key == pygame.K_LEFT:
+ gamestate.direction[0] = -1
+ gamestate.face = 0
+ player_l.play()
+ elif e.key == pygame.K_RIGHT:
+ gamestate.direction[0] = 1
+ gamestate.face = 1
+ player_r.play()
+ elif e.key == pygame.K_DOWN:
+ gamestate.direction[1] = -1
+ elif e.key == pygame.K_UP:
+ gamestate.direction[1] = 1
+ elif e.type == pygame.KEYUP:
+ if e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT:
+ gamestate.direction[0] = 0
+ player_l.stop()
+ player_l.reset()
+ player_r.stop()
+ player_r.reset()
+ elif e.key == pygame.K_UP:
+ gamestate.direction[1] = 0
+ if gamestate.vgravity != 0.0:
+ gamestate.vgravity = 0.0
+ elif e.key == pygame.K_DOWN:
+ gamestate.direction[1] = 0
+
+
+def update():
+ if gamestate.direction[1] == 1 and gamestate.vgravity == 0:
+ gamestate.vgravity = 20.0
+ gamestate.vgravity -= 0.5
+ npos = [gamestate.position[0], gamestate.position[1] + gamestate.vgravity]
+ if surfaces.collide(npos):
+ npos[1] -= 1
+ if surfaces.collide(npos):
+ gamestate.vgravity = 0
+ else:
+ gamestate.position = npos
+ # Move two pixels in whatever direction we're going, only horizontal
+ gamestate.position = moveObject(gamestate.position,(gamestate.direction[0]*2,0))
+ #ground.position[0] = gamestate.position[0] - resolution[0]/2
+ #stars.position[0] = int(ground.position[0] / 5.0)
+ #candelabra.position[0] -= ground.position[0] + 64
+ if gamestate.position[1] < 0:
+ gamestate.position = [gamestate.position[0],480]
+
+def draw():
+ stars.draw()
+ ground.draw()
+ candelabra.draw()
+ if gamestate.face == 1:
+ player_r.drawAt(gamestate.position)
+ else:
+ player_l.drawAt(gamestate.position)
+
+n = 0
+def fpsthing():
+ global n
+ n += 1
+ if n == 100:
+ fps = "%0.1f FPS" % Engine.fpsman.get_fps()
+ pygame.display.set_caption("bouncetest [%s]" % fps)
+ print fps
+ n = 0
+
+Engine.engine([input],[update,fpsthing],[draw])
candelabra.setFramerate(10.0)
candelabra.play()
+#pygame.mixer.music.load('horizon.ogg')
+#pygame.mixer.music.play()
+
def update():
ground.position[0] -= 5
if ground.position[0] < 0:
+#!/usr/bin/env python
+
+import pygame
+from Sprite import *
+from Surface import *
+import Engine
+
+#resolution = (1280,1024)
+resolution = (640,480)
+#resolution = (320,240)
+
+Engine.init(resolution)
+
+pygame.display.set_caption("surfacetest")
+
+surfaces = SurfaceSet('data/example1')
+# Octagon
+#surfaces.append(Surface( (520,240),(461,98) ))
+#surfaces.append(Surface( (461,98),(319,40) ))
+#surfaces.append(Surface( (319,40),(178,98) ))
+#surfaces.append(Surface( (178,98),(120,240) ))
+#surfaces.append(Surface( (120,240),(178,381) ))
+#surfaces.append(Surface( (178,381),(320,440) ))
+#surfaces.append(Surface( (320,440),(461,381) ))
+#surfaces.append(Surface( (461,381),(520,240) ))
+
+# Concave
+#surfaces.append(Surface( (200,200), (200,400) ))
+#surfaces.append(Surface( (200,400), (300,300) ))
+#surfaces.append(Surface( (300,300), (400,300) ))
+#surfaces.append(Surface( (400,300), (500,400) ))
+#surfaces.append(Surface( (500,400), (500,200) ))
+#surfaces.append(Surface( (500,200), (200,200) ))
+
+player = Sprite('img/star.png')
+player.setGravity(CENTER, CENTER)
+player.position = [resolution[0]/2,resolution[1]/2]
+
+class gamestate:
+ direction = [0,0]
+ colliding = False
+
+def input(e):
+ if e.type == pygame.KEYDOWN:
+ if e.key == pygame.K_LEFT:
+ gamestate.direction[0] = -1
+ elif e.key == pygame.K_RIGHT:
+ gamestate.direction[0] = 1
+ elif e.key == pygame.K_DOWN:
+ gamestate.direction[1] = -1
+ elif e.key == pygame.K_UP:
+ gamestate.direction[1] = 1
+ elif e.type == pygame.KEYUP:
+ if e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT:
+ gamestate.direction[0] = 0
+ elif e.key == pygame.K_UP or e.key == pygame.K_DOWN:
+ gamestate.direction[1] = 0
+
+
+def update():
+ player.position[0] += gamestate.direction[0]
+ player.position[1] += gamestate.direction[1]
+ if surfaces.collide(player.position):
+ if not gamestate.colliding:
+ player.setColor(1.0,0.2,0.2)
+ gamestate.colliding = True
+ else:
+ if gamestate.colliding:
+ player.setColor(1.0,1.0,1.0)
+ gamestate.colliding = False
+
+
+
+def draw():
+ surfaces.draw()
+ player.draw()
+
+
+Engine.engine([input],[update],[draw])