[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[pygame] Positioning Objects in 3D w/ Pygame/OpenGL
- To: pygame-users@xxxxxxxx
- Subject: [pygame] Positioning Objects in 3D w/ Pygame/OpenGL
- From: Kris Schnee <kschnee@xxxxxxxxxx>
- Date: Sat, 23 Apr 2005 01:27:23 -0400
- Delivered-to: archiver@seul.org
- Delivered-to: pygame-users-outgoing@seul.org
- Delivered-to: pygame-users@seul.org
- Delivery-date: Sat, 23 Apr 2005 01:27:49 -0400
- Reply-to: pygame-users@xxxxxxxx
- Sender: owner-pygame-users@xxxxxxxx
- User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)
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()