c语言 贪吃蛇 程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言 贪吃蛇 程序相关的知识,希望对你有一定的参考价值。
主要内容:
设计并实现一个类似于手机游戏“贪吃蛇”的程序。一条蛇在密闭的围墙内运动,通过键盘上的四个箭头键控制蛇向上下左右四个方向移动。在围墙内随机出现一个食物,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时加分,接着又出现食物,等待被蛇吃掉。如果蛇在移动过程中,撞到墙壁、身体交叉或蛇头撞到自己的身体则游戏结束。
基本要求:
课程设计中要求掌握和实现如下功能和方法:
1、掌握基本绘图原理和图形函数的使用方法;
2、掌握游戏中基本的动画实现方法;
3、掌握键盘响应的主要函数和方法;
4、了解游戏中碰撞检测的方法;
5、实现游戏加速功能,包括加速键功能和逐步加速功能;
扩展要求:
1、 实现随机出现障碍物功能;
2、 实现迷宫式围墙;
3、 实现过关式的游戏方式;
文档要求:
系统完成后,要提交格式规范的文档,包含如下内容:
1、 程序的功能;
2、 游戏界面设计和图形函数的使用;
3、 整体设计思路;
4、 程序中的数据结构;
5、 程序中碰撞检测的实现方法;
6、 程序核心算法的流程图;
7、 程序改进的设想;
8、 总结。
1、 程序的功能
设计并实现一个类似于手机游戏“贪吃蛇”的程序。一条蛇在密闭的围墙内运动,通过键盘上的四个箭头键控制蛇向上下左右四个方向移动。在围墙内随机出现一个食物,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时加分,接着又出现食物,等待被蛇吃掉。如果蛇在移动过程中,撞到墙壁或蛇头撞到自己的身体则游戏结束。
2、 游戏界面设计和图形函数的使用
/* 参考指导书中1.3.1和画界面函数部分 */
3、 整体设计思路
/* 参考指导书中1.3.2部分 */
4、 程序中的数据结构
/* 参考指导书中1.3.2部分 */
5、 程序中碰撞检测的实现方法
/* 参考指导书中游戏具体过程函数部分 */
6、 程序核心算法的流程图
/* 参考别人的 囧 */
7、 程序改进的设想
/* 自己瞎琢磨吧! */
8、 总结
通过本次课程设计,强化了我对C语言相关知识的掌握,学会了基本的游戏编程方法,加深了我复杂程序设计的能力,初步掌握了高级语言程序调试技能 ......(此处删节三百字,你就随便编吧!)
基本思路:
蛇每吃一个食物蛇身子就增加一格,用UP, DOWN, LEFT, RIGHT控制蛇头的运动,而蛇身子跟着蛇头走,每后一格蛇身子下一步走到上一格蛇身子的位置,以此类推。
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define BEG_X 2
#define BEG_Y 1
#define WID 20
#define HEI 20
HANDLE hout;
typedef enum UP, DOWN, LEFT, RIGHT DIR;
typedef struct Snake_body
COORD pos;//蛇身的位置
struct Snake_body *next;//下一个蛇身
struct Snake_body *prev;//前一个蛇身
SNAKE, *PSNAKE;
PSNAKE head = NULL;//蛇头
PSNAKE tail = NULL;//蛇尾
//画游戏边框的函数
void DrawBorder()
int i, j;
COORD pos = BEG_X, BEG_Y;
for(i = 0; i < HEI; ++i)
SetConsoleCursorPosition(hout, pos);
for(j = 0; j < WID; ++j)
if(i == 0)//第一行
if(j == 0)
printf("┏");
else if(j == WID - 1)
printf("┓");
else
printf("━");
else if(i == HEI - 1)//最后一行
if(j == 0)
printf("┗");
else if(j == WID - 1)
printf("┛");
else
printf("━");
else if(j == 0 || j == WID - 1)//第一列或最后一列
printf("┃");
else
printf(" ");
++pos.Y;
//添加蛇身的函数
void AddBody(COORD pos)
PSNAKE pnew = (PSNAKE)calloc(1, sizeof(SNAKE));
pnew->pos = pos;
if(!head)
head = tail = pnew;
else
pnew->next = head;//新创建蛇身的next指向原先的蛇头
head->prev = pnew;//原先的蛇头的prev指向新创建的蛇身
head = pnew;//把新创建的蛇身作为新的蛇头
SetConsoleCursorPosition(hout, head->pos);
printf("◎");
//蛇身移动的函数
void MoveBody(DIR dir)
PSNAKE ptmp;
COORD pos = head->pos;
switch(dir)
case UP:
if(head->pos.Y > BEG_Y + 1)
--pos.Y;
else
return;
break;
case DOWN:
if(head->pos.Y < BEG_Y + HEI - 2)
++pos.Y;
else
return;
break;
case LEFT:
if(head->pos.X > BEG_X + 2)
pos.X -= 2;
else
return;
break;
case RIGHT:
if(head->pos.X < BEG_X + (WID - 2) * 2)
pos.X += 2;
else
return;
break;
AddBody(pos);//添加了一个新的蛇头
ptmp = tail;//保存当前的蛇尾
tail = tail->prev;
if(tail)
tail->next = NULL;
SetConsoleCursorPosition(hout, ptmp->pos);
printf(" ");
free(ptmp);
int main()
int ctrl;
DIR dir = RIGHT;//初始蛇的方向是向右的
COORD pos = BEG_X + 2, BEG_Y + HEI / 2;
system("color 0E");
system("mode con cols=90 lines=30");
hout = GetStdHandle(STD_OUTPUT_HANDLE);
printf(" ------------贪吃蛇的移动------------");
DrawBorder();
//自定义几个蛇的身体
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
pos.X += 2;
AddBody(pos);
//控制蛇的移动
while(ctrl = getch())
switch(ctrl)
case 'w':
if(dir == DOWN)
continue;
dir = UP;
break;
case 's':
if(dir == UP)
continue;
dir = DOWN;
break;
case 'a':
if(dir == RIGHT)
continue;
dir = LEFT;
break;
case 'd':
if(dir == LEFT)
continue;
dir = RIGHT;
break;
case 'q':
return 0;
MoveBody(dir);
return 0;
扩展资料:
实现逻辑
1,可以设置光标,就能实现制定位置打印制定符号。
2,涉及一个结构体,包含两个元素坐标元素和一个结构体指针。
3,结构体串联形成链表,遍历获取成员坐标,打印符号得到蛇身。
4,不断的加头,去尾,重新遍历坐标,再打印形成蛇的移动。
5,食物产生的位置判定,不能越界,也不能与蛇身体重合。
6,蛇的转向判定,一条规则,不允许倒退。
7,转向的实现,跟行进方向决定新的关节坐标(当前头的上下左右)
8,死亡检测,是否头节点坐标是否与墙壁重合,是否与身体其他关节重合。
9,加速减速,设置刷新休眠时间实现。
参考资料来源:百度百科-C语言
参考技术A代码示例如下:
使用了4个自定义函数来实现
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#define High 20 // 游戏画面尺寸
#define Width 30
// 全局变量
int moveDirection; // 小蛇移动位置,上下左右分别用1,2,3,4表示
int food_x,food_y; // 食物的位置
int canvas[High][Width] = 0; // 二维数组存储游戏画布中对应的元素
// 0为空格0,-1为边框#,-2为食物F,1为蛇头@,大于1的正数为蛇身*
void gotoxy(int x,int y) //光标移动到(x,y)位置
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle,pos);
// 移动小蛇
// 第一步扫描数组canvas所有元素,找到正数元素都+1
// 找到最大元素(即蛇尾巴),把其变为0
// 找到=2的元素(即蛇头),再根据输出的上下左右方向,把对应的另一个像素值设为1(新蛇头)
void moveSnakeByDirection()
int i,j;
for (i=1;i<High-1;i++)
for (j=1;j<Width-1;j++)
if (canvas[i][j]>0)
canvas[i][j]++;
int oldTail_i,oldTail_j,oldHead_i,oldHead_j;
int max = 0;
for (i=1;i<High-1;i++)
for (j=1;j<Width-1;j++)
if (canvas[i][j]>0)
if (max<canvas[i][j])
max = canvas[i][j];
oldTail_i = i;
oldTail_j = j;
if (canvas[i][j]==2)
oldHead_i = i;
oldHead_j = j;
int newHead_i,newHead_j;
if (moveDirection==1) // 向上移动
newHead_i = oldHead_i-1;
newHead_j = oldHead_j;
if (moveDirection==2) // 向下移动
newHead_i = oldHead_i+1;
newHead_j = oldHead_j;
if (moveDirection==3) // 向左移动
newHead_i = oldHead_i;
newHead_j = oldHead_j-1;
if (moveDirection==4) // 向右移动
newHead_i = oldHead_i;
newHead_j = oldHead_j+1;
// 新蛇头如果吃到食物
if (canvas[newHead_i][newHead_j]==-2)
canvas[food_x][food_y] = 0;
// 产生一个新的食物
food_x = rand()%(High-5) + 2;
food_y = rand()%(Width-5) + 2;
canvas[food_x][food_y] = -2;
// 原来的旧蛇尾留着,长度自动+1
else // 否则,原来的旧蛇尾减掉,保持长度不变
canvas[oldTail_i][oldTail_j] = 0;
// 是否小蛇和自身撞,或者和边框撞,游戏失败
if (canvas[newHead_i][newHead_j]>0 || canvas[newHead_i][newHead_j]==-1)
printf("游戏失败!\\n");
Sleep(2000);
system("pause");
exit(0);
else
canvas[newHead_i][newHead_j] = 1;
void startup() // 数据初始化
int i,j;
// 初始化边框
for (i=0;i<High;i++)
canvas[i][0] = -1;
canvas[i][Width-1] = -1;
for (j=0;j<Width;j++)
canvas[0][j] = -1;
canvas[High-1][j] = -1;
// 初始化蛇头位置
canvas[High/2][Width/2] = 1;
// 初始化蛇身,画布中元素值分别为2,3,4,5....
for (i=1;i<=4;i++)
canvas[High/2][Width/2-i] = i+1;
// 初始小蛇向右移动
moveDirection = 4;
food_x = rand()%(High-5) + 2;
food_y = rand()%(Width-5) + 2;
canvas[food_x][food_y] = -2;
void show() // 显示画面
gotoxy(0,0); // 光标移动到原点位置,以下重画清屏
int i,j;
for (i=0;i<High;i++)
for (j=0;j<Width;j++)
if (canvas[i][j]==0)
printf(" "); // 输出空格
else if (canvas[i][j]==-1)
printf("#"); // 输出边框#
else if (canvas[i][j]==1)
printf("@"); // 输出蛇头@
else if (canvas[i][j]>1)
printf("*"); // 输出蛇身*
else if (canvas[i][j]==-2)
printf("F"); // 输出食物F
printf("\\n");
Sleep(100);
void updateWithoutInput() // 与用户输入无关的更新
moveSnakeByDirection();
void updateWithInput() // 与用户输入有关的更新
char input;
if(kbhit()) // 判断是否有输入
input = getch(); // 根据用户的不同输入来移动,不必输入回车
if (input == 'a')
moveDirection = 3; // 位置左移
moveSnakeByDirection();
else if (input == 'd')
moveDirection = 4; // 位置右移
moveSnakeByDirection();
else if (input == 'w')
moveDirection = 1; // 位置上移
moveSnakeByDirection();
else if (input == 's')
moveDirection = 2; // 位置下移
moveSnakeByDirection();
int main()
startup(); // 数据初始化
while (1) // 游戏循环执行
show(); // 显示画面
updateWithoutInput(); // 与用户输入无关的更新
updateWithInput(); // 与用户输入有关的更新
return 0;
拓展资料
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。
其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
参考技术B 回答早上好,亲,很高兴为您解答
e #include #include #include #include /*大一上的时候C语言入门学的一个小游戏。还是挺有意思的,有兴趣的同学可以继续优化下:比如蛇头碰到蛇身就判定为输 /给蛇身加点颜色等。*///1.2食物结构体#define MAPHEIGHT 25#define MAPWIDTH 60#define SNAKESIZE 50 //蛇的最大节数struct FOOD\\x09int x;\\x09int y;food;#define SNAKESIZE 50 //蛇的最大节数struct //每一节蛇的坐标\\x09int x[SNAKESIZE];\\x09int y[SNAKESIZE];\\x09int len; //蛇长\\x09int speed; //snake;///全局变量int key=\'w\';//初始化移动方向int changFlag = 0;//蛇变化标记//模块化设计////1.画地图void gotoxy(int x,int y); //实现的函数声明void drawMap();void createFood();int snakeStatus();void drawMap() srand((unsigned)time(NULL)); //随机函数种子 //1.圈地 //1.1 左右边框 for(int i=0;i<=MAPHEIGHT;i++) gotoxy(0,i); printf("■"); gotoxy(MAPWIDTH,i); printf("■"); for(int i=0;i<=MAPWIDTH;i+=2) //上下 ■占用两个字符 gotoxy(i,0); printf("■"); gotoxy(i,MAPHEIGHT); printf("■"); //2.画蛇 ■ //2.1确定蛇的属性 snake.len=3; s
参考技术C /* 贪吃蛇程序 by champking */#define N 200
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score = 0;/*得分*/
int gamespeed = 100000;/*游戏速度自己调整*/
struct Food
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
food;/*食物的结构体*/
struct Snake
int x[N];
int y[N];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void)
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
/*图形驱动*/
void Init(void)
int gd = DETECT, gm;
initgraph(&gd, &gm, "c:\\tc");
cleardevice();
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void)
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE, 0, THICK_WIDTH);/*设置线型*/
for(i = 50; i <= 600; i += 10)/*画围墙*/
rectangle(i, 40, i + 10, 49); /*上边*/
rectangle(i, 451, i + 10, 460);/*下边*/
for(i = 40; i <= 450; i += 10)
rectangle(50, i, 59, i + 10); /*左边*/
rectangle(601, i, 610, i + 10);/*右边*/
/*玩游戏具体过程*/
void GamePlay(void)
randomize();/*随机数发生器*/
food.yes = 1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life = 0;/*活着*/
snake.direction = 1;/*方向往右*/
snake.x[0] = 100; snake.y[0] = 100;/*蛇头*/
snake.x[1] = 110; snake.y[1] = 100;
snake.node = 2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
if(food.yes == 1)/*需要出现新食物*/
food.x = rand() % 400 + 60;
food.y = rand() % 350 + 60;
while(food.x % 10 != 0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y % 10 != 0)
food.y++;
food.yes = 0;/*画面上有食物了*/
if(food.yes == 0)/*画面上有食物了就要显示*/
setcolor(GREEN);
rectangle(food.x, food.y, food.x + 10, food.y - 10);
for(i = snake.node - 1; i > 0; i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
snake.x[i] = snake.x[i-1];
snake.y[i] = snake.y[i-1];
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)
case 1: snake.x[0] += 10; break;
case 2: snake.x[0] -= 10; break;
case 3: snake.y[0] -= 10; break;
case 4: snake.y[0] += 10; break;
for(i = 3; i < snake.node; i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
if(snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
GameOver();/*显示失败*/
snake.life = 1;
break;
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到墙壁*/
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/
if(snake.life == 1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0] == food.x && snake.y[0] == food.y)/*吃到食物以后*/
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x, food.y, food.x + 10, food.y - 10);
snake.x[snake.node] =- 20; snake.y[snake.node] =- 20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes = 1;/*画面上需要出现新的食物*/
score += 10;
PrScore();/*输出新得分*/
setcolor(4);/*画出蛇*/
for(i = 0; i < snake.node; i++)
rectangle(snake.x[i], snake.y[i], snake.x[i] + 10,
snake.y[i] - 10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1], snake.y[snake.node-1],
snake.x[snake.node-1] + 10, snake.y[snake.node - 1] - 10);
/*endwhile(!kbhit)*/
if(snake.life == 1)/*如果蛇死就跳出循环*/
break;
key = bioskey(0);/*接收按键*/
if(key == ESC)/*按ESC键退出*/
break;
else
if(key == UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key == RIGHT &&snake.direction != 2)
snake.direction=1;
else
if(key == LEFT && snake.direction != 1)
snake.direction = 2;
else
if(key == DOWN && snake.direction != 3)
snake.direction = 4;
/*endwhile(1)*/
/*游戏结束*/
void GameOver(void)
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0, 0, 4);
outtextxy(200, 200, "GAME OVER");
getch();
/*输出成绩*/
void PrScore(void)
char str[10];
setfillstyle(SOLID_FILL, YELLOW);
bar(50, 15, 220, 35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str, "score:%d", score);
outtextxy(55, 20, str);
/*图形结束*/
void Close(void)
getch();
closegraph();
本回答被提问者采纳 参考技术D /*
贪吃蛇程序
by
champking
*/
#define
N
200
#include
<graphics.h>
#include
<stdlib.h>
#include
<dos.h>
#define
LEFT
0x4b00
#define
RIGHT
0x4d00
#define
DOWN
0x5000
#define
UP
0x4800
#define
ESC
0x011b
int
i,key;
int
score
=
0;/*得分*/
int
gamespeed
=
100000;/*游戏速度自己调整*/
struct
Food
int
x;/*食物的横坐标*/
int
y;/*食物的纵坐标*/
int
yes;/*判断是否要出现食物的变量*/
food;/*食物的结构体*/
struct
Snake
int
x[N];
int
y[N];
int
node;/*蛇的节数*/
int
direction;/*蛇移动方向*/
int
life;/*
蛇的生命,0活着,1死亡*/
snake;
void
Init(void);/*图形驱动*/
void
Close(void);/*图形结束*/
void
DrawK(void);/*开始画面*/
void
GameOver(void);/*结束游戏*/
void
GamePlay(void);/*玩游戏具体过程*/
void
PrScore(void);/*输出成绩*/
/*主函数*/
void
main(void)
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
/*图形驱动*/
void
Init(void)
int
gd
=
DETECT,
gm;
initgraph(&gd,
&gm,
"c:\\tc");
cleardevice();
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void
DrawK(void)
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,
0,
THICK_WIDTH);/*设置线型*/
for(i
=
50;
i
<=
600;
i
+=
10)/*画围墙*/
rectangle(i,
40,
i
+
10,
49);
/*上边*/
rectangle(i,
451,
i
+
10,
460);/*下边*/
for(i
=
40;
i
<=
450;
i
+=
10)
rectangle(50,
i,
59,
i
+
10);
/*左边*/
rectangle(601,
i,
610,
i
+
10);/*右边*/
/*玩游戏具体过程*/
void
GamePlay(void)
randomize();/*随机数发生器*/
food.yes
=
1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life
=
0;/*活着*/
snake.direction
=
1;/*方向往右*/
snake.x[0]
=
100;
snake.y[0]
=
100;/*蛇头*/
snake.x[1]
=
110;
snake.y[1]
=
100;
snake.node
=
2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
if(food.yes
==
1)/*需要出现新食物*/
food.x
=
rand()
%
400
+
60;
food.y
=
rand()
%
350
+
60;
while(food.x
%
10
!=
0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y
%
10
!=
0)
food.y++;
food.yes
=
0;/*画面上有食物了*/
if(food.yes
==
0)/*画面上有食物了就要显示*/
setcolor(GREEN);
rectangle(food.x,
food.y,
food.x
+
10,
food.y
-
10);
for(i
=
snake.node
-
1;
i
>
0;
i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
snake.x[i]
=
snake.x[i-1];
snake.y[i]
=
snake.y[i-1];
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)
case
1:
snake.x[0]
+=
10;
break;
case
2:
snake.x[0]
-=
10;
break;
case
3:
snake.y[0]
-=
10;
break;
case
4:
snake.y[0]
+=
10;
break;
for(i
=
3;
i
<
snake.node;
i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
if(snake.x[i]
==
snake.x[0]
&&
snake.y[i]
==
snake.y[0])
GameOver();/*显示失败*/
snake.life
=
1;
break;
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到墙壁*/
GameOver();/*本次游戏结束*/
snake.life=1;
/*蛇死*/
if(snake.life
==
1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0]
==
food.x
&&
snake.y[0]
==
food.y)/*吃到食物以后*/
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,
food.y,
food.x
+
10,
food.y
-
10);
snake.x[snake.node]
=-
20;
snake.y[snake.node]
=-
20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes
=
1;/*画面上需要出现新的食物*/
score
+=
10;
PrScore();/*输出新得分*/
setcolor(4);/*画出蛇*/
for(i
=
0;
i
<
snake.node;
i++)
rectangle(snake.x[i],
snake.y[i],
snake.x[i]
+
10,
snake.y[i]
-
10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],
snake.y[snake.node-1],
snake.x[snake.node-1]
+
10,
snake.y[snake.node
-
1]
-
10);
/*endwhile(!kbhit)*/
if(snake.life
==
1)/*如果蛇死就跳出循环*/
break;
key
=
bioskey(0);/*接收按键*/
if(key
==
ESC)/*按ESC键退出*/
break;
else
if(key
==
UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key
==
RIGHT
&&snake.direction
!=
2)
snake.direction=1;
else
if(key
==
LEFT
&&
snake.direction
!=
1)
snake.direction
=
2;
else
if(key
==
DOWN
&&
snake.direction
!=
3)
snake.direction
=
4;
/*endwhile(1)*/
/*游戏结束*/
void
GameOver(void)
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,
0,
4);
outtextxy(200,
200,
"GAME
OVER");
getch();
/*输出成绩*/
void
PrScore(void)
char
str[10];
setfillstyle(SOLID_FILL,
YELLOW);
bar(50,
15,
220,
35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,
"score:%d",
score);
outtextxy(55,
20,
str);
/*图形结束*/
void
Close(void)
getch();
closegraph();
贪吃蛇 C语言
步骤:
1、建立蛇对象、食物对象
坐标:
struct COOR
int X;
int Y;
;
//蛇对象
struct SANKE
struct COOR snake[MAXSIZE];
int size;
snake;
//食物对象
struct FOOD
struct COOR food;
food;
//定义分数
int score=0;
2、初始化蛇、初始化食物
//初始化蛇
void InitSnake()
snake.size=2;
//蛇头
snake.snake[0].X=WIDE/2;
snake.snake[0].Y=HEIGHT/2;
//蛇身
snake.snake[1].X=WIDE/2-1;
snake.snake[1].Y=HEIGHT/2;
//初始化食物
void InitFood()
food.food.X = rand() % HEIGHT;
food.food.Y = rand() % WIDE;
//修改控制台光标的位置 把光标移动到蛇头的位置 同理可以修改光标到食物的位置
COORD coord;
coord.X=snake.snake[0].X;
coord.Y=snake.snake[0].Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
3、控制流程
1)结束条件:蛇头碰墙 蛇头和蛇身相碰
//蛇头碰墙 如果已经碰墙则不执行后序操作
while(
snake.snake[0].X >=0 && snake.snake[0].X<WIDE
&&
snake.snake[0].Y >=0 && snake.snake[0].Y<height
)
//蛇头碰蛇身
for(int i=1;i<snake.size;i++)
if(snake.snake[0].X==snake.snake[i].X && snake.snake[0].Y==snake.snake[i].Y )
return;
2)蛇头和食物碰撞:
蛇身增长 食物消失产生新的食物 分数增加 移动速度增加
if(snake.snake[0].X==food.food.X && snake.snake[0].Y==food.food.Y)
//蛇身增长
snake.size++;
//食物消失产生新的食物
InitSnake();
//分数增加
score+=10;
//移动速度增加
3)蛇的移动: 自动移动 控制移动
void SnakeMove()
if(_kbhit()) //检查是否有输入 有则执行
char key=_getch();
switch (key)
case w:kx = 0; ky = -1; break;//上
case s:kx = 0; ky = +1 ; break;//下
case d:kx = +1; ky = 0; break;//右
case a:kx = -1; ky = 0; break;//左
default:
break;
//移动 前一个给后一个
for (int i = snake.size - 1; i > 0; i--)
snake.snake[i].X = snake.snake[i - 1].X;
snake.snake[i].Y = snake.snake[i - 1].Y;
snake.snake[0].X += kx;
snake.snake[0].Y += ky;
4)显示分数 : 排行榜
void ShowScore()
COORD coord;
coord.X = 0;
coord.Y = HEIGHT + 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
printf("Game Over!!!\\n");
printf("最终得分为:%d\\n", score);
return;
4、图形界面
//设置墙
void SnakeWall()
for (int i = 0; i <= HEIGHT; i++)
for (int j = 0; j <= WIDE; j++)
if (j == WIDE)
printf("|");
else if (i == HEIGHT)
printf("_");
else
printf(" ");
printf("\\n");
扩展知识:
1、SetConsoleCursorPosition函数
头文件:#include<conio.h>
#include<Windows.h>
typedef struct _COORD
SHORT X;
SHORT Y;
COORD;//是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标
COORD coord;//定义结构体变量
//设置坐标
coord.X=10;
coord.Y=20
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
2、getch() 从控制台无回显的取一个字符
返回值:读取字符的ASCII码
头文件:#include<conio.h>
用法:char key=_getch();
3、kbhit() 以非阻塞方式,检查当前是否有键盘输入
用法:if(kbhit())……
返回值:有则为非零值,无则为假0
头文件:#include<conio.h>
编译出错尝试 :_kbhit();
4、SetConsoleCursorInfo() //放到main()函数中
typedef struct _CONSOLE_CURSOR_INFO
DWORD dwSize;//大小
BOOL bVisible;//是否可见
CONSOLE_CURSOR_INFO;//描述光标信息 隐藏光标位置
用法:
CONSOLE_CURSOR_INFO cci;
cci.dwSize=sizeof(cci);
cci.bVisible=FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci)
综合代码:
头文件snake.h中:
#ifndef __OJ_H__
#define __OJ_H__
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<math.h>
#include<time.h>
#include<conio.h>
#include<Windows.h>
#define MAXSIZE 10
#define WIDE 60
#define HEIGHT 20
struct COOR
int X;
int Y;
;
//蛇对象
struct SANKE
struct COOR snake[MAXSIZE];
int size;
snake;
//食物对象
struct FOOD
struct COOR food;
food;
//初始化蛇
void InitSnake();
//初始化食物
void InitFood();
void SnakeMove();
void SnakeWall();
void InitCursorPosition();
void ShowScore();
#endif // !__OJ_H__
text.c 中:
#include"oj.h"
int main()
//隐藏光标
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
_kbhit();
srand((unsigned int)time(NULL));
SnakeWall();
InitSnake();
InitFood();
InitCursorPosition();
SnakeMove();
return 0;
snake.c中 :
#define _CRT_SECURE_NO_WARNINGS
#include"oj.h"
//成绩
int score = 0;
//移动后的坐标
int kx = 0;
int ky = 0;
//记录蛇尾坐标
int lastX = 0;
int lastY = 0;
//速度
int sleepSpeed = 400;
//初始化蛇
void InitSnake()
snake.size = 2;
//蛇头
snake.snake[0].X = WIDE / 2;
snake.snake[0].Y = HEIGHT / 2;
//蛇身
snake.snake[1].X = WIDE / 2 - 1;
snake.snake[1].Y = HEIGHT / 2;
//初始化食物
void InitFood()
food.food.X = rand() % WIDE;
food.food.Y = rand() % HEIGHT;
//设置坐标在控制台的位置
void InitCursorPosition()
COORD coord = 0 ;
for (int i = 0; i < snake.size; i++)
coord.X = snake.snake[i].X;
coord.Y = snake.snake[i].Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
if (i == 0)
putchar(@);
else
putchar(*);
//除去蛇尾
coord.X = lastX;
coord.Y = lastY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar( );
//食物的坐标
coord.X = food.food.X;
coord.Y = food.food.Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar(#);
//设置墙
void SnakeWall()
for (int i = 0; i <= HEIGHT; i++)
for (int j = 0; j <= WIDE; j++)
if (j == WIDE)
printf("|");
else if (i == HEIGHT)
printf("_");
else
printf(" ");
printf("\\n");
//蛇移动
void SnakeMove()
char key = d;//默认往右走
while (snake.snake[0].X >= 0 && snake.snake[0].X < WIDE
&&
snake.snake[0].Y >= 0 && snake.snake[0].Y < HEIGHT)
//SnakeWall();
InitCursorPosition(); //重画蛇身
if (_kbhit()) //检查是否有输入 有则执行
key = _getch();
switch (key)
case w:kx = 0; ky = -1; break;//上
case s:kx = 0; ky = +1; break;//下
case d:kx = +1; ky = 0; break;//右
case a:kx = -1; ky = 0; break;//左
default:
break;
//蛇头碰蛇身
for (int i = 1; i < snake.size; i++)
if (snake.snake[0].X == snake.snake[i].X && snake.snake[0].Y == snake.snake[i].Y)
ShowScore();
return;
//蛇头和食物碰撞
if (snake.snake[0].X == food.food.X && snake.snake[0].Y == food.food.Y)
//蛇身增长
snake.size++;
//食物消失产生新的食物
InitFood();
//分数增加
score += 10;
//移动速度增加
sleepSpeed -= 50;
//存储蛇尾
lastX = snake.snake[snake.size - 1].X;
lastY = snake.snake[snake.size - 1].Y;
//移动 前一个给后一个
for (int i = snake.size - 1; i > 0; i--)
snake.snake[i].X = snake.snake[i - 1].X;
snake.snake[i].Y = snake.snake[i - 1].Y;
snake.snake[0].X += kx;
snake.snake[0].Y += ky;
//视觉上让蛇移动
Sleep(sleepSpeed);
//system("cls");
ShowScore();
void ShowScore()
COORD coord;
coord.X = 0;
coord.Y = HEIGHT + 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
printf("Game Over!!!\\n");
printf("最终得分为:%d\\n", score);
return;
以上是关于c语言 贪吃蛇 程序的主要内容,如果未能解决你的问题,请参考以下文章