02 点击放置植物功能的实现以及类图设计
今日目标
实现对象 | 实现昨天设计的类。 |
设计类 | 学习类图的设计,并用类图进一步设计类的关系。 |
场景编辑器(失败,时间不够) | 学会用场景编辑器并编辑第一个场景。 |
实现对象
先将资源放入解决方案中的Resources的res文件夹里,cocos默认的代码就将res放入资源路径里了
可以考虑将res添加进资源路径列表中,类似于电脑中的环境变量path,以后添加资源时会尝试搜索res(本人以前使用旧版cocos开发,所以习惯用res文件夹了。如果不用也可以,注意好资源路径对应就行)
CCLOG("nihao");用于在调试模式下输出信息到VS的控制台,一会写代码时可以用该技巧调试代码。
init函数是当前图层初始化时会调用的函数,我们一会就在这里初始化初始的精灵和卡牌面板,接下来开始实际编写代码。
第一步先实现卡牌系统和让游戏能放置一个植物到目标点。
建立CardBar类,会默认建在win32文件夹下,一会需要把所有的代码转移到Classes文件夹内
CardBar头文件写成如下就可以,继承Menu,这样一会可以让卡牌是MenuItem,这样点击并有效果和排版很方便。但现在缺少card类,需要再定义一个card类
卡牌类的定义如下,继承了MenuItemImage,一会可以方便的添加点击效果等。可见还得定义阳光Sun类和Plant类。
阳光类初步定义如下
植物类定义如下
观察发现Sun类不依赖其他类,所以先实现它
vs2015以上版本都有直接创建定义的方法,在快速操作和重构选项里,就是偷懒的方法,还不错
实现效果如下,setSize方法还可以设置改变大小。以25数值大小的阳光为基准,比这个大则就会大一点,比这个小就会比原图小一点。
Plant类可以实现如下,先随便初始化一个图(initFile方法),这样可以先调试放置植物的功能,再稍后调试各种植物的效果。
其他类的编写细节就不展示图了,文字说明即可,因为修修改改的地方很多。
后来编写Card类时发现,可能需要创建Plant对象,这里用宏就是自动建立了一个create静态函数,并且自动调用init,并返回对象。咱们可以直接用这个cocos提供的宏将我们所有的需要cocos管理内存的类来创建。
写代码的过程中顺便学了C语言中 可变长参数的使用和原理,算第一个额外收获。
经过4小时的代码编写和改错(4小时不长,进入了心流状态),终于实现第一个功能的一半,现在可以点击卡牌将半透明的植物展示出来。展示的位置是卡牌的位置。但问题是卡牌基于菜单来设置的,所以需要获得卡牌基于OpenGL窗口的位置。我们的最终效果是 让花出现在 卡牌位置,并让鼠标移动可以控制花的位置,所以要先让花出现在卡牌显示的位置。
插曲:本人重新在m2固态硬盘里建立了新项目,并将项目名改为PVZ。并从原来机械硬盘中的项目里把代码和资源提取出来了。这下运行只需要1s即可运行,重新编译整个项目也只需要5秒时间,加快了开发调试速度(普通电脑可能需要几十秒时间,我的电脑是i7-8700,硬盘m2固态,所以编译很快)。
查询资料可知如何获得一个点的绝对坐标,一个点的绝对坐标用这个点父节点的 convertToWorldSpace即可获得(本质是不断的坐标系变换,可以写但麻烦,如果理解原理就不用追求造轮子)
代码中的体现是——
运行的效果变为——
下一步想办法实现让花跟着鼠标移动。所以需要设计新类,该类代表玩家,负责监听鼠标,并且可以控制卡片等物品。
玩家代理 playerAgent |
代表一个玩家对象。监听着鼠标。可以用设计模式中的单例模式来安排该类,因为单机游戏只有一个玩家(以后想双人游戏时再行研究)。 class playerAgent; pickUp(Plant*) 控制一个植物。该植物会跟着鼠标移动。并且将该植物设置为半透明,等放下时再设置为不透明。(目前只可以控制植物,一会需要能控制铲子,所以需要再抽象一层,一会的事一会再说) putDown(); 放下手中的植物到鼠标当前位置。 bool isEmptyHand(); 是否是空手,点击植物卡牌时应判断是否是空手再决定是否catch |
---|
实现如下:(不是最终定论,还在设计阶段)
然后将玩家代理融入plant类和card类的代码中,实现了可以插入任意位置的花。
考虑插入光标功能,展示自定义光标,但自定义光标交给哪个对象管理出了问题。后来重整项目结构,用PlayerAgent管理光标。不让PlayerAgent是单例模式,由场景管理playerAgent类的hand对象。这样不同场景光标不同也方便设置了。手抓住的节点就是 playerAgent对象的子节点。改变playerAgent对象所有抓住的对象也跟着改变。
然后用showCursor(false) 关闭展示鼠标。
现在playerAgent就代表一个光标,可以拿东西可以放东西。个人感觉更符合面向对象的气质。
重新布置窗口大小和CardBar位置。
再优化代码结构,这回可以通过设置hand的透明度来间接控制所有被hand持有的物品的透明度了。这样以后如果有一些原有就是透明的物体不会因为被点击而改变透明度。
写到这里 已经22点了,好家伙今天写了8个多小时才搞出来点击放置的功能还没确准。剩下时间梳理下目前的逻辑,然后尝试画出类图,明天再尝试用场景工具。
使用ProcessOn在线工具来绘制UML图。