当前位置:网站首页>贪吃蛇 C语言
贪吃蛇 C语言
2022-06-28 00:36:00 【51CTO】
步骤:
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;
}
边栏推荐
- How to use data-driven "customer lifecycle management" to improve lead conversion rate and customer satisfaction?
- 简单文件传输协议TFTP
- Cvpr22 collected papers | hierarchical residual multi granularity classification network based on label relation tree
- [sylixos] I2C device driver creation and use
- Jenkins - 訪問 Jenkins 自定義參數變量,處理變量值中含有空格
- Geojson format description (detailed format)
- 【sylixos】NEW_1 型字符驱动示例
- [Yocto RM]9 - QA Error and Warning Messages
- General process after reference layer reboot
- A set of sai2 brushes is finally finished! Share with everyone!
猜你喜欢

Use code binding DataGridView control to display tables in program interface

Jenkins - 訪問 Jenkins 自定義參數變量,處理變量值中含有空格

SQL injection bypass (IV)

Raspberry pie realizes intelligent cooling by temperature control fan

SQL injection bypass (V)

王心凌、谭维维 - 山海(副歌加长版) 在线试听无损FLAC下载

Jenkins - 内置变量访问

Appium自动化测试基础— 补充:App的包名(appPackage)和启动名(appActivity)

New choice for database Amazon Aurora

frp实现内网穿透
随机推荐
SQL 注入绕过(五)
Appium automation test foundation ADB common commands (I)
STM32F103的11个定时器
原理图合并中的技巧
ScheduledThreadPoolExecutor源码解读(二)
云平台kvm迁移本地虚拟机记录
JS array random value (random array value)
树莓派实现温控风扇智能降温
mysql面试百题集
Description du format geojson (détails du format)
SQL 注入绕过(二)
Jenkins - Copy Artifact 插件 Build 之间数据共享传递
Figure out the difference between MIT, BSD and Apache open source protocols
Complex and inefficient logistics? Three steps to solve problems in enterprise administration
[Yocto RM] 2 - Yocto Project Terms
外盘期货哪里可以开户?哪个平台出入金比较安全?
Differences between cesium polygon extrudedheight and height
Numpy----np.tile()函数解析
王心凌、谭维维 - 山海(副歌加长版) 在线试听无损FLAC下载
文件传输协议--FTP