• Advertisement
Sign in to follow this  

Python Event Handlers

This topic is 1462 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys.  I'm creating a simple text adventure using Python to learn the language and get more accustomed to OOP.  

 

How would I go about adding characters that enter a room?  I have the rooms created and put into a dictionary when the game is started.  The players/characters are then synched with the room(verified by instance id's). Now, in order for the characters to interact with each other,  I figured, I will need a dictionary and whenever someone enters the room, an event handler for the room class would add the player that entered into the dictionary.

 

If this is true, how would I go about creating an event handler so that the room automatically adds characters that enters the room to the room's dictionary of characters.  If there's a better/easier way of doing this, please let me know.

Share this post


Link to post
Share on other sites
Advertisement

Sounds like you are on the right track. Having a location or container keep a set or dictionary of contained entities is a perfectly valid way of organizing that sort of data. I'm a little bit concerned by the word "synced" because I have never heard that term used when describing this sort of problem. Anyway, I use what is called a publisher/subscriber model for events. Basically, entities that are interested in certain types of events will subscribe for messages about those events. When an event occurs, a publisher is instructed to publish a message about the event. Messages have a topic indicating which type of event occurred. This is how the publisher knows which entities to notify about the event.

 

Relating this to your type of game, say you have a room representing a shop. When a character enters or exits the shop, you could publish a message. Shopkeepers could subscribe for this message, and issue a greeting or farewell as appropriate. Let me see if I can scratch up a code example.

import collections

class Publisher(object):

    def __init__(self):
        self._subscriptions = collections.defaultdict(set)

    def publish(self, topic, *args, **kwargs):
        subscribers = self._subscriptions[topic]
        for subscriber in subscribers:
            subscriber(topic, *args, **kwargs)

    def subscribe(self, topic, subscriber):
        self._subscriptions[topic].add(subscriber)

    def unsubscribe(self, topic, subscriber):
        self._subscriptions[topic].discard(subscriber)

publisher = Publisher()

class Room(object):

    def __init__(self):
        self.entities = set()

    def on_enter(self, entity):
        self.entities.add(entity)
        publisher.publish(('on_enter', self), entity)

    def on_exit(self, entity):
        publisher.publish(('on_exit', self), entity)
        self.entities.discard(entity)

shop = Room()

class Character(object):

    def __init__(self, name):
        self.name = name

    def enter(self, room):
        room.on_enter(self)

    def leave(self, room):
        room.on_exit(self)

player = Character("bheo")

class Shopkeeper(object):

    def __init__(self, name, greeting, farewell):
        self.name = name
        self.greeting = greeting
        self.farewell = farewell

    def enter(self, room):
        room.on_enter(self)
        publisher.subscribe(('on_enter', room), self.say_hello)

    def leave(self, room):
        publisher.unsubscribe(('on_exit', room), self.say_goodbye)
        room.on_exit(self)

    def say_hello(self, topic, entity):
        print self.greeting.format(entity.name)

    def say_goodbye(self, topic, entity):
        print self.farewell.format(entity.name)

cleric = Shopkeeper('Cleric', 'Blessings of the Gods upon you, {0}.',
                    'May the Gods light your path, {0}.')
blacksmith = Shopkeeper('Blacksmith', 'Finest arms and armor, {0}.',
                        'Thank you for your business, {0}.')

cleric.enter(shop)
blacksmith.enter(shop)

player.enter(shop)
player.leave(shop)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement