[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Positioning Objects in 3D w/ Pygame/OpenGL



I've built a demo of a rotating, tilted 3D landscape using Pygame and OpenGL (http://www.xepher.net/~kschnee/landscape2.jpg), after reading the great NeHe tutorials and their Python translations.

I've got a bunch of cubes that seem to spin around a distant Y-axis, as in games like "Final Fantasy Tactics." But I don't know how to draw 2D sprites on that landscape, eg. a character standing on the blocks. I could put a rectangle in the right spot and texture it with a character image, but how can I rotate it so that it's facing the screen?

The blocks get positioned by moving back from the screen, then rotating, then getting drawn relative to the Y-axis. Following the same logic to draw a sprite would rotate the rectangle, which I don't want.

I'm using a homemade Camera class to define the view. (You're free to copy the code if you like it.) Any ideas?

Kris


class Camera:
def __init__(self, location=[-0.0,2.0,16.0], rotation=0.0, tilt=45):
"""Modifies OpenGL views to simulate a controllable camera view."""
self.location = None
self.Locate(location,True)
self.rotation = rotation
self.tilt = tilt
self.spinning = 0 ## When this is nonzero, I spin on HandleSpin().
self.spinrate = 5
def Rotate(self,angle,absolute=False):
"""Instantly rotate."""
if absolute:
self.rotation = angle
else:
self.rotation += angle
def SetSpin(self,angle=0):
"""Indicate that I should start rotating."""
self.spinning = angle
def HandleSpin(self):
"""Rotate over time if SetSpin has been called."""
if self.spinning:
if self.spinning > 0:
self.Rotate(self.spinrate)
self.spinning -= self.spinrate
else:
self.Rotate(-self.spinrate)
self.spinning += self.spinrate
## If there's a leftover, apply it.
if abs(self.spinning) < self.spinrate:
self.Rotate(self.spinning)
self.spinning = 0
def Locate(self,location,absolute=False):
"""Set/Change my location."""
if absolute:
self.location = [ -location[0],-location[1],-location[2] ]
else:
self.location = [ self.location[0]-location[0],self.location[1]-location[1],self.location[2]-location[2] ]
def Tilt(self,angle,absolute=False):
if absolute:
self.tilt = angle
else:
self.tilt += angle
def ApplyLocation(self):
glTranslatef(self.location[0],self.location[1],self.location[2])
def ApplyRotation(self):
glRotatef(self.rotation,0,1,0)
def ApplyTilt(self):
glRotatef(self.tilt,1,0,0)
def Apply(self):
"""Call this before drawing each object."""
self.ApplyLocation()
self.ApplyTilt()
self.ApplyRotation()
def ApplyForSprite(self):
"""Experimental; not working yet."""
self.ApplyLocation()
self.ApplyTilt()