In this exercise you'll start with a fully working 3rd person world with Ralph as your avatar. You'll then add a couple of classic HUD features, namely the health bar and the overhead map.
class HealthBar(NodePath): """ Adapted from drwr's code on the Panda 3D forums """ def __init__(self): NodePath.__init__(self, 'healthbar') self.group = self.attachNewNode('group') self.group.setPos(-0.5,0,0) cmfg = CardMaker('fg') cmfg.setFrame(0, 1, -0.1, 0.1) self.fg = self.group.attachNewNode(cmfg.generate()) cmbg = CardMaker('bg') cmbg.setFrame(-1, 0, -0.1, 0.1) self.bg = self.group.attachNewNode(cmbg.generate()) self.bg.setPos(1, 0, 0) self.fg.setColor(0, 1, 0, 1.0) self.bg.setColor(0.5, 0.5, 0.5, 1.0) self.value = 0.8 self.update() def update(self): self.fg.setScale(self.value, 1, 1) self.bg.setScale(1.0 - self.value, 1, 1) def setHealth(self, value): self.value = value self.update() def decrease(self, delta): if (self.value - delta) >= 0: self.value -= delta self.update()
<your button> = DirectButton( text_fg=(1,1,1,1), text_shadow=(0,0,0,1), frameColor=(0.4,0.5,0.4,1), borderWidth=(0.1,0.1), relief=DGG.RAISED, text=("Map","Map","> Map <",""), pressEffect=1, scale=0.035, frameSize=(-3,3,-0.5,1.0), command= <your function here>, rolloverSound = <your sound here>, clickSound = <your sound here>, parent=<parent node here>)
You can use the sounds from this week's gui demo or simply not specify new sounds to use the default Panda3D sounds. The function that the button calls, should be a function that toggles the HUD panel between fully visible and mostly hidden. There's already a toggleHUD method stub you could use. Remember that you have to set the button position in the redraw method. A good position of the button is (0.18,0,0.32) if you are using the panel as parent or (-base.getAspectRatio()+0.535,0,-0.26) if you are using aspect2d as parent.
class OverheadMap(NodePath): def __init__(self, x1, y1, x2, y2): """ Create a square map with the given world corners in the x-y plane """ NodePath.__init__(self, 'overheadmap') self.setBoundary(x1,y1,x2,y2) cmbg = CardMaker('bg') cmbg.setFrame(0,1,0,1) self.prime = self.attachNewNode(cmbg.generate()) self.prime.setColor(0.5,0.7,0.5,0.1) cmav = CardMaker('am') cmav.setFrame(-0.02,0.02,-0.02,0.02) self.avatar = self.prime.attachNewNode(cmav.generate()) self.avatar.setPos(0,0,0) self.avatar.setColor(0,1,0,1) def addLandmarks(self, landmarks, color=Vec4(1,0,0,0.5)): """ Take in a list of (x,y) touples in world coordinates and place them as little dots on the map in the given color """ ## To be filled in... def setBoundary(self, x1, y1, x2, y2): """ Define the extent of the map in world coordinates. Create the proper offset and scaling values that transform world coordinates to map coordinates""" self.xoffset = x1 self.xscale = 1.0/(x2-x1) self.yoffset = y1 self.yscale = 1.0/(y2-y1) def setAvatarPos(self, x, y): """ Sets the position of the avatar marker to the given world coordinates """ self.avatar.setPos((x-self.xoffset)*self.xscale,-0.01,(y-self.yoffset)*self.yscale)