本帖最后由 Meteoric 于 2015-6-5 15:22 编辑
写一下思考过程和遇到的一些问题.
需要的基础知识只有数组for,while 之类的控制语句,需要的函数(rand函数,用来随机出食物坐标,_kbhit函数用来检测按下的按键,这几个函数的使用可以百度查询)不需要其他知识(指针,结构体,链表之类的) 按照模块的形式一步步实现。。。而网上也没有类似的教程帖子(至少我当初没找到(-_-),我只找到了现成的代码……),于是乎,我就整理了一下自己的设计思路,写下了这篇东西,如果你是老鸟,有什么说错的地方还希望您具体指出来,毕竟我的是菜鸟1.第一步先画布局,运动的范围 用打印二维数组数组的方式(由于不用指针,这些变量都设置为全局变量)这一步很简单
[C++] 纯文本查看 复制代码 #include <stdio.h>
char x[10][20];
void print()
{
for (int i = 0; i < 10; i++)//用遍历的形式绘制
{
for (int j = 0; j < 20; j++)
{
printf("%c", x[i][j]);
}
printf("\n");
}
}
int main()
{
for (int i = 0; i < 10; i++) //将字符数组全部以'-'填充,进行初始化
{
for (int j = 0; j < 20; j++)
{
x[i][j] = '-';
}
}
print();
}
结果:
2.第二步 当然是先设置蛇身。。。假设初始长度为3个 初始位置在屏幕左上方
思路 :用两个数组记录蛇身的坐标。。(英语渣。。。横纵就用H,Z表示了)一个数组记录横坐标,一个记录纵坐标 也是全局变量 H[10] Z[10] (数组长度表示蛇的最大长度,当然可以改大一点。。。)
初始化时,有三段身子,记录这三个坐标 即H[0]=0 H[1]=0 H[2]=0 Z[0]=0 Z[1]=1 Z[2]=2
即当x[h][z]中的h z分别与H Z 相等时将x[h][z]的值改为蛇身的值 我将它赋值为笑脸ASCII码是 现在代码变为
[C++] 纯文本查看 复制代码 #include <stdio.h>
char x[10][20];
int H[10];
int Z[10];
void print()
{
for (int i = 0; i < 10; i++)//用遍历的形式绘制
{
for (int j = 0; j < 20; j++)
{
printf("%c", x[i][j]);
}
printf("\n");
}
}
int main()
{
for (int i = 0; i < 10; i++) //将字符数组全部以'-'填充,进行初始化
{
for (int j = 0; j < 20; j++)
{
x[i][j] = '-';
}
}
for (int i = 0; i <10; i++)//将储存坐标的数组全部归零
{
Z[i] = 0;
H[i] = 0;
}
for (int i = 0; i <3; i++)//记录前3个蛇身坐标
Z[i + 1] = i;
for (int i = 0; i <=3; i++)//将数组中记录的蛇身坐标全部填充为笑脸,其ASCII码为1;
{
x[H[i]][Z[i]] = 1;
}
print();
}
运行结果
结果:
3.第三步 当然先不考虑食物问题,先让蛇身动起来!。。。用的是不断的清屏来完成的。。。
这里用到了两个函数 system("cls"); 和Sleep 函数(windows.h) 第一个就是清空控制台,第二个是让函数等待一定时间。。。让蛇身移动,原理很简单,蛇身移动一格,即蛇头进行变化,而蛇头后边的数一直等于前边的数就可以了 例如 原先蛇身坐标分别是0,5 0,6 1,,6 其中1,6是蛇头 假设现在向右移动一格 即 蛇头的纵坐标没变,横坐标+1 而其它的顺延 即移动一格后的坐标记录是 0,6 1,6 1,7 意思就是当蛇头移动时,蛇头后的一个就等于蛇头原先的坐标,。。蛇尾就等于倒数第二格蛇身的坐标,以此类推....当然以前的蛇尾要先清除即先变成‘—’ 再次打印是用Sleep函数睡眠 就相当于设置了蛇身运动的速度。。。先while循环试下效果。。。代码如下
[C++] 纯文本查看 复制代码 #include <stdio.h>
#include <stdlib.h>
#include <windows.h>
char x[10][20];
int H[10];
int Z[10];
void print()
{
for (int i = 0; i < 10; i++)//用遍历的形式绘制
{
for (int j = 0; j < 20; j++)
{
printf("%c", x[i][j]);
}
printf("\n");
}
Sleep(500);//休眠0.5秒 相当于蛇0.5秒动一下
system("cls");//清屏函数。。以便将蛇身重新绘制
}
int main()
{
for (int i = 0; i < 10; i++) //将字符数组全部以'-'填充,进行初始化
{
for (int j = 0; j < 20; j++)
{
x[i][j] = '-';
}
}
for (int i = 0; i <10; i++)//将储存坐标的数组全部归零
{
Z[i] = 0;
H[i] = 0;
}
for (int i = 0; i <3; i++)//记录前3个蛇身坐标
Z[i + 1] = i;
for (int i = 0; i <=3; i++)//将数组中记录的蛇身坐标全部填充为笑脸,其ASCII码为1;
{
x[H[i]][Z[i]] = 1;
}
print();
while (1)
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
Z[3]++;
for (int i = 0; i <3; i++)//将数组中记录的蛇身坐标全部填充为笑脸,其ASCII码为1;
{
x[H[i]][Z[i]] = 1;
}
print();
}
system("pause");
return 0;
}
运行结果如下
怎么样 蛇是不是动起来了! (当然,这只是在写过程,代码优化啥的就先没考虑。。。)
4.好的 向右运动的已经实现,那么实际上 上下左右都已经实现了(即实现上就让横坐标-1,下横坐标+1,。。。),那么先优化一下,把上下左右的函数分别写出来,以方便调用
改完后的功能就是让它自己不停的上下左右的转动
[C++] 纯文本查看 复制代码 #include <stdio.h>
#include <stdlib.h>
#include <windows.h>
char x[10][20];
int H[10];
int Z[10];
void print()
{
for (int i = 0; i <3; i++)//将数组中记录的蛇身坐标全部填充为笑脸,其ASCII码为1;
{
x[H[i]][Z[i]] = 1;
}
for (int i = 0; i < 10; i++)//用遍历的形式绘制
{
for (int j = 0; j < 20; j++)
{
printf("%c", x[i][j]);
}
printf("\n");
}
Sleep(500);//休眠0.5秒 相当于蛇0.5秒动一下
system("cls");//清屏函数。。以便将蛇身重新绘制
}
void left()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
Z[3]--;
}
void right()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
Z[3]++;
}
void up()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
H[3]--;
}
void down()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
H[3]++;
}
int main()
{
for (int i = 0; i < 10; i++) //将字符数组全部以'-'填充,进行初始化
{
for (int j = 0; j < 20; j++)
{
x[i][j] = '-';
}
}
for (int i = 0; i <10; i++)//将储存坐标的数组全部归零
{
Z[i] = 0;
H[i] = 0;
}
for (int i = 0; i <3; i++)//记录前3个蛇身坐标
Z[i] = i;
while (1)
{
for (int j = 0; j <6; j++)
{
right();
print();
}
for (int j = 0; j < 6; j++)
{
down();
print();
}
for (int j = 0; j <6; j++)
{
left();
print();
}
for (int j = 0; j < 6; j++)
{
up();
print();
}
}
system("pause");
return 0;
}
结果:
5.下一步就是考虑获取键盘按下的值,以用来调用相应的方向函数了,我用的vs2013,查到可以用的函数是_kbhit() 函数在#include<conio.h> 里,具体函数用法你可以百度一下
我用到的是这样的表达 if (_kbhit()){...表达式...}即没有键盘按下时_kbhit()返回0,即当有键盘按下时就执行表达式的内容, 可以用getch来获取按下的键盘值,来进行判断
我打算用小写的w a s d 来控制上 下 左 右,我们可以先另写一个小程序来实验一下到底是怎样用的:实验代码如下
[C++] 纯文本查看 复制代码 #include <stdio.h>
#include<conio.h>
int main()
{
char ch;
while (1)
{
if (_kbhit())
{
ch=getch();
switch (ch)
{
case 'w':
printf("按下了w键\n");
break;
case 'a':
printf("按下了a键\n");
break;
case 's':
printf("按下了s键\n");
break;
case 'd':
printf("按下了d键\n");
break;
default:
printf("按下了其它键\n");
break;
}
}
}
return 0;
}
运行结果:
6.将_kbhit()函数加入后,代码如下(当然还有不少bug,现在只考虑对蛇运动方向的控制)
[C++] 纯文本查看 复制代码 #include <stdio.h>
#include<conio.h>
#include <stdlib.h>
#include <windows.h>
char x[10][20];
int H[10];
int Z[10];
char ch = 'd';
void print()
{
for (int i = 0; i <3; i++)//将数组中记录的蛇身坐标全部填充为笑脸,其ASCII码为1;
{
x[H[i]][Z[i]] = 1;
}
for (int i = 0; i < 10; i++)//用遍历的形式绘制
{
for (int j = 0; j < 20; j++)
{
printf("%c", x[i][j]);
}
printf("\n");
}
Sleep(500);//休眠0.5秒 相当于蛇0.5秒动一下
system("cls");//清屏函数。。以便将蛇身重新绘制
}
void getkey()
{
if (_kbhit())
{
ch= getch();
}
}
void left()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
Z[3]--;
}
void right()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
Z[3]++;
}
void up()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
H[3]--;
}
void down()
{
x[H[0]][Z[0]] = '-';
for (int i = 0; i <3; i++)//蛇身全部前进一格
{
Z[i] = Z[i + 1];
H[i] = H[i + 1];
}
H[3]++;
}
int main()
{
for (int i = 0; i < 10; i++) //将字符数组全部以'-'填充,进行初始化
{
for (int j = 0; j < 20; j++)
{
x[i][j] = '-';
}
}
for (int i = 0; i <10; i++)//将储存坐标的数组全部归零
{
Z[i] = 0;
H[i] = 0;
}
for (int i = 0; i <3; i++)//记录前3个蛇身坐标
Z[i] = i;
while (1)
{
getkey();
switch (ch)
{
case 'w':
up();
break;
case 'a':
left();
break;
case 's':
down();
break;
case 'd':
right();
break;
default:
;
break;
}
print();
}
system("pause");
return 0;
}
运行结果:
|