1.模块设计
2.总述
3.定义蛇对象,食物对象
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define WIDE 60 //宽度
#define HIGH 20 //高度
//身体对象
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; //分数
4.初始化蛇,食物
//蛇对象初始化
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-19
return;
}
snake.h
#ifndef __SNAKE_H__
#define __SNAKE_H__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define WIDE 60 //宽度
#define HIGH 20 //高度
//身体对象
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; //分数
void initSnake(void);
void initFood(void);
#endif
main.c
#include "snake.h"
int main(void)
{
srand(time(NULL)); //播种随机数种子
initSnake(); //初始化蛇
initFood(); //初始化食物
printf("snake 头:x=%d,y=%d\n", snake.body[0].X, snake.body[0].Y);
printf("snake 身:x=%d,y=%d\n", snake.body[1].X, snake.body[1].Y);
printf("food x=%d,y=%d\n", food.X, food.Y);
return 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-19
return;
}
5.修改控制台光标位置
#include <conio.h>
#include <Windows.h>
6.画出蛇和食物
void initUI(void)
{
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 = lastX;
coord.Y = lastY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar(' ');
// 画食物
coord.X = food.X;
coord.Y = food.Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar('#');
}
7.蛇的移动控制
int kx = 0; //用户按下 aswd 任意一个按键所得到的坐标值
int ky = 0;
8.开始游戏
void playGame(void)
{
char key = 'd';
//判断蛇撞墙
while (snake.body[0].X >= 0 && snake.body[0].X < WIDE
&& snake.body[0].Y >= 0 && snake.body[0].Y < HIGH)
{
//更新蛇
initUI();
//接收用户按键输入 asdw
if (_kbhit()) //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 (size_t 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)
{
initFood(); //食物消失
snake.size++; //身体增长
score += 10; //加分
sleepSecond -= 10; //加速
}
//存储蛇尾坐标
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;
}
9.画墙
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");
}
}
10.去除蛇尾
int lastX = 0; //蛇尾坐标
int lastY = 0;
11.去除光标
//去除光标
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
12.显示分数,加速
void showScore(void)
{
COORD coord;
//将光标默认位置移动至不干扰游戏的任意位置
coord.X = 0;
coord.Y = HIGH + 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
printf("Game over!!!\n");
printf("成绩为:%d\n\n\n", score);
}
snake.h
#ifndef __SNAKE_H__
#define __SNAKE_H__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>
#define WIDE 60 //宽度
#define HIGH 20 //高度
//身体对象
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; //分数
int sleepSecond = 400;
int kx = 0; //用户按下 aswd 任意一个按键所得到的坐标值
int ky = 0;
int lastX = 0; //蛇尾坐标
int lastY = 0;
void initSnake(void);
void initFood(void);
void initUI(void);
void initWall(void);
void playGame(void);
void showScore(void);
#endif
main.c
#include "snake.h"
int main(void)
{
//去除光标
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
srand(time(NULL)); //播种随机数种子
initSnake(); //初始化蛇
initFood(); //初始化食物
initWall(); //画墙
initUI(); //画蛇和食物
playGame(); //启动游戏
showScore(); //打印分数
return 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-19
return;
}
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 initUI(void)
{
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 = lastX;
coord.Y = lastY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar(' ');
// 画食物
coord.X = food.X;
coord.Y = food.Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar('#');
}
void playGame(void)
{
char key = 'd';
//判断蛇撞墙
while (snake.body[0].X >= 0 && snake.body[0].X < WIDE
&& snake.body[0].Y >= 0 && snake.body[0].Y < HIGH)
{
//更新蛇
initUI();
//接收用户按键输入 asdw
if (_kbhit()) //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 (size_t 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)
{
initFood(); //食物消失
snake.size++; //身体增长
score += 10; //加分
sleepSecond -= 10; //加速
}
//存储蛇尾坐标
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 showScore(void)
{
COORD coord;
//将光标默认位置移动至不干扰游戏的任意位置
coord.X = 0;
coord.Y = HIGH + 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
printf("Game over!!!\n");
printf("成绩为:%d\n\n\n", score);
}