Simple HUD help? (Python, Overlay Scene)

Greets all! I’m just getting into the BGE and Python, and I’m working on a really basic Galaga clone as a way to warm up. I’m trying to create a simple heads-up display that shows a health bar for the player’s ship by using ‘Overlay Scene’, and scaling a bar on the overlayed scene to represent the player’s health. My problem is I can’t figure out how to pass the health of the player to health bar. I’ve attached what I’ve got for a blend and python code thus far. Thanks!

objects.py

#
#	platformer testing shenanigans
#	started 09/07/2011
#

from bge import logic
from bge import events

gravity = .01

def Clamp(value, min, max):		#clamps the values given
	if value>max:				#used to keep ships from moving crazy fast
		return max
	elif value<min:
		return min
	else:
		return value

def Sign(value):				#determines if a value is positive, negative, or neutral (0)
	if value > 0:				#used by AxisCheck()
		return 1
	elif value < 0:
		return -1
	else:
		return 0

def AxisCheck(mx, my, size=0.1, prop = 'wall'):		#checks for collision between an object and a prop
	controller = logic.getCurrentController()
	object = controller.owner
	
	pos = object.position
	topos = pos.copy()
	topos.x += (Sign(mx)*size)+mx
	topos.z += (Sign(my)*size)+my
	
	return object.rayCast(topos, pos, 0, prop, 1, 1)
	

#the player's ship
#this controls all the inputs and generates bullets when the 'fire' key is pressed
def Player():
	controller = logic.getCurrentController()
	scene = logic.getCurrentScene()
	object = controller.owner
	bulletcol = controller.sensors['BulletCol']
	
	key = logic.keyboard.events
	kbup = key[events.UPARROWKEY]
	kbdown = key[events.DOWNARROWKEY]
	kbleft = key[events.LEFTARROWKEY]
	kbright = key[events.RIGHTARROWKEY]
	kbspace = key[events.SPACEKEY]
	
	def Init():
		if not 'init' in object:
			object['init'] = 1
			
			object['mx'] = 0.0
			object['my'] = 0.0
			object['speed'] = .1
			object['hp'] = 3.0
			object['maxhp'] = 3.0
			
	def Update():
		if kbleft>0:
			#print("kbleft")
			object['mx'] = -object['speed']
		elif kbright>0:
			#print("kbright")
			object['mx'] = object['speed']
		else:
			object['mx'] = 0
		
		if kbspace == 1:
			bullet = scene.addObject('playerBullet', object)
			bullet['speed'] = 0.2
			bullet['type'] = 'player'
		
		if bulletcol.positive:
			bullet = bulletcol.hitObject
			object['hp'] -= bullet['power']
			bullet.endObject()
			print("player hit!")
		if object['hp'] <= 0:
			print("Game Over!")
			object.endObject()
			
		object['mx'] = Clamp(object['mx'], -object['speed'], object['speed'])
		object['my'] = Clamp(object['my'], -object['speed'], object['speed'])
		if AxisCheck(object['mx'], object['my'], .1)[0] != None:
			object['mx'] = 0
		
		object.applyMovement([object['mx'], 0.0, 0.0], 0)
		
	Init()
	Update()

#HUD Elements
#
#Health bar
def HealthBar():
	controller = logic.getCurrentController()
	object = controller.owner
	scene = logic.getCurrentScene()
	
	player = scene.objects["Player"]
	
	object.scaling = ([1.0, 1.0, player['hp']/player['maxhp']])
	
#a really basic enemy called 'Station'
#the station moves back and forth between the 'wall's and steadily fires (very slowly)
def Station():
	controller = logic.getCurrentController()
	scene = logic.getCurrentScene()
	object = controller.owner
	bulletcol = controller.sensors['BulletCol']

	def Init():
		if not 'init' in object:
			object['init'] = 1
			object['hp'] = 3
			object['speed'] = 0.05
			object['my'] = 0.05
			object['shottimer'] = 0.0
			
	def Update():
		if bulletcol.positive:
			bullet = bulletcol.hitObject
			print("station hit!")
			object['hp'] -= bullet['power']
			bullet.endObject()
		if object['hp'] <= 0:
			object.endObject()
		
		if object['shottimer'] > 1.0:
			bullet = scene.addObject('enemyBullet', object)
			bullet['speed'] = -0.05
			object['shottimer'] = 0.0
		
		if object.position.z > 2:
			object['my'] = -abs(object['speed'])/10
		else:
			object['my'] = 0
		
		if AxisCheck(object['speed'], 0.0, 0.1)[0] != None:
			object['speed'] *= -1.0
		
		object['shottimer'] += 1.0/logic.getLogicTicRate()
		object.applyMovement([object['speed'], 0.0, object['my']], 0)
		
	Init()
	Update()

#the bullet code
def Bullet():
	controller = logic.getCurrentController()
	scene = logic.getCurrentScene()
	object = controller.owner
	camera = scene.active_camera
	
	def Init():
		if not 'init' in object:
			object['init'] = 1
		if not 'power' in object:	
			object['power'] = 1.0
		if not 'speed' in object:
			object['speed'] = 0.2
	
	def Update():
		if not camera.pointInsideFrustum(object.position):
			object.endObject()
		
		object.applyMovement([0.0, 0.0, object['speed']], 0)
			
	Init()
	Update()

Attachments

space-shooter.blend (427 KB)

:’) - That’s my code… I’m so proud! LOL

Anyway, your healthbar function uses the current scene - but, the healthbar is in an overlay scene, right? So, you’ve got to get the game scene and use that instead. This should work instead of the ‘scene’ line in your Healthbar() function.


scene = [s for s in logic.getSceneList() if s.name != "GUI"][0]

Replace “GUI” with the name of your overlay scene. This line should essentially get the scene that isn’t the overlay scene (e.g. the game scene). It might not work if you have more than two scenes in your game at once. If you want more control:


scene = [s for s in logic.getSceneList() if s.name == "Game"][0]

You could use this and replace ‘Game’ with the name of your game scene.

There are several choices:
A) as SolarLune suggest let the player object search for the health bar object
B) let the healthbar object search for the player object
C) let the player object send messages with the new health value around - the health bar can extract the new health value when receiving of such message

Mmk, it’s still not working but I see how it’s supposed to work so I’ll keep playing. Thanks!

Oh, and yeah, those tutorials are fantastic SolarLune, thanks again!

Okay, so I’ve gotten the HUD to work and even added a nice little menu to the start of the game, but now when the game ends and goes back to the menu the HUD overlay scene is still there and python throws all kinds of error messages. How do I go about killing the overlay scene before returning to the Menu scene?

scene.remove() should work if you have a reference to the scene.

I apologize to the author of the TD, but this is just a typical example of “module addict”

ie, what it is to write all these def? (not complicate things?)
is not better than a simple “IF”??

I see that this practice is widespread …:eek:

@MarcoIT - The def keyword allows you to define functions, which is useful if you need to execute code more than once in an almost identical fashion with only a few changing values. For example, say I wanted to clamp two values to between -100 and 100.

I could do:


a = 1
b = 50

if a > 100:
    a = 100
elif a < -100
    a = -100

if b > 100:# Plus the same with b
    b = 100
elif b < -100
    b = -100

However, by defining a function, I can simplify the code, making it more readable and easier to use for multiple situations:


def Clamp(value, min, max):
     if value < min:
          return min
     elif value > max:
          return max
     else:
          return value

a = 1
b = 50

a = Clamp(a, -100, 100)
b = Clamp(b, -100, 100)