游戏项目中观察者模式解析

一、观察者模式

  观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发生改变的对象称为观察目标(Subject),而被通知的对象称为观察者(Observer),一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。

  观察者模式定义如下: 观察者模式(Observer Pattern):定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

                                

注意:Subject调用Observer的update()方法,理解这一点就不会混淆了。

 

二、游戏简要说明

游戏中有一个玩家,他处在一个5X5的区域中,每个区域为一个房子。在每个房子各中有一些人,他们都变成了可怕的怪物。玩家的目标是通过向怪物投掷不同的糖果,将所有的怪物变回正常人。不同的糖果具有不同的攻击效果。怪物易受一些特定类型的糖果的攻击,而对另外一些类型的糖果免疫。

玩家所有npc(即怪物)具有一定量的生命值和攻击level。玩家在移动到下一个房子之前,必须清空当前房子中的所有怪物。如果玩家生命值变为0,则玩家失败;如果玩家成功清除所有房间中的怪物,则玩家胜利。

 

三、通过代码展示观察者模式

抽象Observer类:

class Observable(object):
    def __init__(self):
        self.observers = []

    def add_observer(self, observer):
        if not observer in self.observers:
            self.observers.append(observer)

    def remove_observe(self, observer):
        if observer in self.observers:
            self.observers.remove(observer)

    def remove_all_observers(self):
        self.observers = []
   
   #更新Observer def update_observable(self): for observer in self.observers: observer.update_observer()

具体Observer类:

class Game(Observer):
        #注:只截取了与观察者模式有关的代码部分
        def update_observer(self):
        self.__total_monsters = self.__total_monsters - 1
        if self.__total_monsters <= 0:  # Winning condition
            print('You Win!\nYour neighborhood is now safe.')
    
class House(Observer, Observable):
   #注:只截取了与观察者模式有关的代码部分 def update_observer(self): # Remove any monsters with health <= 0. for m in self.__monsters: if m.get_hp() <= 0: self.__monsters.remove(m) self.__house_monsters = self.__house_monsters - 1 # Now add a person to replace the monster. person = Person() self.__monsters.append(person) # Update the game object observing. self.update_observable()

具体Subject类:

class House(Observer, Observable):
        def update_observer(self):
        # Remove any monsters with health <= 0.
        for m in self.__monsters:
            if m.get_hp() <= 0:
                self.__monsters.remove(m)
                self.__house_monsters = self.__house_monsters - 1
                # Now add a person to replace the monster.
                person = Person()
                self.__monsters.append(person)
                # Update the game object observing.
                self.update_observable()
class Monster(Npc, Observable):
        def monster_defence(self, weapon, attack):
        # Calculate the damage from player's weapon.
        damage = self.get_multiplier(weapon) * attack * \
            weapon.get_mult()
        health = self.get_hp() - damage
        self.set_hp(health)

        if health <= 0:
            print('%s defeated! It became a helpful human!'
                  % (Monster.monster_id[self.get_id()]))
            Monster.__decrement_monster_count()
       #更新观察者house # Update all houses watching of a monster purified. self.update_observable() else: print("%s hit for %.1f damage, now at %.1f health points." % (Monster.monster_id[self.get_id()], damage, health))

结论:

1)Game类观察house类。Game类是Observer,house类是Subject。

2)house类观察Monster类。house类是Observer,Monster类是Subject。

观察者模式的优点:

 

使用观察者模式很好的降低Observer和被Subject的耦合程度,并且观察者模式满足了“开闭原则”的要求,增加新的具体Observer无须修改原有系统代码,在具体Observer与Subject之间不存在关联关系的情况下,增加新的观察目标非常地方便。

在本项目中,使用观察者模式可以方便地对游戏主类Game类的house信息进行更改,而同时house也作为Oberver观察Monster类,方便地更改house中的Monster信息。这样一种层次化的观察者模式使得游戏项目层次清晰,解耦合度高,方便设计与维护。

 

四、项目地址与及运行截图

https://github.com/dunnow16/Zork_Text_Game

                                            

 

posted on 2018-10-26 19:44  dxwtony  阅读(341)  评论(0编辑  收藏  举报

导航