Assignment 7 Progress: The State Pattern

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):

playerAttack

Advertisements

One comment

  1. dellswor

    Concurrency is hard… that is sort of the root of the problem displaying the fire for a little while. The example code attempted to avoid concurrency using the while loop that enforces the turns/frames; which means that your sleep call causes everything to stop. A solution may be to add a counter to your state to count how many frames have occurred since the state changed to flaming and only change back after the counter reaches some number (maybe 6 or 10).
    I think your approach for the attack sounds reasonable. Collision detection needs to compute distance between two things in the world, I’d look there for things that could be helpful for detecting who the attack should effect.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s