当你用c++控制台一直练习 cout<<"hellow world" 写各种循环 写数组、链表、容器。
当你已经厌烦 看到你想要的内容输出在控制台上的那份成就感 ,你是否想写点不一样的东西。
在这里我就记录下写的第一个游戏——贪吃蛇。
--导读
写一个完整的程序准备是非常重要的。
首先我们要了解的游戏的本质:死循环(死循环的方法只有你点了退出游戏或者关闭电源)
然后就是框架,打好一个框架对后续的编程有很大的影响,不然新手总会出现写了这行又停下来想半天下一行怎么写。
最后就是动手了,动手是最快的学习编程的方法,如果你有想法,那就赶紧下载软件,然后开始自己的第一个项目。
说了半天什么是死循环呢,死循环又怎么写呢。
我们可以先想想一个最简单的游戏,就是我说1,你说2,然后我说3,直到谁说不下去或者不想说了。是不是很幼稚,但是用代码又是如何实现呢?
int main()
{
while (true)
{
//玩家1输入i
//玩家2输入i+1
}
}
伪代码。。。
切入正题
贪吃蛇嘛。先事先构思一下思路
1.画一个地图
2.然后画出蛇
3.让蛇移动
4.产生食物
5.蛇吃食物
6.撞自己或撞墙
1.画地图
首先需要画一个地图,先画一个矩形吧,这里没用到绘画技术,而是用到最简单的形式输出
int arrMap[20][40] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
};
没错,就是定义一个数组,但是如果只是输出01的话感觉不是很美观
这个时候我们就需要来遍历这个数组,当数组为0的时候就输出空地,为1就输出墙
void DrawALL()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 40; j++)
{
if (1 == arrMap[i][j])
{
cout << "※";
}
else
{
cout << " ";
}
}cout << endl;
}
}
2.画蛇
其实贪吃蛇有很多种方法,但最终版的就是用链表去画蛇。不懂链表的可以翻翻我之前的笔记,有C++里的链表
首先定义一个蛇的结构体,就是蛇的蛇头和每一节身体。
//蛇结构体定义
struct Snake
{
//初始化
Snake()
{
iRow = 0;
iCol = 0;
pNext = nullptr;
iRowBk = 0;
iColBk = 0;
}
//行列坐标
int iRow;
int iCol;
//行列坐标备份
int iRowBk;
int iColBk;
//指向下一节身体
Snake* pNext;
//备份,每次走了一步后备份,先封装,后续使用
void BackUp()
{
iRowBk = iRow;
iColBk = iCol;
}
};
结构体定义好了,接下来就是先画一个蛇头了
//蛇头的初始化
Snake* pSnakeHead = new Snake;
pSnakeHead->iRow = 15;
pSnakeHead->iCol = 15;
//蛇身
Snake* pSnakeBody = new Snake;
//链接蛇头与蛇身
pSnakeHead->pNext = pSnakeBody;
接着就是让他渲染出来了
在之前的渲染函数改进一下
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 40; j++)
{
if (1 == arrMap[i][j])
{
cout << "※";
}
//画蛇
else if (DrawSnake(pSnakeHead, i, j))
{
cout << "◎";
}
else
{
cout << " ";
}
}cout << endl;
}
到这里就画出一条蛇来了
3.让蛇移动
说到移动,就先要想到移动的4个方向,因为用到链表,所以只要控制蛇头移动,其他的自动继承上一节点的坐标就能达到移动的效果了,这里用枚举来定义4个方向。枚举之前也有所说明
//蛇头的方向定义
enum
{
//上,下,左,右
E_SNAKE_UP,
E_SNAKE_DOWN,
E_SNAKE_LEFT,
E_SNAKE_RIGHT
};
接下来就是让蛇根据方向移动,将下面的代码写在一开始写的while(true) 大循环里就可以了,当然这里只是没考虑速度的
//最开始已蛇头为当前节点
Snake* CurNode =pSnakeHead;
//备份
CurNode->BackUp();
//让下一节点继承当前节点的坐标
while (nullptr != CurNode&&nullptr!=CurNode->pNext)
{
CurNode->pNext->BackUp();
CurNode->pNext->iRow = CurNode->iRowBk;
CurNode->pNext->iCol = CurNode->iColBk;
CurNode = CurNode->pNext;
}
//移动头节点,direction为方向,在初始的时候根据自己喜好定义好
switch (direction)
{
case E_SNAKE_UP:
pSnakeHead->iRow -= 1;
break;
case E_SNAKE_DOWN:
pSnakeHead->iRow += 1;
break;
case E_SNAKE_LEFT:
pSnakeHead->iCol -= 1;
break;
case E_SNAKE_RIGHT:
pSnakeHead->iCol += 1;
break;
default:
break;
}
这时候你会发现你的蛇只能快速往你定义的方向一直走,然后消失在屏幕
那么这时候我们需要手动去改变蛇的方向了,键盘监听事件,这是游戏人机交互必须的方法。先加头文件
#include<cstdlib>
//用到的一起写上吧,不懂的自己搜一下
#include "stdafx.h"
#include<Windows.h>
#include<iostream>
#include<cstdlib>
#include <conio.h>
#include<vector>
using namespace std;
// x 为方向,这里封装了一个函数
int SetDirection(int x)
{
char ch;
if (_kbhit())
{
ch = _getch();
switch (ch)
{
case ('w'):
如果按了上,方向变为上
x = E_SNAKE_UP;
break;
case 's':
x = E_SNAKE_DOWN;
break;
case 'a':
x = E_SNAKE_LEFT;
break;
case 'd':
x = E_SNAKE_RIGHT;
break;
case ' ':
system("pause");
break;
default:
break;
}
}
return x;
}
当然,在while(true)循环里也要调用这个函数,以此来实时获取改变的方向
direction = SetDirection(direction);
做到这里就能上下左右的移动了。
4.产生食物
蛇出来了,也能移动了,那就需要产生食物了,这时候就需要函数的重要性了。
敲代码的时候我们经常希望 随便什么时候只要简单地敲一句代码就能实现很复杂的功能。比如我写个 makeFood() 就能随机产生一个食物。但是万事开头难,想要这么简单就需要在一开始的时候就把该做的做了,专业名字 叫 定义。。。
首先要在main函数之前声明,并且产生一个食物,关于函数里面的参数看不懂的可以看看之前的,或者找度娘
void MakeFood(Snake* pSnakeHead);
Snake* g_sFood=new Snake;
然后在main 函数外定义,可以看出来食物并不是被吃了后消失,而是被吃了后改变了位置,但是效果就是消失的,因为这里的设定并不是很复杂,所以这样就够了
void MakeFood(Snake* pSnakeHead)
{
Snake* pCurNode = pSnakeHead;
g_sFood->iRow = rand() % 18 + 1;
g_sFood->iCol = rand() % 38 + 1;
//当食物产生到蛇的身上
while (nullptr != pCurNode)
{
if (g_sFood->iRow == pCurNode->iRow&&g_sFood->iCol == pCurNode->iCol)
{
MakeFood(pSnakeHead);
break;
}
pCurNode = pCurNode->pNext;
}
//无敌版本
/*g_sFood.iRow = g_arrSnake[0].iRow ;
g_sFood.iCol = g_arrSnake[0].iCol;*/
/*for (int m = 0; m <VecSnake.size(); ++m)
{
if (g_sFood->iRow == VecSnake[m]->iRow && g_sFood->iCol == VecSnake[m]->iCol)
{
MakeFood();
break;
}
}*/
}
5.蛇吃食物
接下来就是判断是否吃到食物了,到这一步可能又一筹莫展了。但其实换个思路,如果没一帧我们都去判断蛇头与食物是否在同一位置,在一起就算吃到食物了,吃到食物后就调用一次上面的 makeFood()函数,这样理论上就能完成一个完整的游戏了。
那么继续定义一个函数,要习惯这种方式,因为逻辑性会很高,对大型项目就不容易乱,并且在实际项目中的团队互动性会很好
void IsChangeFood(Snake*& pSnakeHead, Snake*& pSnakeBody);
接着定义了
void IsChangeFood(Snake*& pSnakeHead, Snake*& pSnakeBody)
{
//蛇头的坐标与食物的坐标重叠
if (pSnakeHead->iRow == g_sFood->iRow&&pSnakeHead->iCol == g_sFood->iCol)
{
//蛇的身体数量+1,
Snake* snake = new Snake();
pSnakeBody->pNext = snake;
pSnakeBody = snake;
//产生新的食物
MakeFood(pSnakeHead);
//分数加1
g_iGrade++;
}
}
然后就是在 while(true)里加入这个函数就可以了
6.判断死亡
天下没有不散的宴席,游戏也有结束的时候,但是判断游戏结束是需要自己写的,因为这时候当蛇跑出屏幕外的时候我们会觉得已经结束了,但实际上蛇还是一直在走,只是没显示在屏幕里而已,但是蛇又会在什么时候停止下来呢,当然是你停止调试或者程序崩溃的时候。
那么我们要怎么判断死亡呢。
1.蛇头撞到墙
2.蛇头撞到蛇身
作为一个敲代码的程序员上面的是不需要你去考虑的,你只需要怎么去实现这个功能。
声明函数。。。
//判断蛇是否存活
bool IsLive(Snake*& pSnakeHead);
定义函数
bool IsLive(Snake*& pSnakeHead)
{
//将蛇头传进来,然后去遍历整个蛇身,如果蛇头撞到蛇身就返回false
//这里没写撞墙
Snake* pCurNode = pSnakeHead->pNext;
while (nullptr!=pCurNode)
{
if (pSnakeHead->iRow == pCurNode->iRow&&pSnakeHead->iCol == pCurNode->iCol)
{
return false;
}
pCurNode = pCurNode->pNext;
}
return true;
}
好了,只要在while(true)里调用这个函数就好了
//判断是否结束游戏
if (!IsLive(pSnakeHead))
{
cout << "Game Over";
//这里只是写了让程序暂停,让控制台关闭的函数也是有的,
system("pause");
break;
}
贴上所以代码吧
//LoveEatSnake2.0.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<Windows.h>
#include<iostream>
#include<cstdlib>
#include <conio.h>
#include<vector>
using namespace std;
//定义地图
int arrMap[20][40] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
};
//蛇结构体定义
struct Snake
{
Snake()
{
iRow = 0;
iCol = 0;
pNext = nullptr;
iRowBk = 0;
iColBk = 0;
}
int iRow;
int iCol;
int iRowBk;
int iColBk;
Snake* pNext;
void BackUp()
{
iRowBk = iRow;
iColBk = iCol;
}
};
//蛇头的方向定义
enum
{
//上,下,左,右
E_SNAKE_UP,
E_SNAKE_DOWN,
E_SNAKE_LEFT,
E_SNAKE_RIGHT
};
//贪吃蛇数组
//Snake g_arrSnake[100] = {};
//蛇头
//食物数组
Snake* g_sFood=new Snake;
//蛇身的长度
int g_length=1;
//定义初始速度
int g_iSpeed = 100;
int g_iGrade = 0;
//画蛇
bool DrawSnake(Snake* pSnakeHead,int i,int j);
//渲染所有的
void DrawALL(Snake* pSnakeHead);
//生成食物
void MakeFood(Snake* pSnakeHead);
//改变方向
int SetDirection(int x);
//改变蛇
void ChangeSnake(Snake*& pSnakeHead, Snake*& pSnakeBody,int x);
//判断蛇是否吃到食物
void IsChangeFood(Snake*& pSnakeHead, Snake*& pSnakeBody);
//判断蛇是否存活
bool IsLive(Snake*& pSnakeHead);
int main()
{
//方向的初始化
int iPo = E_SNAKE_UP;
//蛇头的初始化
Snake* pSnakeHead = new Snake;
pSnakeHead->iRow = 15;
pSnakeHead->iCol = 15;
//蛇身
Snake* pSnakeBody = new Snake;
pSnakeHead->pNext = pSnakeBody;
g_sFood->iRow = 16;
g_sFood->iCol = 20;
while (true)
{
system("cls");
//蛇移动
iPo = SetDirection(iPo);
ChangeSnake(pSnakeHead,pSnakeBody, iPo);
//判断是否吃到了食物
IsChangeFood(pSnakeHead,pSnakeBody);
//判断是否结束游戏
if (!IsLive(pSnakeHead))
{
cout << "Game Over";
system("pause");
break;
}
//渲染
DrawALL(pSnakeHead);
//渲染地图
Sleep(g_iSpeed);
}
return 0;
}
bool DrawSnake(Snake* pSnakeHead,int i,int j)
{
bool bSnake = false;
while(nullptr!= pSnakeHead)
{
if (i == pSnakeHead->iRow&&j == pSnakeHead->iCol)
{
bSnake = true;
}
pSnakeHead = pSnakeHead->pNext;
}
return bSnake;
}
void MakeFood(Snake* pSnakeHead)
{
Snake* pCurNode = pSnakeHead;
g_sFood->iRow = rand() % 18 + 1;
g_sFood->iCol = rand() % 38 + 1;
//当食物产生到蛇的身上
while (nullptr != pCurNode)
{
if (g_sFood->iRow == pCurNode->iRow&&g_sFood->iCol == pCurNode->iCol)
{
MakeFood(pSnakeHead);
break;
}
pCurNode = pCurNode->pNext;
}
//无敌版本
/*g_sFood.iRow = g_arrSnake[0].iRow ;
g_sFood.iCol = g_arrSnake[0].iCol;*/
/*for (int m = 0; m <VecSnake.size(); ++m)
{
if (g_sFood->iRow == VecSnake[m]->iRow && g_sFood->iCol == VecSnake[m]->iCol)
{
MakeFood();
break;
}
}*/
}
int SetDirection(int x)
{
char ch;
if (_kbhit())
{
ch = _getch();
switch (ch)
{
case ('w'):
if(E_SNAKE_DOWN==x)
{
x = E_SNAKE_DOWN;
}
else
{
x = E_SNAKE_UP;
}
break;
case 's':
if (E_SNAKE_UP == x)
{
x = E_SNAKE_UP;
}
else
{
x = E_SNAKE_DOWN;
}
break;
case 'a':
if (E_SNAKE_RIGHT == x)
{
x = E_SNAKE_RIGHT;
}
else
{
x = E_SNAKE_LEFT;
}
break;
case 'd':
if (E_SNAKE_LEFT == x)
{
x = E_SNAKE_LEFT;
}
else
{
x = E_SNAKE_RIGHT;
}
break;
case ' ':
system("pause");
break;
default:
break;
}
}
return x;
}
void ChangeSnake(Snake*& pSnakeHead, Snake*& pSnakeBody, int x)
{
Snake* CurNode =pSnakeHead;
CurNode->BackUp();
while (nullptr != CurNode&&nullptr!=CurNode->pNext)
{
CurNode->pNext->BackUp();
CurNode->pNext->iRow = CurNode->iRowBk;
CurNode->pNext->iCol = CurNode->iColBk;
CurNode = CurNode->pNext;
}
switch (x)
{
case E_SNAKE_UP:
pSnakeHead->iRow -= 1;
break;
case E_SNAKE_DOWN:
pSnakeHead->iRow += 1;
break;
case E_SNAKE_LEFT:
pSnakeHead->iCol -= 1;
break;
case E_SNAKE_RIGHT:
pSnakeHead->iCol += 1;
break;
default:
break;
}
if (20 <= pSnakeHead->iRow)
{
pSnakeHead->iRow =1;
}
if (40 <= pSnakeHead->iCol)
{
pSnakeHead->iCol =1;
}
if (0 >= pSnakeHead->iRow)
{
pSnakeHead->iRow = 19;
}
if (0 >= pSnakeHead->iCol)
{
pSnakeHead->iCol = 39;
}
}
void IsChangeFood(Snake*& pSnakeHead, Snake*& pSnakeBody)
{
if (pSnakeHead->iRow == g_sFood->iRow&&pSnakeHead->iCol == g_sFood->iCol)
{
Snake* snake = new Snake();
pSnakeBody->pNext = snake;
pSnakeBody = snake;
MakeFood(pSnakeHead);
g_iGrade++;
}
}
bool IsLive(Snake*& pSnakeHead)
{
Snake* pCurNode = pSnakeHead->pNext;
while (nullptr!=pCurNode)
{
if (pSnakeHead->iRow == pCurNode->iRow&&pSnakeHead->iCol == pCurNode->iCol)
{
return false;
}
pCurNode = pCurNode->pNext;
}
return true;
}
void DrawALL(Snake* pSnakeHead)
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 40; j++)
{
if (1 == arrMap[i][j])
{
cout << "※";
}
else if (DrawSnake(pSnakeHead, i, j))
{
cout << "◎";
}
else if (i == g_sFood->iRow&&j == g_sFood->iCol)
{
cout << "★";
}
else
{
cout << " ";
}
}cout << endl;
}
}
其实同一游戏都是差不多的,当你会这个,只要你多自己想想是能写第二个,第三个。。。第n个的。这里给出几个参考:推箱子、飞机大战。
下篇预告
:C++实现RPG游戏,