欢迎光临散文网 会员登陆 & 注册

pvzclass是如何实现的?pvzclass源代码初步分析(7)PVZ类的其他成员类

2021-08-02 12:31 作者:__W1thoutD0ubt  | 我要投稿

在第5篇中,我们已经具体分析了Plant类和Zombie类的代码。

本篇将对PVZ类剩余的成员类进行分析。

强烈建议在阅读本篇前先阅读第3~5篇的内容

注:本文以2021.6.27更新的版本为准。

成员类介绍

PVZ类的直属成员类共有22个,每一个都与PVZ本体中的变量存在直接的对应关系。

其中,Grave(墓碑)、Crater(毁灭菇生成的坑洞)、Brain(脑子)、Snail(花园的蜗牛)和Vase(罐子)都是Griditem的派生类。

CardSlot类具有自己的成员类SeedCard,以控制每个卡槽的属性。

SaveData类具有自己的成员类GardenPlant,以控制花园植物的属性。

在官方Readme文件中,PVZ类的直属成员类分为三种:

  • Animation类。

  • 唯一指定的类。这些类通常起控制作用,需要用pPVZ->GetXXX的方式获得。

  • 游戏内的对象实体类。这些类需要手动获取PVZ中的第n个对象。部分类可以用pPVZ->GetAllXXX的方式获得全部可用的对象。

以下类属于唯一指定的类:

  • Lawn

  • Icetrace

  • Wave

  • Mouse

  • MousePointer

  • Caption

  • Miscellaneous

  • SaveData

  • Music

以下类属于游戏内的对象实体类:

  • Zombie

  • Projectile

  • Plant

  • Coin

  • Lawnmover

  • Griditem及其派生类

  • CardSlot

当然,Animation类实际上也可以算作对象实体类。

SeedCard类和GardenPlant类在代码上和Wave类更加相似,也可以算作“唯一指定的类”(即使它们显然不是唯一指定的)。

代码分析

PVZ类的成员类都由三部分构成:基址和构造函数、对象属性、方法。

在构造函数上,CardSlot类和所有唯一指定的类都以"address"或"Baseaddress"为参数。这些类的构造函数都是“地址+偏移”型的:

(以上为CardSlot类的构造函数)

Animation类,以及除CardSlot类外游戏内的对象实体类则以"indexoraddress"或"idoraddress"为参数。

这些类的构造函数在“地址+偏移”型的基础上添加了将编号转换为基址的代码:

(以上为Projectile类的构造函数)

各种类在对象属性上都一样,除了少数属性使用PROPERTY_BINDING宏及其变种定义外,几乎所有属性都用T_PROPERTY宏及其变种定义。

方法上,所有方法都是在PVZ.h中声明,在其他源代码文件中定义。这些文件集中于Classes文件夹。

虽然PVZ类的成员类方法繁多,但在原理上可以大致分为以下多种:

直接写入
直接读取
调用Windows API
调用PVZ内部函数

值得一提的是,Animation类的UnLock()方法使用了状态压缩,其状态的定义在PVZ.h开头:

看上去很长的代码,实际上并不复杂。找到了原理层面的东西后,就不难分析pvzclass的代码了。

下一篇将分析Creaters,pvzclass生成对象的代码。


参考资料与文献

pvzclass的Readme文档

Lazuplis-Mei(Github名)于2019年6月11日上传

YouTheB(Github名)于2020年3月更新

pvzclass是如何实现的?pvzclass源代码初步分析(7)PVZ类的其他成员类的评论 (共 条)

分享到微博请遵守国家法律