Table of contents
1. The idea of game realization
(6) Modify the console cursor position
(8) Movement control of the snake
2. Game implementation code and header files
This project is suitable for those who have just learned the C language structure and have a certain basic C language practice. This small project can help you practice your object-oriented programming thinking.
1. The idea of game realization
In order to realize the Snake game, according to the object-oriented thinking, the following modules must be realized
1. Define snake objects and food objects
2. Initialize the snake, initialize the food
3. Control process:
1) The collision between the snake head and the wall
2) Collision between snake head and snake body
3) Collision between snake head and food
1> Snake body growth
2> Food disappears -- new food is created
3> Score accumulation
4> Increased movement speed
4) Movement of the snake
automatic movement
Manually control the movement: ASWD --- Left, bottom, top, right
5) Show score
leaderboard
4. Graphical interface.
(1) Define the snake object
The principle of snake object implementation is coordinates, and X and Y are set to represent the abscissa and ordinate respectively. The body can be represented by an array. body[0] represents the head of the snake, and others represent the body of the snake. And increase.
struct BODY {
int x;
int Y;
};
struct SNAKE {
struct BODY body[20*60]; // 蛇身 。 body[0] -- 蛇头
int size; // 蛇的大小
}snake;
(2) Food objects
The implementation of the food object is the same as that of the snake object
struct FOOD {
int X;
int Y;
}food;
(3) Score:
int score;
(4) Initialize the snake
Encapsulate a function to complete the initial snake. The initial size of the snake is 2, representing the snake body and snake head respectively.
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;
}
(5) Initialize food
void initFood(void)
{
food.X = rand() % WIDE; // 0-59
food.Y = rand() % HIGH; // 0-59
return;
}
(6) Modify the console cursor position
The cursor position will be positioned at the initialized snake head position (WIDE/2, HIGH/2). The middle of the screen. Note that header files are required to implement the following code: #include <conio.h>, #include <Windows.h>
COORD coord; // COORD --> 结构体, 有两个成员变量:x,y 坐标
coord.X = snake.body[0].X;
coord.Y = snake.body[0].Y;
setConsoleCursorPositon(GetStdHandle(STD_OUTPUT_HANDLE), coord);
(7) Draw the snake and food
"@" means the head of the snake, and "*" means the body of the snake. "#" means food
封装函数, initUI()
COORD coord = {0}; // 光标移动的位置。
// 画蛇
for (size_t i = 0; i < snake.size; i++)
{
coord.X = snake.body[i].X;
coord.Y = snake.body[i].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('#');
(8) Movement control of the snake
keyboard input
W: (0, -1) --> Affects snake heads.
s:(0, +1)
A:(-1, 0)
D:(+1, 0)
No echo: can make the asdw typed by the keyboard not displayed on the input interface
getch() receives user input.
char key = getch();
Error while compiling, try to use _getch();
Non-blocking: the input snake cursor can be made non-blocking
kbhit(); Does not block to judge user input.
If there is user input, return "true", otherwise return "false".
Error while compiling, try to use _kbhit();
(9) Start the game
void playGame(void)
{
char key = 'd'; // 默认蛇向右移动
// 蛇头和墙壁的碰撞:
while ( 判断是否撞墙 ) {
// 重画蛇身 intiUI
// 接收用户键盘输入。
在全局 添加:kx, ky --》 根据 asdw 按键得不同坐标,影响蛇头
// 蛇头和身体的碰撞
// 蛇与食物的碰撞
// 蛇身体移动 : 前一节给后一节赋值,蛇头收 kx ky 的影响。
system("cls"); 清屏 -- 去除蛇尾。
}
}
Collision of snake head and wall
Analyzing conditions
snake.body[0].X > 0 && snake.body[0].X < WIDE
&&
snake.body[0].Y > 0 && snake.body[0].Y < HIGH
Snake head and body collision
The coordinates of the snake head are exactly the same as the coordinates of any segment of the body.
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 ;
}
}
Collision of snake head and food
if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
{
蛇身增长: snake.size++;
食物消失:(产生一个新食物)initFood()
加分:score += 10;
加速:sleepSecond -= 20;
}
(10) Snake Move
The body of the previous section assigns a value to the body of the next section. The snake head is transformed according to the coordinate value converted by aswd.
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;
(11) Painting the wall
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");
}
}
(12) Remove snake tail
Save the snake tail coordinates before the snake moves.
Define global variables: lastX, lastY;
lastX = snake.body[snake.size-1].X ;
lastY = snake.body[snake.size-1].Y ;
In initUI, replace snake tail with ' '
coord.X = lastX;
coord.Y = lastY;
setConsoleCursorPosition(GetSTDHandler(STD_OUTPUT_HANDLE), coord);
putchar(' ');
(13) Remove the cursor
Cancel the displayed cursor: please press anywhere to continue to make the interface more beautiful
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize; // 大小
BOOL bVisible; // 是否可见。
} CONSOLE_CURSOR_INFO;
定义结构体变量:
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE; // 0 假 --- 不可见
设置光标不可见生效:
setConsoleCursorInfo(GetSTDHandler(STD_OUTPUT_HANDLE), &cci);
在main函数中,调用一次即可生效。
(14) Display score
When the playGame call ends, print the global score value.
(15) speed up
Define variables globally: sleepSecond = 400;
Sleep(sleepSecond);
successfully eat food, sleepSecond -= 20;
2. Game implementation code and header files
It is recommended to use the VS editor for the game, and it is not recommended for beginners to use the dev editor. The complete code and the implemented exe file are below. If you are interested, you can pack it and take it away.
The figure below is after the code is implemented