一、观察者模式

  观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发生改变的对象称为观察目标(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 = []   #更新Observerdef 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 - 1if self.__total_monsters <= 0:  # Winning conditionprint('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() - damageself.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

                                            

转载于:https://www.cnblogs.com/guilai2018/p/9858348.html

游戏项目中观察者模式解析相关推荐

  1. Network-Monitor项目中观察者模式解析

    一.观察者模式概要 在多个对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新,也就是发布订阅模式.当发布者发布消息时,,订阅了此发布者的人能监听到信息,,没订阅此 ...

  2. 作业三_C#中的观察者模式解析

    作业三_C#中的观察者模式解析 一.观察者模式的理解分析 由于之前没有接触过观察者模式,所以找了一段源码编译运行调试一下.下面是观察者模式用C#模拟实现的示意源码.该段代码模拟了观察者模式的一个运行原 ...

  3. 《Lua游戏开发实践指南》一3.2游戏项目中的Lua

    3.2游戏项目中的Lua 把脚本语言集成到游戏项目中可以提升团队的开发效率,并且可以很好地扩展原生编译语言的能力.Lua在游戏开发的许多基础领域中都表现得很出色. 在游戏开发团队中,可能有许多成员都使 ...

  4. JAVA方法调用中的解析与分派

    JAVA方法调用中的解析与分派 本文算是<深入理解JVM>的读书笔记,参考书中的相关代码示例,从字节码指令角度看看解析与分派的区别. 方法调用,其实就是要回答一个问题:JVM在执行一个方法 ...

  5. Oracle中SQL解析的流程

    Oracle中SQL解析的主要流程: 我们说的游标概念比较复杂,它可以是客户端程序中的游标,服务进程中的私有游标,以及服务器端共享池里的共享游标.假设一个游标被打开了,一般来说它的共享游标信息(包括执 ...

  6. iOS中XML解析汇总

    在时间上TBXML占优,libxml2支持了边下载边解析. 来源:http://www.codeios.com/forum.php?mod=viewthread&tid=9880&hi ...

  7. 论游戏项目中的左与右

    标题<论游戏项目中的左与右> 何为左与右?左,左倾,即 激进主义,冒险主义,盲动主义.右,右倾,即 消极主义,保守主义,投降主义. (一)先说说关于左的例子. 左例之一:激进主义 遇到一个 ...

  8. Android中怎获取json,Android应用中如何解析获取的json数据

    Android应用中如何解析获取的json数据 发布时间:2020-11-24 17:10:08 来源:亿速云 阅读:107 作者:Leah 这篇文章将为大家详细讲解有关Android应用中如何解析获 ...

  9. linux源码文件名,Linux中文件名解析处理源码分析

    Linux中文件名解析处理源码分析 前言 Linux中对一个文件进行操作的时候,一件很重要的事情是对文件名进行解析处理,并且找到对应文件的inode对象,然后创建表示文件的file对象.在此,对文件名 ...

最新文章

  1. 模态框获取id一直不变,都是同一个id值
  2. 功能整合(二):轮播图(可控)、事件流
  3. Docker:学习笔记(1)——基础概念
  4. docker详细介绍
  5. Python 路径问题:cv2.error: OpenCV(4.1.0)...size.width>0 size.height>0 in function ‘cv::imshow‘. 解决方法
  6. Redis的Set操作
  7. 刚刚!第七次人口普查出炉!男性比女性多3490万,老龄化进一步加深
  8. C语言错误c2063,请教C语言中关于将二维数组复制到一个三维数组的问题
  9. java 获取方法的注释_java – 有更有效的方法来获取注释方法吗?
  10. [译] 手摸手教你如何轻松发布私有 App
  11. 蓝队应对攻击的常用策略二
  12. 2020计算机应用模拟题,2020年函授本科计算机应用基础课后作业、模拟题及答案...
  13. python接入讯代理_[Python3网络爬虫开发实战] 9.3-付费讯代理、阿布云代理的使用...
  14. 天泉证道四句教与价值观
  15. EV SSL证书和普通证书的区别
  16. imshow显示图像为纯白
  17. java验证图片大小_java 校验图片的大小、尺寸、比例
  18. P17安全领袖圆桌:安全市场迎来千亿发展机遇,腾讯携手产业链伙伴共建安全生态
  19. 如何使用html、css制作一个期末作业网站【羽毛球体育运动主题html网页设计】
  20. 12864液晶屏接口定义,16引脚的(普中科技所配)

热门文章

  1. 浏览器访问网页的详细内部过程
  2. 【2】最简单的Laravel5.1程序分析
  3. 传智播客 Html基础知识学习笔记
  4. Nginx 的 Location 配置指令块
  5. CSS 魔法系列:纯 CSS 绘制各种图形《系列五》
  6. ASP.NET中GridView数据导出EXCEL小结
  7. 摩托车午夜飙车撞进公交车下 肇事车主当场死亡
  8. Flutter抖动动画、颤抖动画、Flutter文字抖动效果
  9. Android 自定义View绘制的基本开发流程 Android自定义View(二)
  10. 老码农的Java干货资源