关于数组贪吃蛇移动思路,由于蛇身是数组,因此用数组的下标能够很好 的移动到需要操作的位置,每次移动的时候让蛇尾先移动,之后读取下一位 置的坐标再移动,直到数组[1]的位置,(为什么不到[0]因为[0]是蛇头的 位置,我们需要用它来移动位置)之后让[0]自加,(蛇就会移动了) 关于制造食物的思路,需要特别考虑的一点,不要把食物生成到蛇身的坐标 里面,因此,每当产生了新的食物的坐标,我们都要循环一偏蛇身,检测是 否与神身的坐标相同的,如果有则重新产生新的坐标,如果没有则结束循环 关于方向键的思路,先定义两个变量CH1,CH2。其中CH1用爱接受用户的按键 信息,CH2用来作为主函数的实参(它是传给方向函数,操作小蛇的方向) 首先给CH2赋一个向右移动的值,之后我们判断如果CH2向右边移动,那么输入 CH1的值若是向左边就不执行CH2=CH1。
编译器:VC6
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
int v=200; //小蛇的移动速度
int foodx; //食物的坐标
int foody;
int snakeleng=2; //蛇身的长度(注意数组坐标从0开始)
int count=0; //计算分数
struct body
{
int x;
int y;
};
struct body snake_body[500]; //蛇身的长度
void gotoxy(int x,int y)
{
HANDLE app; //定义句柄
COORD pos; //定义坐标
pos.X=x; //修改X坐标,使X移动
pos.Y=y; //修改Y坐标,使Y移动
app=GetStdHandle(STD_OUTPUT_HANDLE); //获取句柄
SetConsoleCursorPosition(app,pos); //将获取的句柄移动,坐标是POS
}
void initsnake() //初始化小蛇
{
int i,temp=7;
for(i=0;i<3;i++,temp-=2)
{
snake_body[i].x=temp;
snake_body[i].y=10;
gotoxy(temp,10);
printf("■");
}
}
void direct(char ch) //小蛇移动方向函数
{
if(ch=='s'||ch=='S')//支持大小写按键
snake_body[0].y=snake_body[0].y+1;
if(ch=='w'||ch=='W')
snake_body[0].y=snake_body[0].y-1;
if(ch=='a'||ch=='A')
snake_body[0].x=snake_body[0].x-2;
if(ch=='d'||ch=='D')
snake_body[0].x=snake_body[0].x+2;
}
void make_food() //制造食物(有问题,怎么避免把食物生成在蛇身里?)
{
int i,flag=1; //此处是flag用于记录蛇身坐标与食物坐标是否相等
srand((unsigned)time(NULL));
while(flag)
{
foodx=rand()%53+2;
if(foodx%2==0) //将食物的X轴坐标变为奇数
foodx++;
foody=rand()%22+2;
for(i=snakeleng;i>=0;i--) //遍历蛇身
{ //如果产生的食物坐标与蛇身的任意位置相等
if(snake_body[i].x==foodx && snake_body[i].y==foody)
{
flag=1; //坐标相等则再重新产生新的坐标
break; //跳出循环
}
else
flag=0;
}
}
gotoxy(foodx,foody); //画出食物
printf("●");
}
void drawmap() //地图函数
{
int i;
for(i=1;i<=30;i++)
printf("□");
printf("\n");
for(i=1;i<=23;i++)
{
printf("□\t\t\t\t\t\t\t □");
printf("\n");
}
for(i=1;i<=30;i++)
printf("□");
gotoxy(66,4);
printf("贪吃蛇内测");
gotoxy(65,5);
printf("软件开发二班");
gotoxy(64,7);
printf("======");
gotoxy(64,8);
printf("‖玩家得分‖");
gotoxy(64,9);
printf("‖\t ‖");
gotoxy(64,10);
printf("======");
gotoxy(64,13);
printf("======");
gotoxy(64,14);
printf("‖游戏说明 ‖");
gotoxy(64,15);
printf("‖w向上移动‖");
gotoxy(64,16);
printf("‖s向下移动‖");
gotoxy(64,17);
printf("‖a向左移动‖");
gotoxy(64,18);
printf("‖d向右移动‖");
gotoxy(64,19);
printf("======");
}
int add_snake_body() //增加蛇身的函数
{
if(snake_body[0].x==foodx && snake_body[0].y==foody) //如果食物坐标和蛇头坐标相等,说明蛇已经吃到食物了
{
gotoxy(foodx,foody); //擦去蛇的食物
printf("■");
snakeleng++; //增加蛇的长度
count++; //每吃一个食物增加一分
v--;
gotoxy(66,9); //打印得分
printf("%5d",count);
snake_body[snakeleng].x=snake_body[snakeleng-1].x; //增加新的身体,读取下个位置的坐标
snake_body[snakeleng].y=snake_body[snakeleng-1].y;
return 1; //记录蛇已经吃了食物
}
else
return 0;
}
void read_next_coord() //下一位置坐标函数
{
int i;
for(i=snakeleng;i>0;i--) //循环读取下一个位置的坐标
{
if(i==snakeleng) //如果i等于蛇尾(snakeleng最先初始化为2,那么2是蛇尾)
{
gotoxy(snake_body[i].x,snake_body[i].y); //擦除蛇尾
printf(" ");
}
snake_body[i].x=snake_body[i-1].x;
snake_body[i].y=snake_body[i-1].y;
}
}
void snake_death() //判断蛇死亡的函数
{
int i;
if( (snake_body[0].x<2 || snake_body[0].x>55) || (snake_body[0].y<1 || snake_body[0].y>23)) //检测左右两边是否碰墙,检测上下两边是否碰墙
{
printf("撞墙了!游戏结束!");
exit(0);
}
for(i=snakeleng;i>=4;i--) //能否避免遍历所有数组?
{
if(snake_body[0].x==snake_body[i].x && snake_body[0].y==snake_body[i].y)
{
printf("咬到身体了!");
exit(0);
}
}
}
int main(void)
{
int flag=1; //标记食物是否被吃
char ch2='d',ch1='a';
system("color b"); //改变颜色
drawmap(); //初始化地图
initsnake(); //初始化蛇身
while(1)
{
if(flag)
{
make_food();
flag=0;
}
read_next_coord(); //蛇身读取下一个位置的坐标
if(kbhit()) //接受键盘输入的方向
ch1=getch();
if(ch1!='a' && ch1!='s' && ch1!='w' && ch1!='d')//此语句是为了避免用户按下非a,s,w,d键
ch1=ch2; //将上次移动的方向键赋值(如果错误按下,然默认为按原来方向移动)
if((ch2=='d' && ch1!='a')||(ch2=='w' && ch1!='s')||(ch2=='s' && ch1!='w')||(ch2=='a' && ch1!='d'))
{
ch2=ch1; //此语句要来判断小蛇不往相反方向移动
}
direct(ch2); //调用方向函数
gotoxy(snake_body[0].x,snake_body[0].y); //画出新的蛇头
printf("■");
Sleep(v); //控制蛇的速度
flag=add_snake_body(); //判断蛇是否吃了食物
snake_death(); //判断蛇是否死亡
}
return 0;
}
|