[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pygame] handy snippets: Status Bar and Simple Button
Hey all.
Here are a couple classes I am using for the StrikeOps project, but
they're pretty general, so I'd thought I'd submit them here as they may
be useful to others.
Also, I guess this should be considered a submission to the PCR too, but
don't know what the proper channel is. (is it even called the PCR
anymore?)
--
+-------------------------------------------------------------+
| Shandy Brown Digital Thinkery |
| shandy@geeky.net http://www.digitalthinkery.com |
+-------------------------------------------------------------+
#!/usr/bin/env python
"""
Here's some text to describe the SimpleButton module
"""
#Import Modules
import os, pygame
from pygame.locals import *
#-----------------------------------------------------------------------------
def load_png( name ):
basedirectory = 'data'
if isinstance(name, list):
fullname = basedirectory
for component in name:
fullname = os.path.join(fullname, component)
else:
fullname = os.path.join(basedirectory, name)
try:
image = pygame.image.load(fullname)
if image.get_alpha is None:
image = image.convert()
else:
image = image.convert_alpha()
except pygame.error, message:
print 'Cannot load image:', fullname
raise SystemExit, message
return image, image.get_rect()
#-----------------------------------------------------------------------------
class EventSensitive:
""" This is an interface for sprites that should be sensitive
to keypresses and mouse clicks
The object MUST have listenKeys and offKeys for keypresses
The object MUST have rect and callbackFn for mouse clicks
listenKeys and offKeys are dicts of functions, indexed by key name
callbackFn is a function"""
#----------------------------------------------------------------------
def Signal( self, event ):
"""event is a pygame style event"""
if hasattr(self, 'callbackFn') \
and event.type == MOUSEBUTTONDOWN \
and self.rect.collidepoint (event.pos):
self.callbackFn()
elif hasattr(self, 'listenKeys') \
and event.type in [KEYUP,KEYDOWN]:
if self.listenKeys.has_key( event.key ) \
and event.type is KEYDOWN:
self.listenKeys[event.key]( )
elif self.offKeys.has_key( event.key ) \
and event.type is KEYUP:
self.offKeys[event.key]( )
#-----------------------------------------------------------------------------
class SimpleButton(pygame.sprite.Sprite, EventSensitive):
def __init__(self, callbackFn, imgName=None):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
if imgName:
self.image, self.rect = load_png(imgName)
else:
#if there's no image name, make a red square
self.image = pygame.Surface( (100,100) )
self.image.fill( (200,0,0) )
self.rect = self.image.get_rect()
self.callbackFn = callbackFn
#----------------------------------------------------------------------
def SetCallback( self, newCallbackFn ):
self.callbackFn = newCallbackFn
#this calls the 'main' function when this script is executed
if __name__ == '__main__': print "didn't expect that!"
#!/usr/bin/env python
"""
This is a status bar class for things like health, time, progress, etc.
"""
#Import Modules
import os, pygame
from pygame.locals import *
red = (220,0,0)
black = (0,0,0)
#-----------------------------------------------------------------------------
class StatusBar(pygame.sprite.Sprite):
"""status bar to track health"""
def __init__(self, object, rect,
outlineImg=None, insideImg=None,
attrName='health', fullAmt=100,
outerColor=black, innerColor=red ):
"""pass in a rectstyle to tell the statusbar where to appear
and pass in an object with a health attribute"""
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.outerColor = outerColor
self.innerColor = innerColor
#The outer image is usually something like a black outline
# but it could be more complex, maybe with text or something
if outlineImg is not None:
self.backImg, self.rect = load_png(outlineImg)
self.rect.move_ip( rect.topleft )
else:
self.rect = pygame.Rect(rect)
self.backImg = pygame.Surface( (self.rect.width,
self.rect.height) )
self.backImg.fill( self.outerColor )
#The inside image defaults to a red rectangle if no image
# is given.
if insideImg is not None:
self.innerImg, self.innerRect = load_png(insideImg)
else:
self.innerRect = self.rect.inflate( -10, -10 )
self.innerImg = pygame.Surface( (self.innerRect.width,
self.innerRect.height))
self.innerImg.fill( self.innerColor )
self.object= object
self.attrName = attrName
self.fullAmt = fullAmt
self.amt = getattr(self.object, self.attrName)
#For efficiency, the object can update it's status bar ONLY
# when it's health is changed, instead of every tick.
self.onlyUpdateOnExplicitRequest = 0
if( hasattr(object, "SetStatusBar") ):
self.object.SetStatusBar( self )
self.onlyUpdateOnExplicitRequest = 1
self.UpdateImg()
def update(self):
if self.onlyUpdateOnExplicitRequest :
return
self.UpdateImg()
def UpdateImg(self):
#First figure out how big the inner bar should be
amt = getattr(self.object,self.attrName) / float(self.fullAmt)
height = self.innerRect.height
fullWidth = self.innerRect.width
width = fullWidth * amt
if width < 0:
width = 0
self.image = self.backImg.convert_alpha()
self.image.blit( self.innerImg, (5,5),
Rect( [0,0,width,height] ) )
#this calls the 'main' function when this script is executed
if __name__ == '__main__': print "Not supposed to run me!"