import pygame
from pygame.locals import *
from pgu import tilevid, timer
from OpenGL.GL import *
from OpenGL.GLU import *
from util import *
import tongue
import ode
# Declare some "constants"
SW = 1024
SH = 768
TW = 16
TH = 16
LW = 512 # Lightmap dimensions
LH = 512
FPS = 30
MOVESPEED = 300
AIRACC = 20
GRAVITY = 98.1
def player_new(g,t,value):
g.clayer[t.ty][t.tx] = 0
s = tilevid.Sprite(g.images['player'],t.rect)
g.sprites.append(s)
s.loop = player_loop
s.groups = g.string2groups('player')
s.standing = False
s.tongue = None
s.turned = False
g.player = s
s.body = ode.Body(g.world)
m = ode.Mass()
m.setSphere(120.0, 0.20) # density, radius
m.mass = 1.0 # 1 kilo frog
s.body.setMass(m)
s.body.setPosition((s.rect.centerx, s.rect.centery, 0))
def player_loop(g,s):
keys = pygame.key.get_pressed()
if keys[K_UP]:
if s.standing:
s.body.addForce((0,-GRAVITY*40,0))
s.standing = False
if keys[K_LEFT] and s.standing:
s.body.addForce((-MOVESPEED,0,0))
if keys[K_LEFT] and not s.standing:
s.body.addForce((-AIRACC,0,0))
if keys[K_RIGHT] and s.standing:
s.body.addForce((MOVESPEED,0,0))
if keys[K_RIGHT] and not s.standing:
s.body.addForce((AIRACC,0,0))
if keys[K_SPACE]:
if s.tongue:
#print s.tongue
g.sprites.remove(s.tongue)
s.tongue = None
else:
dir = [0,0]
if keys[K_LEFT]:
dir[0] -= 5
if keys[K_RIGHT]:
dir[0] += 5
if keys[K_UP]:
dir[1] -= 5
if keys[K_DOWN]:
dir[1] += 5
if dir[0] == 0 and dir[1] == 0:
if s.turned:
dir[0] = -5
else:
dir[0] = 5
t = tongue.new(g, dir)
s.tongue = t
if s.standing:
vel = s.body.getLinearVel()
if vel[0] > 0:
s.body.addForce((max(-MOVESPEED, -vel[0]*10), 0,0))
#s.body.addForce((-200,0,0))
elif vel[0] < 0:
s.body.addForce((min(MOVESPEED, -vel[0]*10), 0,0))
#s.body.addForce((200,0,0))
#s.dy += 0.5
pos = s.body.getPosition()
s.rect.centerx = pos[0]
s.rect.centery = pos[1]
s.rect.clamp_ip(g.bounds)
def tile_block(g,t,a):
if a.groups == g.string2groups('tongue'):
return tongue.tile_block(g,t,a)
c = t.config
if (c['top'] == 1 and a._rect.bottom <= t._rect.top and a.rect.bottom > t.rect.top):
a.rect.bottom = t.rect.top
a.body.setPosition((a.body.getPosition()[0], a.rect.centery,0))
a.body.addForce((0,-GRAVITY,0))
a.standing = True
#a.dy = 0
if (c['left'] == 1 and a._rect.right <= t._rect.left and a.rect.right > t.rect.left):
a.rect.right = t.rect.left
a.body.setPosition((a.rect.centerx, a.body.getPosition()[1],0))
a.body.addForce((-a.body.getLinearVel()[0]*10,0,0))
#a.body.addForce((t.rect.left-a.rect.right,0,0))
if (c['right'] == 1 and a._rect.left >= t._rect.right and a.rect.left < t.rect.right):
a.rect.left = t.rect.right
a.body.setPosition((a.rect.centerx, a.body.getPosition()[1],0))
a.body.addForce((-a.body.getLinearVel()[0]*10,0,0))
#a.body.addForce((t.rect.right-a.rect.left,0,0))
if (c['bottom'] == 1 and a._rect.top >= t._rect.bottom and a.rect.top < t.rect.bottom):
a.rect.top = t.rect.bottom
#a.setPosition((a.getPosition()[0], t.rect.bottom,0))
a.body.setPosition((a.body.getPosition()[0], a.rect.centery,0))
a.body.addForce((0, -a.body.getLinearVel()[1]*10,0))
#a.body.addForce((0,1,0))
#a.dy = 0
tdata = {
32:(('player,tongue'),tile_block,{'top':1,'bottom':1,'left':1,'right':1}),
36:(('player,tongue'),tile_block,{'top':1,'bottom':1,'left':1,'right':1}),
48:(('player,tongue'),tile_block,{'top':1,'bottom':1,'left':1,'right':1}),
52:(('player,tongue'),tile_block,{'top':1,'bottom':1,'left':1,'right':1})
}
idata = [
('player','frog.png', (4,4,32,32)),
('player_left', 'frog_left.png', (4,4,32,32)),
('tongue_head', 'tongue_head.png', (0,0,4,4))
]
cdata = {
1:(player_new,None)
}
def init():
# Init PGU tile engine
g = tilevid.Tilevid()
# Init ode
g.world = ode.World()
g.world.setGravity((0.0, GRAVITY, 0.0))
# Init screen
g.screen = pygame.display.set_mode((SW,SH), OPENGL|DOUBLEBUF)
#pygame.display.set_mode((SW,SH), OPENGL|DOUBLEBUF)
glClearColor(0.0,0.0,0.0,1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0,SW,0,SH)
glMatrixMode(GL_MODELVIEW)
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
#glEnable(GL_DEPTH_TEST)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
# Load level
g.tga_load_tiles('tiles.tga', (TW,TH),tdata)
g.tga_load_level('level.tga', bg=1)
g.load_images(idata)
g.run_codes(cdata,(0,0,64,48))
for t in g.tiles:
image = make_gl_texture(t.image)
t.image = image
g.level_list = glGenLists(1)
glNewList(g.level_list, GL_COMPILE)
w = len(g.tlayer[0])
h = len(g.tlayer)
glColor3f(1.0,1.0,1.0)
def gentiles(layer,layernum):
currtex = -1
for y in range(h):
for x in range(w):
if layer[y][x] == 0:
continue
nexttex = g.tiles[layer[y][x]].image.texture
if currtex != nexttex:
glBindTexture(GL_TEXTURE_2D, nexttex)
currtex = nexttex
glBegin(GL_QUADS)
glTexCoord2f(0,0); glVertex3f(x*16, (h-y)*16-16,layernum)
glTexCoord2f(0,1); glVertex3f(x*16, (h-y)*16,layernum)
glTexCoord2f(1,1); glVertex3f(x*16+16, (h-y)*16,layernum)
glTexCoord2f(1,0); glVertex3f(x*16+16, (h-y)*16-16,layernum)
glEnd()
gentiles(g.blayer,0)
gentiles(g.tlayer,0.1)
glEndList()
for s in g.sprites:
im = make_gl_texture(s.image)
s.image = im
for i in g.images:
im = make_gl_texture(g.images[i][0])
g.images[i] = (im, g.images[i][1])
#for s in g.sprites:
#im = make_gl_texture(s.image)
return g
def run(g):
g.quit = 0
g.player_pos = (64,64)
# Calculate bounds for scrolling
g.bounds = pygame.Rect(0,0,(len(g.tlayer[0]))*TW,(len(g.tlayer))*TH)
#g.lightmap = pygame.Surface((LW,LH), SWSURFACE)
#g.lightmap.set_colorkey((255,0,255))
#g.lightmap.set_alpha(128)
# Make PGU paint to the screen we initialised
#g.paint(g.screen)
#pygame.display.flip()
# Initialize timer
t = timer.Timer(FPS)
# Initialize variables for calculating FPS
g.frames = 0
g.lastsec = pygame.time.get_ticks()
while not g.quit:
# Event handling
for e in pygame.event.get():
if e.type is QUIT: g.quit = 1
elif e.type is KEYDOWN:
if e.key == K_ESCAPE: g.quit = 10
elif e.key == K_LEFT:
if g.player.standing:
g.player.body.addForce((-1000,0,0))
g.player.turned = True
g.player.setimage(g.images['player_left'])
elif e.key == K_RIGHT:
if g.player.standing:
g.player.body.addForce((1000,0,0))
g.player.turned = False
g.player.setimage(g.images['player'])
elif e.type is KEYUP:
if e.key == K_LEFT:
if g.player.standing:
g.player.body.addForce((1000,0,0))
elif e.key == K_RIGHT:
if g.player.standing:
g.player.body.addForce((-1000,0,0))
# PGU loop and update the screen
g.loop()
# Ode loop
g.world.step(1.0/FPS)
#g.lightmap.fill((0,0,0))
#pygame.draw.circle(g.lightmap, (255,0,255), (g.player.rect.centerx*LW/SW, g.player.rect.centery*LW/SW), 40)
# Insert OpenGL paint code here
#glBegin(GL_QUADS)
#for y in range(g.
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glDisable(GL_DEPTH_TEST)
glCallList(g.level_list)
# generating textures on the fly is really slow
#texture = make_gl_texture(g.lightmap)
#glBindTexture(GL_TEXTURE_2D, texture.texture)
"""
glBegin(GL_QUADS)
glTexCoord2f(0,0.25); glVertex2f(0,0)
glTexCoord2f(0,1); glVertex2f(0,SH)
glTexCoord2f(1,1); glVertex2f(SW,SH)
glTexCoord2f(1,0.25); glVertex2f(SW,0)
glEnd()
"""
for s in g.sprites:
glLoadIdentity()
glTranslatef(s.rect.x, SH-s.rect.y, 0.0)
glBindTexture(GL_TEXTURE_2D, s.image.texture)
glBegin(GL_QUADS)
glTexCoord2f(0,0); glVertex3f(0,-s.image.height,0.2)
glTexCoord2f(0,1); glVertex3f(0,0,0.2)
glTexCoord2f(1,1); glVertex3f(s.image.width,0,0.2)
glTexCoord2f(1,0); glVertex3f(s.image.width,-s.image.height,0.2)
glEnd()
glEnable(GL_DEPTH_TEST)
glDisable(GL_TEXTURE_2D)
glLoadIdentity()
glColor4f(0,0,0,0)
glBegin(GL_QUADS)
glVertex3f(320, 400,1)
glVertex3f(270, 450,1)
glVertex3f(320, 500,1)
glVertex3f(370, 450,1)
glEnd()
glColor4f(0.0,0,0,0.5)
glBegin(GL_QUADS)
glVertex2f(0, 0)
glVertex2f(0, SH)
glVertex2f(SW, SH)
glVertex2f(SW, 0)
glEnd()
glEnable(GL_TEXTURE_2D)
pygame.display.flip()
#updates = g.update(g.screen)
#g.screen.blit(g.lightmap, (0,0))
#pygame.display.update(updates)
# Tick the timer
t.tick()
# Calculate and print FPS (which should be constant)
g.frames += 1
currtime = pygame.time.get_ticks()
if currtime - g.lastsec >= 1000:
print g.frames, "fps"
g.frames = 0
g.lastsec = currtime
run(init())