一 、实现贪吃蛇的步骤:
1.画地图
2.画蛇
3.移动
二 、画地图
1.先确定地图的大小
int height=20;
int weight=20;
2.画出边框
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < weight; ++j)
{
if (i == 0 || i == height - 1)
{
map[i][j] = 1;
}
else if (j == 0 || j == weight - 1)
{
map[i][j] = 1;
}
else
{
map[i][j] = 0;
}
}
}
3用■代表边框和蛇身,中间用□划分,●代表蛇头,★代表食物
for (int i = 0; i < height; ++i) {
for (int j = 0; j < weight; ++j) {
if (map[i][j] == 1) {
cout << "■";
}
else if (map[i][j] == 2)
{
cout << "●";
}
else if (i == star[0] && j == star[1])
{
cout << "★";
}
else {
cout << "□";
}
}
cout << '\n';
}
二、画蛇
map[p->i][p->j] = 2; /
p = p->next;
while (p) {
map[p->i][p->j] = 1;
p = p->next;
}
三、移动
switch (c)
{
//向上
case 'w':
update_snake(c, s, star);
break;
//向下
case 's':
update_snake(c, s, star);
break;
//向左
case 'a':
update_snake(c, s, star);
break;
//向右
case 'd':
update_snake(c, s, star);
break;
}
四、整体代码
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<iostream>
#include<conio.h>
#define random(x) (rand()%x)
using namespace std;
int** map;
char c = 0;
int sign = 0;
char check_snake(char c);
struct snake {
int i;
int j;
struct snake* next;
};
struct snake* generateSnake() {
struct snake* s;
s = (struct snake*)malloc(sizeof(struct snake));
struct snake* p = s;
int x[6] = { 2, 3, 4, 5, 5, 5 };
int y[6] = { 2, 2, 2, 2, 3, 4 };
for (int i = 0; i < 6; i++) {
struct snake* node; //节点
node = (struct snake*)malloc(sizeof(struct snake));
p->next = node;
p = p->next;
p->i = x[i];
p->j = y[i];
}
p->next = NULL;
return s;
} // 设置蛇的长度和初始位置
void gotoxy(int x, int y)
{
COORD Position;
Position.X = x;
Position.Y = y;
//调用API改变字体位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Position);
}
// 绘制地图
void draw_map(int** map, int height, int weight) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < weight; ++j) {
if (i == 0 || i == height - 1) { // 表示在第一层和最后一层
map[i][j] = 1; // 四边形的四边作为墙,强我们用1表示,表示位置已占
}
else if (j == 0 || j == weight - 1) { // 表示在最左层和最右层
map[i][j] = 1;
}
else {
map[i][j] = 0; // 除墙以外其他位置为0 表示该位置为空
}
}
cout << "\n";
}
return;
}
// 图形形状
void draw(int** map, int* star, int height, int weight) {
system("cls");//清空屏幕
gotoxy(0, 0);
for (int i = 0; i < height; ++i) {
for (int j = 0; j < weight; ++j) {
if (map[i][j] == 1) {
cout << "■";
}
else if (map[i][j] == 2)
{
cout << "●";
}
else if (i == star[0] && j == star[1])
{
cout << "★";
}
else {
cout << "□";
}
}
cout << '\n';
}
return;
}
// 蛇
void drawSnake(int** map, struct snake* s) {
struct snake* p = s->next;
map[p->i][p->j] = 2; // 蛇头
p = p->next;
while (p) {
map[p->i][p->j] = 1;
p = p->next;
}
return;
}
void draw_star(int** map, int* star, int height, int weight) {
int sum = 0; // 空格子的个数
int index = 0; // 剩下的格子
// 算出空格子的个数
for (int i = 0; i < height; ++i) {
for (int j = 0; j < weight; ++j) {
if (map[i][j] == 0)
{
sum += 1;
}
}
}
index = random(sum) + 1; // 在1到sum 中随机的位置生成星星
//生成星星
for (int i = 0; i < height; ++i) {
for (int j = 0; j < weight; ++j) {
if (map[i][j] == 0) {
index -= 1;
}
if (index == 0) {
star[0] = i;
star[1] = j;
return;
}
}
}
return;
}
void update_snake(char c, struct snake* s, int* star) {
snake* newsnake;
newsnake = (snake*)malloc(sizeof(snake));
if (c == 'w') {
// 相当于在s 头插一个新节点
newsnake->i = s->next->i - 1;
newsnake->j = s->next->j;
if (map[newsnake->i][newsnake->j] == 1) {
// 头插的节点的位置 原本 map[i][j] == 1 表示该位置是墙或者是蛇身了
sign = 3;
}
else if (newsnake->i == star[0] && newsnake->j == star[1]) {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■"); // 恢复蛇身
q = q->next;
}
sign = 2;
}
else {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
gotoxy(q->i, q->j);
printf("■");
map[q->next->i][q->next->j] = 0;
free(q->next);
q->next = NULL;
}
}
else if (c == 's') {
newsnake->i = s->next->i + 1;
newsnake->j = s->next->j;
if (map[newsnake->i][newsnake->j] == 1) {
sign = 3;
}
if (newsnake->i == star[0] && newsnake->j == star[1]) {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
sign = 2;
}
else {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
gotoxy(q->i, q->j);
printf("■");
map[q->next->i][q->next->j] = 0;
free(q->next);
q->next = NULL;
}
}
else if (c == 'a') {
newsnake->i = s->next->i;
newsnake->j = s->next->j - 1;
if (map[newsnake->i][newsnake->j] == 1) {
sign = 3;
}
if (newsnake->i == star[0] && newsnake->j == star[1]) {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
sign = 2;
}
else {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
gotoxy(q->i, q->j);
printf("■");
map[q->next->i][q->next->j] = 0;
free(q->next);
q->next = NULL;
}
}
else {
newsnake->i = s->next->i;
newsnake->j = s->next->j + 1;
if (map[newsnake->i][newsnake->j] == 1) {
sign = 3;
}
if (newsnake->i == star[0] && newsnake->j == star[1]) {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
sign = 2;
}
else {
newsnake->next = s->next;
s->next = newsnake;
struct snake* q = s;
while (q->next->next != NULL) {
gotoxy(q->i, q->j);
printf("■");
q = q->next;
}
gotoxy(q->i, q->j);
printf("■");
map[q->next->i][q->next->j] = 0;
free(q->next);
q->next = NULL;
}
}
}
// 蛇 移动方向
// 上 119 wd
// 下 115 s
// 左 97 a
// 右 100 d
void action_snake(struct snake* s, int* star) {
switch (c)
{
//向上
case 'w':
update_snake(c, s, star);
break;
//向下
case 's':
update_snake(c, s, star);
break;
//向左
case 'a':
update_snake(c, s, star);
break;
//向右
case 'd':
update_snake(c, s, star);
break;
}
}
void check_snake() {
DWORD time = 500; // 1表示一毫秒 1000表示一秒 要改变速度可以修改time的时间
DWORD time_start = GetTickCount(); // 获取当前时间
char t;
while (true) {
if (_kbhit()) {
char ch = _getch(); // 当前键位
if (ch == 97 || ch == 100 || ch == 115 || ch == 119) {
t = ch;
if (t == 97 && c == 'd')
{
c = 'd';
}
else if (t == 100 && c == 'a') {
c = 'a';
}
else if (t == 115 && c == 'w') {
c = 'w';
}
else if (t == 119 && c == 's') {
c = 's';
}
else {
c = ch;
}
}
}
DWORD time_end = GetTickCount(); // 获取键位后的时间
if (time_end - time_start > time) {
time_start = time_end;
break;
}
}
return;
}
int main() {
int height = 20; // 地图高度 map.height = 20
int weight = 20; // 地图宽度 map.weight = 20
struct snake* s = generateSnake();
map = (int**)malloc(sizeof(int*) * height);
for (int i = 0; i < height; ++i) {
map[i] = (int*)malloc(sizeof(int) * weight);
}
draw_map(map, height, weight);
drawSnake(map, s);
int star[2] = { 0,0 };
draw_star(map, star, height, weight);
draw(map, star, height, weight);
while (1) {
if (sign == 3) {
break;
}
check_snake();
action_snake(s, star);
draw_map(map, height, weight);
drawSnake(map, s);
if (sign == 2) {
draw_star(map, star, height, weight);
sign = 0;
}
draw(map, star, height, weight);
gotoxy(0, 0);
}
system("cls");
gotoxy(height / 2, weight / 2);
cout << "游戏结束 ";
system("pause");
return 0;
}
四、
1、gotoxy函数: gotoxy函数可以任意移动位置,进行输入输出。
函数格式是gotoxy(x,y);
使用函数前要定义,还要加头文件#include<windows.h>
2、getch函数:函数原型是t getch(void);[void表示函数没有参考值,t表示返回值类型为整形]
getch函数的作用是从键盘上读取一个字符,并将其返回给程序。
使用函数前要加头文件#include<conio>;
3、index 索引号,一般从0开始计数,返回的是字符数组下标中从0开始计数
4、全局变量: 在所有函数值外部定义的变量. 其可以被任何函数值访问,并且全局变量的值在程序 的整个生命周期都是有效的。