On 4/3/2011 9:55 PM, Ryan Strunk wrote:
Hi list,

Hi

I've read your code. Frankly I don't understand your problem. I also don't see any occurrence of "health".

Could you point to a specific line of code, explain what you want and what you are getting.

Also your description of the program and the program itself is kinda overwhelming, and so much of that information is not relevant to your question. That makes it hard to understand the question.

How about posting the smallest possible piece of code that exemplifies the problem?

Python does not "pass by value". It passes a reference to the argument. In essence:

def foo(a): pass
b = somePythonObject # b is now a reference to somePythonObject
foo(b)

In calling the function Python "binds" local name a to somePythonObject
a is now another reference to somePythonObject

I am in the midst of trying to code a game based entirely on audio cues, and
I've run into a bit of a snag when trying to monitor certain variables. I'll
lay out the framework of what I'm going for in the hope that it makes sense
when written down.
In a standard video game I could have a health bar go from normal to yellow
to red as it diminishes. In audio, though, I don't have that luxury. As a
result, I have conceptualized a system whereby a player hears a sound every
so often if a particular stat drops into the caution range. If the player
drops into the danger range, the sound loops continuously. I also wanted to
make sure that if the player dropped from caution to danger, there wasn't a
big, awkward pause in the sound loop and that the player would know
immediately that his stat had dropped (see first and second if checks in the
check method).
The problem:
My existing methods directly update stats. For example: the player class has
a self.health stat which is directly affected by other methods. This has
caused no problem up until now. When I pass self.health to the code I will
paste below, however, the Statistic class does not receive health, but
rather health's value.
I understand that python passes variables by value and not by reference, and
this has not been a problem up until now. Now that I am trying to design a
class which explicitly checks a specific variable, though, I can't fathom a
way to do it unless I pass a direct reference, and I'm not sure that can be
done. I need to figure out a way for the below code to check the value of
the health variable and act on it. This way, if player's self.health
changes, the static class will take note of that and respond accordingly.
It occurred to me to make Statistic a child of int, but I'm told that's more
trouble than I probably want to deal with.
Any suggestions/advice anyone has would be greatly appreciated.

Best,
Ryan

import sound_lib
from game_utils import delay
#this encapsulates threading.Timer's assignment and start method

class Statistic(object):

     def __init__(self, stat=None, sound=None, low=None, mid=None,
high=None):
         self.stat = stat
         self.sound = sound
         self.low = low
         self.mid = mid
         self.high = high
         self.status = 'safe'
         self.auto_check_timer = None

     def auto_check(self):
         if self.stat>  self.high:
             self.status = 'safe'
             return
         if self.mid<= self.stat<= self.high:
             self.status = 'caution'
             self.sound.play(True)
             self.auto_check_timer =
delay(self.sound.bytes_to_seconds(len(self.sound))*2, self.auto_check)
             return
         if self.low<= self.stat<  self.mid:
             self.status = 'danger'
             self.sound.play(True)
             self.auto_check_timer =
delay(self.sound.bytes_to_seconds(len(self.sound)), self.auto_check)

You can simplify the above logic:

         if self.stat > self.high:
             self.status = 'safe'
         elif self.stat >= self.mid:
             self.status = 'caution'
             self.sound.play(True)
self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound))*2, self.auto_check)
         elif self.stat >= self.low:
             self.status = 'danger'
             self.sound.play(True)
self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound)), self.auto_check)
     def check(self):
         if self.status = 'caution' and self.low<= self.stat<  self.mid:
             #This will set the program to start a constant alarm when the
stat level has dropped below caution
             self.auto_check_timer.cancel()
         if self.sound.is_playing:
             #to assist in setting up the caution to danger transition
             #a standard playing sound will have a timer running alongside
it, so skip the next guard and return
             if self.auto_check_timer.is_alive() == False:
                 #guard to make sure program doesn't catch every playing
sound, should prevent repeated checks from recalling auto_check
                 sound_duration =
self.sound.bytes_to_seconds(len(self.sound)) -
self.sound.bytes_to_seconds(self.sound.position)
                 self.auto_check_timer = delay(sound_duration,
self.auto_check)
             return
         if self.auto_check_timer == False:
             #if the timer has never been called, call auto_check
             self.auto_check()
             return
         if self.auto_check_timer.is_alive == True:
             #there's already a timer running. return
             return
         #If it gets this far, it's because the timer already ran, the player
is 'safe', and another check is being performed
         self.auto_check()

Also note

if self.auto_check_timer == False:

can be simplified to

if not self.auto_check_timer:


and

if self.auto_check_timer.is_alive == True:

to

if self.auto_check_timer.is_alive:

also it is better to eliminte the returns and use elif as I did furhter above

--
Bob Gailer
919-636-4239
Chapel Hill NC

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to