简介
上一次我们写了贪吃蛇的显示部分,这次我们完善一下,将游戏控制也加入。(完整代码链接在最后)
开始动手
游戏输入
要收集键盘的按键响应,每帧收集一次,将收集到本帧按下的按键记录下来,如下代码片段。
class InputManager
{
int mCurrentKey = 0;
public:
void CollectInputKey()
{
if (_kbhit())
{
mCurrentKey = _getch();
if (mCurrentKey == 224)
mCurrentKey = _getch();
}
}
int GetCurrentKey() const { return mCurrentKey; }
static InputManager& Instance()
{
static InputManager inputManager;
return inputManager;
}
};
输入反馈
在游戏主逻辑下来识别当前按下的按键,然后做出相应的反应,这里我们没有过于细节的去处理每一帧接收到的按键,而是当前按下和松开按键后,按键记录变量中保留的始终都是刚才按下的按键。
void UpdateFrame()
{
mCurrentTime = clock();
// Get input
InputManager::Instance().CollectInputKey();
{
switch (InputManager::Instance().GetCurrentKey())
{
case InputKey::Left:
mSnake.SetDirection(ivec2::Left());
break;
case InputKey::Right:
mSnake.SetDirection(ivec2::Right());
break;
case InputKey::Up:
mSnake.SetDirection(ivec2::Up());
break;
case InputKey::Down:
mSnake.SetDirection(ivec2::Down());
break;
}
}
...
}
来点颜色
最后我们再让控制台可以输出各种颜色来丰富一下游戏的视觉效果,在渲染设备中加入对mColor字段的处理。如下代码片段。
for (int i = 0; i < mBlockBuffer.size(); i++)
{
for (int j = 0; j < mBlockBuffer[i].size(); j++)
{
int color = mBlockBuffer[j][i].mColor;
if (color == PixelColor::White)
{
std::cout << mPixelMap[mBlockBuffer[j][i].mPixel];
}
else
{
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
std::cout << mPixelMap[mBlockBuffer[j][i].mPixel];
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7);
}
}
std::cout << std::endl;
}
最后给食物增加逻辑,吃掉后消失并随机生成在新的位置,为了简单,没有判定食物不可以出现在蛇身上的情况。
最终效果
完成了一个简单的贪吃蛇逻辑,当然还有一些细节没有完善,例如屏幕刷新的时候会闪烁,游戏没有菜单等,当然这些都不是我们在意的重点问题,我们在意的是到现在为止,已经有了游戏元素,游戏逻辑,渲染逻辑,控制管理的概念。