一、贪吃蛇游戏实现思路:
1.定义蛇对象、食物对象
2.初始化蛇、初始化食物
3.控制流程:
(1)蛇头和墙壁的碰撞
(2)蛇头和蛇身体碰撞
(3)蛇头和食物碰撞
(4)移动速度增大
4.游戏效果:
(1)蛇身增长
(2)食物消失 -- 新食物产生
(3)分数累加
(4)移动速度增大
(5)蛇的移动
(6)显示分数
二、实现步骤:
1.引入头文件:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
2.宏定义:
#define WIDE 60 //宽度
#define HIGH 20 //高度
3.定义对象:
蛇身对象: struct BOOY { int X; int Y; }; 蛇对象: struct SNAKE { struct BODY body[20*60]; //蛇身 body[0] -- 蛇头 int size; //蛇的大小 } snake; 食物对象: struct FOOD { int X; int Y; } food;
4.初始化:
初始化分数: int score = 0; 初始化蛇: 封装一个函数 完成蛇的初始化: void initSnake(void) { snake.size = 2; 初始化好了蛇头 snake.body[0].X = WIDE/2; snake.body[0].Y = HIGH/2; 初始化一节蛇身 snake.body[1].X = WIDE/2 - 1; snake.body[1].Y = HIGH/2; return; } 初始化食物: void initFood(void) { food.X = rand() % WIDE; //0-59 food.Y = rand() % HIGH; //0-59 return; }
5.控制定位:
修改控制台光标位置: COORD coord; //CORD --> 结构体, 有两个成员变量:x, y 坐标 coord.X = snake.body[0].X; coord.Y = snake.body[0].Y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); 会将光标位置,定位到 初始化好的蛇头位置(WIDE/2, HIGH/2), 屏幕中间
6.画出形状:
画出蛇和食物: 封装函数 initUI(void) { //光标移动位置 COORD coord = {0}; //画蛇 for (size_t i = 0; i < snake.size; ++i) { coord.X = snake.body[0].X; coord.Y = snake.body[0].Y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); if (i == 0) putchar('@'); else putchar('*'); } //画食物 coord.X = food.X; coord.Y = food.Y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); putchar('#'); }画墙: void initWall(void) { for (size_t i = 0; i <= HIGH; i++) //多行 { for (size_t j = 0; j <= WIDE; j++) //一行中的多列 { if (j == WIDE) { printf("|"); } else if (i = HIGH) { printf("_"); } else { printf(" "); } } printf("\n"); } }
7.按键控制:
蛇的移动控制: W: (0, -1) -->影响蛇头 S: (0, +1) A: (-1, 0) D: (+1, 0) 不回显: getch():接受用户输入。 char key = getch(); 编译时出错,尝试使用 _getch(); 不堵塞: kbhit(); 不阻塞判断用户输入。 有用户输入返回“真”,否则返回“假”值 编译时出错,尝试使用 _kbhit();
8.游戏体验:
开始游戏: void playGame(void) { char key = 'd'; //默认蛇向右移动 蛇头和墙壁的碰撞: while(判断是否撞墙) { //重画蛇身 initUI //接受用户键盘输入 在全局 添加:kx, ky --> 根据 A S D W 按键得不同坐标, 影响蛇头 //蛇头和身体的碰撞 //蛇头和食物的碰撞 //蛇身体移动:前一节给后一节赋值,舌头收 kx ky 的影响 system("cls"); 清屏 -- 去除蛇尾 } } 蛇头和墙壁的碰撞: snake.body[0].X > 0 && snake.body[0].X < WIDE && snake.body[0].Y > 0 && snake.body[0].Y < HIGH 蛇头和身体碰撞: 蛇头的坐标 和 任意一节身体和坐标 完全一致 for(i = 1; i < snake.size; i++) { if(snake.body[0].X == snake.body[i].X && snake.body[0].Y == snake.body[i].Y) { //终止游戏 return; } } 蛇头和食物的碰撞: if(snake.body[0].X == food.X && snake.body[0].Y == food.Y) { 蛇身增长:snake.size++ 食物消失:(产生一个新食物)initFood() 加分:score += 10; 加速: } 蛇移动: 前一节身体给后一节身体赋值。蛇头按照 A S W D 换算的坐标值 进行交换 for (size_t i = snake.size - 1; i > 0; i--) { snake.body[i].X = snake.body[i - 1].X; snake.body[i].Y = snake.body[i - 1].Y; } snake.body[0].X += kx; //蛇头坐标根据用户按键,修改 snake.body[0].Y += ky;
9.游戏优化 :
去除蛇尾: 蛇移动之前保存蛇尾坐标: 定义全局变量:lastX, lastY; lastX = snake.body[nake.size - 1].X; lastX = snake.body[nake.size - 1].X; 在int中,将蛇尾 替换为 ' ' coord.X = lastX; coord.Y = lastY; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); putchar(' ');去除光标: typedef struct _CONSOLE_CURSOR_INFO { DWORD dwSize; //大小 BOOL bVisible; //是否可见 } CONSOLE_CURSOR_INFO; 定义结构体变量: CONSOLE_CURSOR_INFO cci; cci.dwSize = sizeof(cci); cci.bVisible = FALSE; //TRUE; 设置光标不可见生效: SetConsoleCursorInfo(SetStdHandle(STD_OUTPUT_HANDLE), &cci); 显示分数 playGame调用结束时, 打印 全局 score 值 加速: 全局定义变量: sleepSecond = 400; Sleep(sleepSecond); sleepSecond -= 20;
10.实现效果:
文章来源:https://www.toymoban.com/news/detail-826611.html
文章来源地址https://www.toymoban.com/news/detail-826611.html
三、项目源码:
1.主程序文件" main.c "中的代码:
#define _CRT_SECURE_NO_WARNINGS
#include "snake.h" //引入自定义头文件
int main(void) {
// 强制控制输出
//-----------------------------------------------------------------
// setbuf(stdout, NULL); //直接输出,解除缓存
//-----------------------------------------------------------------
// 游戏地图范围 测试代码
//----------------------------------------------------------------
// for (size_t i = 0; i < 20; i++) {
// for (size_t j = 0; j < 60; j++) {
// printf(" ");
// }
// printf("\n");
// }
//----------------------------------------------------------------
//去除光标
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE; //TRUE;
SetConsoleCursorInfo(SetStdHandle(STD_OUTPUT_HANDLE), &cci);
srand(time(NULL)); //播种随机数种子
initSnake(); //初始化蛇
initFood(); //初始化食物
initWall(); //画墙
initUI(); //画蛇和食物
playGame(); //启动游戏
showScore(); //打印分数
// 测试代码
//----------------------------------------------------------------
// printf("头:x=%d, y=%d\n",snake.body[0].X, snake.body[0]);
// printf("身:x=%d, y=%d\n",snake.body[1].X, snake.body[1]);
// printf("food:x=%d, y=%d\n", food.X, food.Y);
//----------------------------------------------------------------
system("pause");
return EXIT_SUCCESS;
}
//
//void Kithit() {
//
//}
void showScore()
{
//将光标默认位置移动至 不干扰游戏的任意位置
COORD coord;
coord.X = 0;
coord.Y = HIGH + 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
printf("Game Over!!!");
printf("成绩为:%d\n\n\n", score);
}
void initWall(void)
{
for (size_t i = 0; i <= HIGH; i++) //多行
{
for (size_t j = 0; j <= WIDE; j++) //一行中的多列
{
if (j == WIDE)
{
printf("|");
}
else if (i = HIGH)
{
printf("_");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
void playGame(void)
{
//定义key案件
char key = 'd';
//判断蛇撞墙
while(snake.body[0].X >= 0 && snake.body[0].X < WIDE
&& snake.body[0].Y >= 0 && snake.body[0].X < HIGH)
{
//更新蛇
initUI();
//接受用户键盘输入 A左 D右 W上 S下
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;
}
// 测试上下左右键
//------------------------------------------------------------------
// printf("---- key = %c\n", key);
//------------------------------------------------------------------
//蛇头撞身体:蛇头 == 任意一节身体
for (size_t i = 0; i < snake.size; i++)
{
if (snake.body[0].X == snake.body[i].X
&& snake.body[0].Y == snake.body[i].Y)
{
return; //游戏结束
}
}
//蛇头撞食物
if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
{
initFood(); //食物消失
snake.size++; //身体增长
score += 10; //加分
sleepSecond; //加速
}
//存储蛇尾坐标
lastX = snake.body[snake.size - 1].X;
lastY = snake.body[snake.size - 1].Y;
//蛇移动,前一节身体给后一节身体赋值
for (size_t i = snake.size - 1; i > 0; i--)
{
snake.body[i].X = snake.body[i - 1].X;
snake.body[i].Y = snake.body[i - 1].Y;
}
snake.body[0].X += kx; //蛇头坐标根据用户按键,修改
snake.body[0].Y += ky;
Sleep(sleepSecond);
//清屏
// system("cls");
}
return;
}
//定义初始化蛇函数
void initSnake(void)
{
snake.size = 2;
//蛇头初始化
snake.body[0].X = WIDE / 2;
snake.body[0].Y = HIGH / 2;
//蛇一节身体初始化
snake.body[1].X = WIDE / 2 - 1;
snake.body[1].Y = HIGH / 2;
return;
}
//坐标 COOED结构体定义
//------------------------------------------------------------------------------
//typedef struct _COORD{
// SHORT X; //X坐标
// SHORT Y; //Y坐标
//} COORD;
//------------------------------------------------------------------------------
//初始化界面控件
void initUI(void)
{
//光标移动位置
COORD coord = {0};
//画蛇
for (size_t i = 0; i < snake.size; ++i)
{
coord.X = snake.body[0].X;
coord.Y = snake.body[0].Y;
//printf("X=%d,Y=%d\n", coord.X, coord.Y);
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
if (i == 0)
putchar('@');
else
putchar('*');
}
//去除蛇尾
coord.Y = lastX;
coord.Y = lastY;
SetConsoleCursorPosition( GetStdHandle(STD_OUTPUT_HANDLE), coord);
//画食物
coord.X = food.X;
coord.Y = food.Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar('#');
// 画食物 测试代码
//--------------------------------------------------------------------------
// coord.X = 0;
// coord.Y = 0;
// SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
//--------------------------------------------------------------------------
}
//初始化食物函数
void initFood(void)
{
food.X = rand() % WIDE; //0-59
food.Y = rand() % HIGH; //0-59
return;
}
2.头文件"snake.h"中的代码:
#ifndef __SNAKE_H__
#define __SNAKE_H__
#define WIDE 60 //宽度
#define HIGH 20 //高度
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
//一个身体的对象
struct BODY {
int X;
int Y;
};
//定义蛇对象
struct SNAKE {
struct BODY body[WIDE*HIGH];
int size;
} snake; //一个蛇对象
//定义一个食物对象
struct FOOD {
int X;
int Y;
} food; //一个食物对象
int score = 0; //分数
//用户按下 asdw 任意一个按键所得到的坐标值
int kx = 0;
int ky = 0;
int lastX = 0; //蛇尾的坐标
int lastY = 0;
//秒数
int sleepSecond = 400;
//声明函数
void initSnake(void);
void initFood(void);
void initUI(void);
void initWall(void);
void playGame(void);
void showScore(void);
#endif
到了这里,关于C语言实战项目-贪吃蛇小游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!