J
Jonathan Hartley
One common way to store delayed actions is as a lambda (an anonymous
function.) A lambda defines a new function:, and you can call this function later. The created function has no
name, (but you can assign it to a variable to give it a name if you
like) and can be called later:So in the game, you could have a collection 'effects', each one will
be a lambda:effects = []At the start of the round, as each entity makes its moves, they add
lambdas to this collection.effects.append(
lambda: decrease_hp(monster_a, 4)
)
effects.append(
lambda: lose_item(monster_a, item_b)
)Instead of appending it directly like this, I imagine the lambdas
could be returned by the monster's 'act' or 'update' method:class Monster():
def act(self):
# blah and finally
return lambda: decrease_hp(monster_a, 4)Then for the start of a round, first you ask each monster what action
it is going to perform:for monster in room.monsters:
effects.append(
monster.act()
)Then for the end of the round, call all the lambdasfor effect in effects:
effect()
Mr. Roy Smith already proposed using closures. I already did a similar
thing in my code, but instead of decrease_hp() I have AttributeEffect
class which is able to modify any attribute (in old RPGs some monsters
could drain your intelligence, in my game laser gun hit will decrease
HP as well as armor integrity). The first version looks like this
(missing few checks):
class AttributeEffect(object):
'''Effect changes object's attribute by delta'''
def __init__(self, obj, attrib, delta):
self.obj = obj # reference to object the effect
applies to
self.attrib = attrib # name of attribute that effect
applies to
self.delta = delta # change of value for
object.attribute
def apply(self):
value = getattr(self.obj, self.attrib) # todo: try, except
value += self.delta
setattr(self.obj(), self.attrib, value)
Yesterday I learned that Python 3.0 introduces nonlocal keyword which
would simplify defining effect functions and passing them along. Nice
improvement.
Very cool, that looks like it would work. The thing I like about the
lambda idea though, is that you don't have to write any classes like
AttributeEffect, (and presumably other such classes, like
LoseItemEffect, etc.) Instead of *modelling* the different kind of
effects that could happen, you just write code that *performs* the
desired effect. (e.g. monster.hp -= damage) To my eyes, lambda's are
therefore more flexible and require less code. But I could be wrong,
and obviously you should do what you think is best for your
circumstances. Very best of luck with it.
Out of interest, is there anywhere you blog about the game
development, or are likely to make announcements?
Jonathan Hartley