看完小甲鱼老师的视频后自己做了一个贪吃蛇(qwq不喜勿喷)
#include <stdio.h>#include <windows.h>
#include <conio.h>
#include <time.h>
#define frame_height 25 //边框上下长
#define frame_width 50 //边框左右宽
#define UP 'w' //宏定义, 将以下出现的up替换成w
#define DOWN 's'//同上
#define WEST 'a'//同上
#define RIGHT 'd' //同上
struct Food // 定义一个结构体 确认食物坐标
{
int x;
int y;
}food;
struct Snake // 定义一个结构体 用数组的方式储存蛇的每一节身体坐标、身体总长度(节点数量)和速度
{
int x;
int y;
int speed;
int length;
}snake;
char ch, tempch;//蛇的方向, 蛇暂时的方向(后面改变蛇的方向会用到)
int i, temp_x, temp_y, temp_x2, temp_y2, score; //i循环用 ,两个暂时的坐标(后面完成蛇的移动会用到), 得分
int main(void)
{
void screen(void);//定义一个函数,用来打印界面
void initial_data(void); //定义一个函数,用来初始化蛇的身体和食物的位置
void update_food(void); //定义一个函数,用来生成一个食物
void move_snake(void); //定义一个函数,用来移动蛇
void get_speed(void); //定义一个函数,用来确定蛇移动的速度
int if_dead(void);//定义一个函数,用来确定游戏是否结束
void end(void);//定义一个函数,用来打印结束画面
void gotoxy(int x, int y); //定义一个函数,用来移动光标到屏幕上对应的位置(屏幕看成一个坐标系,左上角为原点,向下为X轴,向右为Y轴)
while(1)
{
initial_data(); //初始化蛇的身体和食物的位置******这里为我了美观所以先初始化再打印界面(我函数中不完善的地方)*********
screen();//打印界面 ******按照逻辑应该先打印界面的(之后定义的函数也有很多不符合逻辑的地方请体谅新手qwq)******
while(1) //游戏开始
{
update_food(); //生成食物
get_speed(); //获得蛇速度
move_snake(); // 移动蛇
Sleep(snake.speed); //Sleep(100),程序暂停100毫秒。
if(if_dead()) //蛇死亡函数返回1,跳出循环即游戏结束
{
break;
}
}
end();
if(getch()==27) //如果输入ESC退出程序即退出游戏
{
break;
}
else //输入不为ESC键重新开始游戏
{
gotoxy(12, 20); //把光标移动到(12,20)这个点
printf(" ");//这两句清除屏幕中“游戏结束”4个字和“!”一个字符,一个汉字两个字符所以总共打印9个空格覆盖
continue;
}
}
return 0;
}
void screen(void)
{
void gotoxy(int x, int y);
for(i=0 ; i<=24 ; i++) //打印左右边框
{
gotoxy(i, 0);
printf("+");
gotoxy(i, frame_width - 1);
printf("+");
}
for(i=1; i<=48 ; i++) //打印上下边框
{
gotoxy(0, i);
printf("+");
gotoxy(frame_height-1, i);
printf("+");
}
gotoxy(6, 60); //打印右侧的界面
printf("欢迎来到贪吃蛇(简易版)");
gotoxy(9, 60);
printf("当前得分:%d ", score);
gotoxy(12, 60);
printf("操作:'W'上,'S'下,'A'左,'D'右");
gotoxy(15, 60);
printf("按空格键开始(重新开始)");
gotoxy(18, 60);
printf("ESC键退出游戏!");
if(getch() != ' ') //如果输入不是空格键就进入下面那个循环
{
while(1) // 直到输入空格键跳出循环,相当于按空格键开始游戏
{
if(getch() == ' ')
{
break;
}
}
}
}
void initial_data(void)
{
void gotoxy(int x, int y);
void update_food(void);
snake.x = frame_width / 3;
snake.y = frame_height / 3; //蛇的坐标(X,Y)在(25/3, 50/3)处
snake.length = 3; //蛇有3节
ch = RIGHT; //蛇的方向向右;
for(i=1 ; i<=snake.length ; i++)//从第二节蛇身开始每一节的Y坐标都比蛇头少1,循环输入除了蛇头其余身体节点的坐标
{ //这里循环了3次,按道理身体长度为3时除了蛇头应该只要循环两次
snake.x = snake.x; //所以除了蛇目前身体的坐标确定以外,未来吃到食物的一节身体的坐标也是确定的(目前这节身体还不在)。
snake.y = snake.y - 1;//目前确定的点有snake,snake,snake,snake,除了snake以外蛇的身体是确实存在的
gotoxy(snake.x, snake.y);//所以打印了除了snake的节点 (为了方便就简写成snake的形式了,其实是snake.x, snake.y,以后出现同理)
printf("*");//我用的“*”来表示蛇的身体,也可以用其他的字符表示
}
food.x = snake.x;
food.y = snake.y; //暂定食物在蛇头位置(这里只是为了初始化食物的数据以方便后面调用update_food函数)
score = 0;
update_food();
}
void update_food(void)
{
void gotoxy(int x, int y);
if(snake.x == food.x && snake.y == food.y)
{
while(1)
{
srand(time(NULL)); //srand(),time(),rand()详细说明自行百度,这里的作用就是得到一个随机数
food.x = rand()%23 + 1; //(rand()%23+1实际上是rand()%(24-1)+1,得到一个范围再[1,24)的随机数)
food.y = rand()%48 + 1;
for(i=0 ; i<=snake.length - 1 ; i++)//如果食物的随机位置在蛇身位置重新随机一个食物位置
{
if(food.x==snake.x && food.y==snake.y)
{
break;
}
if(i == snake.length - 1)
{
i = snake.length;
}
}
if(i == snake.length + 1)//直到食物位置不在蛇身位置退出循环
{
break;
}
}
gotoxy(food.x, food.y);//光标移动到食物的位置
printf("o"); //我用的“o”表示食物,也可以用其他字符表示
}
}
void get_speed(void)
{
if(snake.length < 5)
{
snake.speed = 300;
}
else if(snake.length < 10)
{
snake.speed = 250;
}
else if(snake.length < 15)
{
snake.speed = 200;
}
else if(snake.length < 20)
{
snake.speed = 150;
}
else
{
snake.speed = 100;
}
}
void move_snake(void)
{
void gotoxy(int x, int y);
temp_x = snake.x;
temp_y = snake.y;//暂时把蛇头snake的坐标保存再temp中
if(kbhit())//kbhit()详细说明自行百度,这里作用是如果键盘输入了字符就判断为真
{
tempch = getch();//读入键盘输入的字符
if(tempch == 'w' || tempch == 's' || tempch == 'a' || tempch == 'd')
{
ch = tempch;
}
}
switch(ch)//只移动蛇头,并不是移动整个蛇身
{
case 'w' : snake.x = snake.x - 1;break;
case 's' : snake.x = snake.x + 1;break;
case 'a' : snake.y = snake.y - 1;break;
case 'd' : snake.y = snake.y + 1;break;
}
if(food.x == snake.x && food.y == snake.y)//如果吃到食物,蛇身+1,分数+1
{
snake.length = snake.length +1;
score++;
gotoxy(9, 69);
printf("%d", score);
}
for(i=snake.length ; i>=2 ; i--)//从未来吃到食物的一节蛇的身体开始,把前一节的身体坐标赋给当前这节,以达到蛇的移动
{ //第二节身体还保持原样, 因为蛇头的位置变动了
snake.x = snake.x;
snake.y = snake.y;
}
snake.x = temp_x;
snake.y = temp_y;//把蛇头移动前的坐标赋给第二节身体
gotoxy(snake.x, snake.y);
printf("*");//打印蛇头
gotoxy(snake.x, snake.y);
printf(" ");//清除“*”未来吃到食物的一节蛇的身体(即移动前,蛇的最后一节身体),不懂的话可以单步调试(我语文学的不太好。。。)
}
int if_dead(void)
{
for(i=1 ; i<=snake.length-1 ; i++)//蛇头的坐标与蛇身体任意一节的坐标相同的话判断死亡
{
if((snake.x == snake.x && snake.y == snake.y))
{
return 1;
}
}
if((snake.x == 0 || snake.x == 24) || (snake.y == 0 || snake.y == 49))
{ //蛇头的坐标与边界的坐标一样的话判断死亡
return 1;
}
return 0;
}
void end(void)
{
void gotoxy(int x, int y);
gotoxy(snake.x, snake.y);
printf("+");
gotoxy(food.x, food.y);
printf(" ");
for(i=1 ; i<=snake.length-1 ; i++)
{
gotoxy(snake.x, snake.y);
printf(" ");
}//清除蛇和食物
gotoxy(12, 20);
printf("游戏结束!");
}
void gotoxy(int x, int y) //这个函数作用是把屏幕坐标化,详细说明请自行百度
{
HANDLE hout;
COORD cor;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
cor.X=y;
cor.Y=x;
SetConsoleCursorPosition(hout,cor);
}
亲~,这么多行代码,请问您这是什么语言? 13572044595 发表于 2018-5-4 22:15
亲~,这么多行代码,请问您这是什么语言?
C语言啊0- 0 可以的,加油,我得向楼主看起,其实这个程序感觉就是C语言的面向对象编程了{:10_275:} 溯影 发表于 2018-5-4 23:25
可以的,加油,我得向楼主看起,其实这个程序感觉就是C语言的面向对象编程了
谢谢{:5_91:} 真厉害!我已经从入门到放弃了。看来还得加油学习啊 弄过去全是繁体中文 不过我还是凭借我的聪明机智猜到怎么玩了,厉害了我的哥
厉害 魔法虫虫 发表于 2018-5-8 17:59
不过我还是凭借我的聪明机智猜到怎么玩了,厉害了我的哥
谢谢夸哦{:5_91:} 鱼头骨 发表于 2018-5-7 22:07
真厉害!我已经从入门到放弃了。看来还得加油学习啊
嗯嗯,一起加油{:5_108:} 楼主学了多久啊 楼主学习了多久啊。。
页:
[1]