Hi,
the code snippet below is intented to simplify sprite rendering by allowing you to use screen coordinates in calls to NodePath.setPos() and NodePath.setScale() instead of render[2d] and aspect2d coordinates.
The idea is to first call create_sprites_node_setup and use the returned nodepath as the parent to all your sprite nodes. Then you can use screen coordinates with your sprite nodes.
from pandac.PandaModules import Vec3
from pandac.PandaModules import Point3
from pandac.PandaModules import TextureStage
from pandac.PandaModules import NodePath
from pandac.PandaModules import CardMaker
from direct.interval.LerpInterval import LerpPosInterval
import direct.directbase.DirectStart
def create_sprites_node_setup(screenWidth, screenHeight, parent = render2d):
aspect_ratio = parent.getScale()[0]
screenOrigin = parent.attachNewNode('screen_origin')
screenNode = screenOrigin.attachNewNode('screen_node')
screenOrigin.setPos(-1.0/aspect_ratio, 0.0, 1.0)
screenOrigin.setScale(2.0, 1.0, -2.0)
screenNode.setPos(0, 0, 0)
screenNode.setScale(1.0/(aspect_ratio*screenWidth), 1.0, 1.0/screenHeight)
screenNode.setTexScale(TextureStage.getDefault(), 1.0, -1.0)
# test some points
# points = [(0,0), (screenWidth, 0), (screenWidth, screenHeight), (screenWidth/2.0, screenHeight/2.0), (0, screenHeight)]
# for pt in points:
# print '%s -> %s' % (pt, str(parent.getRelativePoint(screenNode, Vec3(pt[0], 0, pt[1]))))
return screenNode
def create_sprite(filename, x, z, sx, sz, transparent = 1):
cm = CardMaker('spritesMaker')
cm.setFrame(-0.5, 0.5, -0.5, 0.5)
sprite = cm.generate()
tex = loader.loadTexture(filename)
spriteNP = NodePath(sprite)
spriteNP.setTexture(tex)
spriteNP.setPos(x, 0, z)
spriteNP.setScale(sx, 1.0, sz)
spriteNP.setTransparency(transparent)
return spriteNP
# use it like this
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
sprites_root = create_sprites_node_setup(SCREEN_WIDTH, SCREEN_HEIGHT, aspect2d)
flower_sprite = create_sprite('flower.png', SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 128, 128, 1)
flower_sprite.reparentTo(sprites_root)
horizontalMove = LerpPosInterval(flower_sprite, 9.0, Point3(SCREEN_WIDTH, 0, SCREEN_HEIGHT / 2), Point3(0, 0, SCREEN_HEIGHT / 2))
horizontalMove.loop()
run()
As you can see the coordinates to LerpPosInterval are given in screen space.
In case you want to run the code, you can right click on the sprite image below and save it:
It has simplified my sprite handling code which was initially mixed with coordinates converions.
Regards