在上一次,我们对初始版本的代码进行了一些优化,还记得优化了哪些地方么?[狗头]让我们一起来回顾一下吧:
首先,我们把箱子的场景数据拿了出来,单独放在了一个场景文本文件中。
这样的作用是让我们专注于代码的编写,而不是场景数据的维护。
然后我们优化了一维数组保存二维数据的方式,将一维数组定义成为了一个数组类,
用来保存二维的场景数据。
最后,我们还将实时状态定位为一个状态类,里面拥有画面的绘制,更新,游戏是否结束的函数
以及包含了两个数组类,用来存储场景数据以及对应的目标点标识。
那么今天的内容,便是优化之前的场景。之前我们使用了一些自定义字符来表示墙壁,玩家,箱子等,看上去非常的简陋。而本次,我们将把这些字符修改为有颜色方块,这样一来,我们的小游戏会更加美观。
在这里,我使用了平山尚所著的《游戏开发》书中的案例。
首先,我们需要在VS中,创建一个空的Windows桌面应用程序,并且创建一个main.cpp文件,我们的代码就全部都在这个cpp文件中了。
然后我们需要把书中提供的lib库链接到我们的项目中,这个lib库的作用便是提供了底层的应用程序绘制功能,我们只需要专注于游戏本身的逻辑即可。
对于之前的几个主要函数,我们只需要做一些小的修改便可以直接移植过来。下面我列出修改后的函数部分:
void State::draw() const {
for (int y = 0; y < mHeight; y) {
for (int x = 0; x < mWidth; x) {
Object o = mObjects(x, y);
bool goalFlag = mGoalFlags(x, y);
// 这里我们定义了一个unsigned类型来保存这个位置像素点的颜色
unsigned color = 0;
if (goalFlag) {
switch (o) {
case OBJ_SPACE: cout << 'X'; color = 0x0000ff; break;
case OBJ_WALL: cout << '#'; color = 0xffffff; break;
case OBJ_BOX: cout << 'Z'; color = 0xff00ff; break;
case OBJ_MAN: cout << 'P'; color = 0x00ffff; break;
}
}
else {
switch (o) {
case OBJ_SPACE: cout << ' '; color = 0x000000; break;
case OBJ_WALL: cout << '#'; color = 0xffffff; break;
case OBJ_BOX: cout << 'Y'; color = 0xff0000; break;
case OBJ_MAN: cout << 'p'; color = 0x00ff00; break;
}
}
drawCell(x, y, color);
}
cout << endl;
}
}
void State::drawCell(int x, int y, unsigned color) {
// vram便是底层Framework需要绘制的颜色数据
unsigned* vram = Framework::instance().videoMemory();
// 这里获取到应用程序窗口的宽度
unsigned windowWidth = Framework::instance().width();
for (int i = 0; i < 16; i) {
for (int j = 0; j < 16; j) {
// 为什么这里需要有两个循环并且乘以16呢?
// 其实是因为假如我们不这么处理,那么每个位置改变的仅仅是一个像素点,
// 而这里我们为了让方块更加显眼,所以我们将一个像素点修改为一个16*16的方块
vram[(y * 16 i) * windowWidth (x * 16 j)] = color;
}
}
}
主要改动的就是这个函数,其中改动地方我加上了注释,下面我们来看看代码的运行效果吧:
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved