C语言贪吃蛇游戏

一、问题描述和解决思路

问题描述:贪吃蛇游戏,玩家用w、s、a、d分别代表上、下、左、右,以此来控制贪吃蛇的运动方向。当贪吃蛇吃到食物时身体会增加一段,同时也会使分数加一。如果贪吃蛇撞到它的身体或是游戏边框时,屏幕便会冻结,游戏便会失败。 

解决思路: 首先,要初始化游戏,将边框和贪吃蛇画出来,并且随机产生一个食物(利用rand来产生两个随机数,并将其放到二维数组中,使其可以在画布中随机产生食物)。然后,让贪吃蛇的蛇头和身体一开始被赋的值都加一,同时将旧的蛇头蛇身的坐标记录下来,让旧的蛇头变为新的蛇身。再根据玩家输入的字符来判断方向,同时以旧的蛇头和蛇身的坐标为依据来为新的蛇头赋新的值。接下来判断新的蛇头所在位置之前是否有食物(利用if语句进行判断,让新的蛇头的所在的位置的二维数组的值和食物的值进行比较),如果有食物(两个值相同),就使分数加一,同时再随机产生一个新的食物,旧的食物消失。如果没有食物,就依据之前记录的旧的蛇尾的坐标来使蛇尾去掉一段。同时也要判断蛇头是否撞向边框或者撞向自己(利用一个if语句来判断新的蛇头的值是否等于边框的值或者是蛇身的值),如果撞到了,就使屏幕冻结,否则游戏继续。

二、功能模块划分

功能划分:

流程图:

三、遇到问题和解决措施

问题:游戏的边框不是一个矩形,边框只有三边。

解决方法:查看二维数组对边框的赋值,发现最右侧的边框没有赋值。

问题:贪吃蛇的食物随机产生的次数是有限的,无法一直产生食物。

解决方法:查看食物产生随机数的函数,发现食物的x y赋值反啦。

四、源程序

//贪吃蛇游戏

#include<stdio.h>             

#include<stdlib.h>      //可以产生随机数                           

#include<conio.h>      //控制光标的移动

#include<windows.h>   //用来冻结屏幕和延迟时间

#define HIGH 20      //画布尺寸  宽

#define WIDTH 30    //  长



int drection,count;   //全局变量(方向和分数)

int food_x,food_y;   //全局变量(产生食物的随机数)

int canvas[WIDTH][HIGH]={0}; //刚开始都初始化为零,全是空白



void gotoxy(int x,int y)  //用于控制屏幕上的光标的移动     //需要conio.h函数的使用

{

HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); //调用

COORD pos; //定义一个坐标

pos.X=x;

pos.Y=y;

SetConsoleCursorPosition(handle,pos);

}

void start()              //画出边框和蛇头及蛇身

{

int i,j      //0代表空格 1代表蛇头 大于1代表蛇身 -1代表边框 -2代表食物    

for(i=0;i<WIDTH;i++)        //画出边框              

{

canvas[i][0]=-1;   

canvas[i][HIGH-1]=-1;   

}       

for(j=0;j<HIGH;j++)

{

canvas[0][j]=-1;

canvas[WIDTH-1][j]=-1;      //画出边框

}

canvas[WIDTH/2][HIGH/2]=1;    //画出蛇头

for(i=1;i<5;i++)

{

canvas[WIDTH/2-i][HIGH/2]=1+i;    //画出蛇身

}

drection=4;       //让小蛇刚开始朝右移动

food_x=rand()%(27)+2;

food_y=rand()%(17)+2;

canvas[food_x][food_y]=-2;   //随机在边框内产生食物

}



void drect()    //让贪吃蛇按照既定的方向前进一步,同时判断贪吃蛇是否吃到了食物,玩家可以改变贪吃蛇前进的方向

{

int i,j,k;

for(i=1;i<HIGH-1;i++)       //使贪吃蛇朝着原来的方向运动

{

for(j=1;j<WIDTH-1;j++)

{

if(canvas[j][i]>0)     //让贪吃蛇的蛇头和蛇身的数值都增加一,使原来的蛇头变成蛇身

{

canvas[j][i]++;     

}

}

}

int oldend_i,oldend_j,oldhead_i,oldhead_j,newhead_i,newhead_j;   //旧的蛇头和蛇尾的坐标以及新的蛇头的坐标

int max=0;

for(i=1;i<HIGH-1;i++)

{

for(j=1;j<WIDTH-1;j++)

{

if(canvas[j][i]>0)

{

if(max<canvas[j][i])      //记录下蛇尾的坐标

{

max=canvas[j][i];     //引用 max的原因是尾巴会改变,不能使用canvas[i][j]==6

oldend_i=i;

oldend_j=j;

}

if(canvas[j][i]==2)

{

oldhead_i=i;

oldhead_j=j;     //将旧的蛇头的坐标记录下来,便于对新的蛇头进行赋值

}

}

}

}

if(drection==1)           //根据方向,对新的蛇头进行赋值

{

newhead_i=oldhead_i-1;

newhead_j=oldhead_j;       //向上移一个单位

}

if(drection==2)

{

newhead_i=oldhead_i+1;

newhead_j=oldhead_j;      //向下移一个单位

}

if(drection==3)

{

newhead_i=oldhead_i;

newhead_j=oldhead_j-1;    //向左移一个单位

}

if(drection==4)

{

newhead_i=oldhead_i;

newhead_j=oldhead_j+1;     //向右移一个单位

}

    if(canvas[newhead_j][newhead_i]==-2) //贪吃蛇吃到食物时

{

count++;

canvas[food_x][food_y]=0;          //旧的食物消失

    food_x=(rand()%(27))+2;

food_y=(rand()%(17))+2;

printf(" 得分为:%d\n",count);     //记录分数                                       

canvas[food_x][food_y]=-2  //随机在边框内产生新的食物

}

else

{

canvas[oldend_j][oldend_i]=0; //贪吃蛇没吃到食物时,将旧的蛇尾去掉

}

if((canvas[newhead_j][newhead_i]==-1)||(canvas[newhead_j][newhead_i]>0))    //贪吃蛇撞墙或者是撞向自己时

{

printf("游戏结束!\n");

system("pause");    //屏幕冻结 (需要使用windows.h)

exit(0);

}

else

{

canvas[newhead_j][newhead_i]=1;   //为新的蛇头赋值

}

}

void show()         //根据start函数来使画面展示在屏幕上

{

gotoxy(0,0);     //调用光标函数

int i,j;

for(i=0;i<HIGH;i++)

{

for(j=0;j<WIDTH;j++)

{

if(canvas[j][i]==-1)

{

printf("#");      //边框

}

else if(canvas[j][i]==1)

{

printf("@");       //蛇头

}

else if(canvas[j][i]==0)

{

printf(" ");       //空白部分

}

else if(canvas[j][i]>1)    

{

printf("*");       //蛇身

}

else if(canvas[j][i]==-2)

{

printf("F");       //食物

}

}

printf("\n");       //使边框更好的展示出来

}

Sleep(100);           //延迟时间为100秒 (要用到头文件 windows.h同时S要大写)

}

void input()         //用来控制贪吃蛇运动的方向

{

char ch;

if(kbhit()        //判断是否有从键盘输入的内容 (需要使用  conio.h头文件)

{

ch=getch();       //得到输入的内容,但不显示在屏幕上

if(ch=='w')       //分别用w,s,a,d来表示上,下,左,右

{

drection=1;      //上

drect();

}

if(ch=='s')        //下

{

drection=2;

drect();

}

if(ch=='a')      //左

{

drection=3;

drect();

}

if(ch=='d')       //右

{

drection=4;

drect();

}

}

}

int main()

{

char ch;

system("color F5");  //背景和字体颜色(F为白色背景,5为紫色字体)

printf("\n");

printf(" 欢迎开始贪吃蛇游戏\n");

printf("\n");

printf( " 请按p进入游戏界面\n");

scanf("%c",&ch);

if(ch=='p')

{

start();    //画面函数的调用

while(1)

{

show();       //将画面展示在屏幕上

drect();     //主要操作

input();   //根据键盘的输入来调节方向

}

}

return 0;

}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RuIYInG287

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值