I was able to somewhat successfully incorporate the state pattern into my project this week. As of now it’s simply being used to change the image of the user controlled character, Godzilla. I created two states for Godzilla depending on whether he’s engage with an enemy or not. When he engages an enemy by calling his performAttack() method on them it will switch his state to the EngagedState which will cause his sprite to change to one where he’s shooting a fireball. I say that I was somewhat successful because I’ve encountered two stumbling blocks related to how I want the performAttack() method and state pattern to function.
The first issue, and really the only part of my use of the state pattern that isn’t working, is making the sprite change back to the not engaged sprite after an attack has been performed. I basically want the fire breathing sprite to be displayed for a few seconds when I perform an attack and then for it to change back to the notEngaged sprite (not breathing fire). I’ve tried, in numerous places throughout the chain of commands, to reset the state to notEngaged. It works, in that it does reset the state, but it does so instantaneously such that you never even see the fire breathing sprite displayed. I’ve tried using the sleep function imported from time, thinking that I could make it pause for a few seconds before resetting the sprite but so far that’s only had the effect of pausing the canvas from being displayed and then when it is the sprite has already been reset to notEngaged. My attack behaviors are implemented using the strategy pattern and are the final step in the chain of actions when I call performAttack(), thus they seem like a logical spot reset the the sprite to me. Here’s what I was trying to no avail (the two commented out lines):
class AttackFireBreath(AttackBehavior): """breath fire attack behavior""" def attack(self, victim): victim.health -= 20 self.notifyObservers() print "I'm breathing fire at you!" # time.sleep(3.0): # self.setState(self.notEngagedState)
The second issue is that I want the performAttack() method to be called with the press of a key. I was able to get this functionality working properly as far as binding the proper keys and having a keyPressHandler send instructions to the GameWorld to call the performAttack() method. What I’m getting stuck on is how to make it perform that attack on an actual enemy on the screen. My train of thought is that when the performAttack() method is called I somehow need to cycle through each object in the gameWorlds object list, test if any of them are within some defined attackRange, perform attack if they are, else pass. Testing the distance between them is what I haven’t successfully implemented yet; I’m attempting to do it using the provided getLocation() method (in GameWorld.py) and the distance() method imported into GameWorld.py from Locations.py. Here’s screenshot of the hybrid code/pseudocode I currently have for this (in GameWorld.py):