推箱子的游戏很多人应该都玩过,那么尝试写一个蚂蚁推面包的游戏。首先整理一下游戏的需求。
1、 游戏中有蚂蚁、面包、洞、墙这些东西
2、 蚂蚁只要把所有的面包推入洞中,游戏就成功
3、 蚂蚁只能推得动一个面包,不能“拉”面包
4、 不能把面包往墙里推
首先看看该如何构造对象,分析一下,包括以下对象蚂蚁、面包、洞、墙、地板几种对象,然后看看有没有共同部分可以抽取,为它们抽取出一个功能的抽象类Module,表示物体,五种物体分别表现为可移动的(蚂蚁和面包)、可通过的(地板、洞)、不可通过的(墙)三类,分别使用IMoveable、ICrossable、IUnCrossable三个接口来限定,其中ICrossable和IUnCrossable学习微软的IRequiresSessionState,仅仅是一个声明性接口,其中并不包含任何成员。
这个游戏的业务难点在于移动,蚂蚁和面包实际上都可以(被)移动,其中变化比较多,一个面包可以动,前面是墙不能动,两个面包不能动等等,最后还是决定向微软学习,统一都使用IMoveable的Move方法,但是在Move方法的实现中,并不进行判断,而交给外界决定,参考Form的FormClosing时间,其中有一个e.Cancel如果设置为True,那么就取消事件,为IMoveable接口增加Moving事件,
事件具体实现代码如下:
而具体事件监听的方法实现如下:
而Moved方法主要用于移动成功后的局部刷新界面,以避免每次移动后,都要对整个页面进行刷新。
总而言之,移动的代码争取越晚实现越好。
数据的保存
使用xml文件进行数据的保存,保存的范例基本如下
以上的结构描述了第一关,列宽是20,行数由具体数据决定,Layout节点中是具体数据,其中n表示地板,w表示墙,b表示面包,h表示洞,a表示蚂蚁,对应的图应该如下图
从XML文件到图实际上包括的部分有xml文件读取,构造一系列对象,描绘对象,同样分层分类实现。
1、 XMLReader类专门用于针对xml文件进行读写
创建对象主要用到的是提供xPath的索引器
2、 Level关卡类封装一个关卡,内部保存一只蚂蚁、一堆面包、一堆地板和洞(CrossObjects)、一堆墙(UnCrossOjbects)
3、 由于所有的操作对象都在Level类中封装了,因此可以使用简单工厂LevelFactory来生产Level这个产品
最后界面的操作就比较简单了
1、 为关卡的蚂蚁和面包监听Moving对象判断移动
2、 为Moved成功后判断重绘对象
3、 监听键盘事件,调用移动方法
总结一下,主要用到的知识点有:
自定义委托以及事件、继承、接口编程、XML、简单工厂模式、最后蚂蚁的单件模式其实没有必要。
最后还写了一个关卡编辑器来扩展关卡,可以调用LevelFactory的SaveLevel方法来保存到xml文件,不过写得比较随意,也许还有一些bug,有兴趣的朋友自己研究好了。