一、前言
从本章开始,我们将逐步对原有程序进行优化。
优化的方面有很多,比如本章介绍的便是代码层面上的优化。
其它的还有游戏程序执行逻辑上的优化,比如我们游戏地图写死在程序里面就有些不好,我们可能更想要将其分离出程序,动态加载地图。
这样的好处就是,当你更新游戏地图的时候,就不用再去修改程序了,即两者分离了。
二、枚举
说话本章要讨论的重点:枚举。
它的使用方式如下:
enum name{
a=1,
b=2,
c=3
};
正如你所看到的,它是用关键字enum
来声明的,这就和普通的变量声明差不过,比如int name;
。
只不过不同之处在于,它后面跟了一个大括号,然后里面写了一系列的等号,比如a=1,b=2
这种。
这就是在给数字重新命名,将a
这个字母重新赋予了1
的含义。
之后你再使用字母a时,它就不再是单纯的字母了,而是一个枚举值:1。
上面的写法如果用宏替换的话,等于于下面这样:
#define a 1
#define b 2
#define c 3
那我们为什么要用枚举来替换宏呢?毕竟相比较而言,宏的功能可比枚举强的多。
枚举只能给数字重命名,而宏则可以给任意东西重命名,因为宏的本质是替换。
原因并不复杂,那就是宏纯粹只是通过替换实现的。
那么首先一点就是它没有组织性,每一个宏定义都是独立的,即使这些宏可能比较相关。
而枚举你就可以将相关联的枚举量写在一起。
其次就是,编译器无法检测它的对错,因为它单纯就是替换,这就导致一旦出错,你也很难定位具体的错误点。
而枚举不一样,它也是C语言的一种基本结构,编译器会检测它的错误的,一旦出现错误,你很容易排查出来。
三、使用枚举
枚举的使用并不难,直接拿我们的代码来测试即可,将所有相关的宏定义更改为枚举。
首先就是定义,将原有的宏更改为对应的枚举即可:
enum Game {
SPACE = 0, //空地
WALL = 1, //墙壁
TARGET = 3, //目标位置
BOX = 4 , //箱子
TARGET_IN = 5, //箱子已经推到目标位置
PLAYER = 6 , // 玩家
PLAYER_IN_TARGET= 2 //玩家在目标位置
};
然后你依旧可以向往常一样正常使用,其它代码丝毫不需要更改。
唯一变化的可能就是vs中的代码颜色,从原有的紫色,替换为现在的淡绿色。
这个时候,如果你写错了,比如让里面的枚举量SPACE
等于字母o
了,编译器就会直接报错,并且报错点在这个枚举定义的地方,你可以直接修改。
但如果你使用的是宏,由于它是通过替换的方式进行的,那么报错地点就会是所有你使用到宏的地方。
一般你就会看到大量的红线、错误提示,短时间就不容易排查错误了。
四、枚举进阶
虽然上面就是枚举最基本的用法了,但其实还可以简写。
比如你发现我们上面的枚举名Game
根本没用啊!
所以你是可以省略的:
enum{
SPACE = 0, //空地
WALL = 1, //墙壁
TARGET = 3, //目标位置
BOX = 4 , //箱子
TARGET_IN = 5, //箱子已经推到目标位置
PLAYER = 6 , // 玩家
PLAYER_IN_TARGET= 2 //玩家在目标位置
};
同时由于这种数字递增的方式定义枚举量太常见了,所以它默认就是递增的,你可以省略掉其中比较规范递增的枚举量赋值:
enum{
SPACE = 0, //空地
WALL = 1, //墙壁
PLAYER_IN_TARGET= 2, //玩家在目标位置
TARGET = 3, //目标位置
BOX = 4 , //箱子
TARGET_IN = 5, //箱子已经推到目标位置
PLAYER = 6 , // 玩家
};
调整为上面的位置顺序,那么就刚好为0-6
依次递增。
这时就可以省略后面的数字:
enum{
SPACE, //空地
WALL, //墙壁
PLAYER_IN_TARGET, //玩家在目标位置
TARGET, //目标位置
BOX , //箱子
TARGET_IN, //箱子已经推到目标位置
PLAYER, // 玩家
};
这两种写法完全等价。
但这种简化写法只推荐在简单区别下使用,而我们这里由于SPACE
这种含义明确的枚举量必须为0(地图数据中就是这么写的),那么如果有人不清楚这一点,更换了各个枚举量的位置,程序就会立马出问题。
对于这种明确某个枚举量必须为某个数字的情况下,最好还是将后面的数字明确的写出来。