学习C/C++一月有余,我在基本了解了它们的核心内容以及部分算法后,开始尝试此前认为有难度的贪吃蛇游戏。不同于我之前写过的迷宫游戏,贪吃蛇在动态画面的要求会更高。解决这个问题花了我不少时间。耗时将近两个小时,我写出了贪吃蛇第一版,并在接下来一天时间内反复修改,得到了比较满意的结果。这次我初步使用了有关类与对象、二维数组的内容,我认为这足够证明我这个月的长足进步。
此后我也对比了我与网上一些贪吃蛇代码的差异,它们通过移动光标进行画面的局部打印这样的方法比我重新绘制画面要先进许多,这也是我需要不断学习的。我会一直改进。
此贴仅用于记录个人进步历程。
#include<iostream>
#include<conio.h>// _getch() _khbit() 所在的头文件
#include<cstdlib>
#include <Windows.h>
#define height 20
#define width 40
using namespace std;
class snake {
public:
int snx[100];
int sny[100];
}snake;
int sekai[height][width];//贪吃蛇的本体数据 地图 蛇本体都通过 sekai 来实现
int slong = 3;//蛇的长度
//int sx = height / 2;
//int sy = width / 2;//蛇头的位置
int fnum = 1;//果实的数量
int m = 1;
int fx = 0, fy = 0;
//int sc=0;//世界变化量
char now = 'a';//方向
int sp = 200;
int score = 0;
int gamedo = 1;
void gamestart()//游戏入场
{
void dead();
cout << "Welcome to MySnake" << endl;
cout << "Input q if you want to quit , or input other keys to start : ";
if (_getch() == 'q') {
dead();
}
else
system("cls");
}
void dead()//游戏结束画面
{
system("cls");
cout << "Game over."<<endl;
Sleep(3000);
exit(0);
}
void outsekai()//绘制地图
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
switch (sekai[i][j])
{
case 1://墙
cout << "#"; break;
case -1://果实
cout << "$"; break;
case 2://蛇身体
cout << "O"; break;
case 3://蛇头
cout << "@"; break;
default://空白部分
cout << " ";
}
}
cout << endl;
}
}
bool rgt(char a)
{
if (a == 'a' || a == 's' || a == 'd' || a == 'w')
{
if (a == 'a' && now == 'd')return 0;
if (a == 'd' && now == 'a')return 0;
if (a == 's' && now == 'w')return 0;
if (a == 'w' && now == 's')return 0;
else return 1;
}
else return 0;
}
void snakenewmove()
{
while (_kbhit())
{
char a;
a = _getch();
if (rgt(a) == true)
now = a;
}
sekai[snake.snx[slong - 1]][snake.sny[slong - 1]] = 0;
for (int k = slong - 1; k > 0; k--)
{
snake.snx[k] = snake.snx[k - 1];
snake.sny[k] = snake.sny[k - 1];
}
switch (now)
{
case 'w':
snake.snx[0]--; break;
case 'a':
snake.sny[0]--; break;
case 'd':
snake.sny[0]++; break;
case 's':
snake.snx[0]++; break;
default:
break;
}
sekai[snake.snx[0]][snake.sny[0]] = 3;//重新定义蛇头
}
void speedup()
{
if (slong <= 8)sp = 240;
else if (slong <= 16)sp = 180;
else sp = 120;
}
void food()//刷新果实
{
if(m==0)
for (int i = 0; i < fnum; i++)
{
fx = rand() % (height - 2) + 1;
fy = rand() % (width - 2) + 1;
sekai[fx][fy] = -1;
m = 1;
}
}
void grow_alive()
{
if (snake.snx[0] == fx && snake.sny[0] == fy)
{
m--; slong++; score += 10;
}
if (snake.snx[0] == 0 || snake.sny[0] == 0||snake.snx[0]==height-1||snake.sny[0]==width-1)
dead();
for (int k = 1; k < slong; k++)
if (snake.snx[0] == snake.snx[k] && snake.sny[0] == snake.sny[k])
dead();
}
int main()
{
//游戏开始界面
gamestart();
//初始化地图
for (int i = 0; i < height; i++)//每列
{
sekai[i][0] = 1;
sekai[i][width-1] = 1;
for (int j = 0; j < width; j++)//每行
{
sekai[0][j] = 1;
sekai[height-1][j] = 1;
}
}
//蛇的初始化
{
snake.snx[0] = height / 2;
snake.sny[0] = width / 2;
for (int i = 0; i <= slong; i++)
sekai[snake.snx[i]][snake.sny[0]] = 3;
}
//outsekai();
for (int i = 0; i < fnum; i++)//果实的初始化
{
fx = rand() % (height-2) + 1;
fy = rand() % (width-2) + 1;
sekai[fx][fy] = -1;
}
for (;gamedo==1;)//游戏操作开始
{
for (int i = 0; i < height; i++)//每列
{
sekai[i][0] = 1;
sekai[i][width - 1] = 1;
for (int j = 0; j < width; j++)//每行
{
sekai[0][j] = 1;
sekai[height - 1][j] = 1;
}
}
snakenewmove();
system("cls");
outsekai();
cout <<"果实坐标: " << fx << " " << fy <<" 蛇头坐标: " << snake.snx[0] << " " << snake.sny[0] <<" score: "<<score<<" speed: "<<300/sp<<" slong: "<<slong;//参数表
speedup();
Sleep(sp);
grow_alive();
food();//刷新果实
system("cls");
}
return 0;
}