#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
void Pos(int x, int y) {
COORD pos;
pos.X = x;
pos.Y = y;
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//声明句柄变量,做参数操作控制台
SetConsoleCursorPosition(hOutput, pos);//定位光标
}
int main()
{
Pos(26, 15);
printf("@");
Pos(26, 15);
printf(" ");
return 0;
}
//以上代码表示" "可以掩盖住“@”
// 贪吃蛇.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <string.h>
#define Key_Right 'd'//按键向右
#define Key_Left 'a'//按键向组左
#define Key_Up 'w'//按键向上
#define Key_Down 's'//按键向下
#define Key_Space ' '//暂停键 空格
//标记状态量
#define R 1
#define L 2
#define W 3
#define D 4
typedef struct node
{
int x;
int y;
struct node *next;
}Snake;//蛇身结构体
//必要的全局变量
Snake *head; //蛇头
Snake *p; //遍历蛇身
int score = 0; //记录分数
int food_x, food_y; //食物位置坐标
int Status = R; //初始状态量
int key; //接收字符
int endgamestatus = 0; //判断游戏是否结束的状态量
//
//全局函数声明
void Pos(int x, int y); //光标定位符
void CreatMap();//创建地图
void CreatFood(); //生成食物
void CrossWall(); //蛇头与墙相撞
int BitSelf(); //舌头与自身相撞
void SnakeMoving(); //蛇移动
void Endgame(); //游戏结束
void gamecircle(); //游戏循环
void pause();//游戏暂停
////////////////////////////////////
void Pos(int x, int y) // 光标定位符
{
COORD pos;//再windows里面,包含x,y
HANDLE hOutput;
pos.X = x;
pos.Y = y;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//声明句柄变量,做参数操作控制台
SetConsoleCursorPosition(hOutput, pos);//定位光标
}
void CreatMap()//创建地图
{
for (int i = 0; i < 54; ++i)
{
for (int j = 0; j < 26; ++j)
{
Pos(i, 0);
printf("*");
Pos(i, 26);
printf("*");
Pos(0, j);
printf("*");
Pos(54, j);
printf("*");
Pos(54, 26);
printf("*");
}
}
}
void CreatFood()
{
srand(time(NULL));
food_x = rand() % 50 + 1;//1-51降低游戏难度
food_y = rand() % 24 + 1;//1-25
Pos(food_x, food_y);
printf("@");
}
void InitSnake()//蛇身初始化
{
Snake *tail; //蛇尾
head = (Snake *)malloc(sizeof(Snake));
head->x = 25;
head->y = 5;
head->next = NULL;
for (int i = 1; i < 4; ++i)
{
tail = (Snake *)malloc(sizeof(Snake));
tail->x = 25 + i * 1;
tail->y = 5;
tail->next = head;
head = tail;
}
while (tail)
{
Pos(tail->x, tail->y);
printf("@");
tail = tail->next;
}
}
void CrossWall()//撞墙
{
if (head->x == 0 || head->x == 54 || head->y == 0 || head->y == 26)
{
endgamestatus = 1;
Endgame();
}
}
int BitSelf()//撞到自己身体
{
p = head->next;
while (p)
{
if (p->x == head->x && p->y == head->y)
{
return 1;
}
p = p->next;
}
return 0;
}
void SnakeMoving()
{
Snake *newhead;
newhead = (Snake *)malloc(sizeof(Snake));
CrossWall();
if (BitSelf())
{
endgamestatus = 2;
Endgame();
}
if (Status == R)//初始状态为R 1
{
if (head->x == food_x && head->y == food_y)
{
score += 10;
newhead->x = head->x + 1;
newhead->y = head->y;
newhead->next = head;
head = newhead;
p = head;
while (p)
{
Pos(p->x, p->y);
printf("@");//新链表重新打出一条蛇
p = p->next;
}
CreatFood();
}
else
{
newhead->x = head->x + 1;
newhead->y = head->y;
newhead->next = head;
head = newhead;
p = head;
while (p->next->next)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
Pos(p->next->x, p->next->y);//最后一个打印空格,释放节点
printf(" ");//这个空格会掩盖符号
free(p->next);
p->next = NULL;
}
}
if (Status == L)
{
if (head->x == food_x && head->y == food_y)
{
score += 10;
newhead->x = head->x - 1;
newhead->y = head->y;
newhead->next = head;
head = newhead;
p = head;
while (p)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
CreatFood();
}
else
{
newhead->x = head->x - 1;
newhead->y = head->y;
newhead->next = head;
head = newhead;
p = head;
while (p->next->next)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
}
if (Status == W)
{
if (head->x == food_x && head->y == food_y)
{
score += 10;
newhead->x = head->x;
newhead->y = head->y - 1;
newhead->next = head;
head = newhead;
p = head;
while (p)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
CreatFood();
}
else
{
newhead->x = head->x;
newhead->y = head->y - 1;
newhead->next = head;
head = newhead;
p = head;
while (p->next->next)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
}
if (Status == D)
{
if (head->x == food_x && head->y == food_y)
{
score += 10;
newhead->x = head->x ;
newhead->y = head->y + 1;
newhead->next = head;
head = newhead;
p = head;
while (p)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
CreatFood();
}
else
{
newhead->x = head->x;
newhead->y = head->y + 1;
newhead->next = head;
head = newhead;
p = head;
while (p->next->next)
{
Pos(p->x, p->y);
printf("@");
p = p->next;
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
}
}
void Endgame()
{
system("cls");//清屏
Pos(13, 13);
if (endgamestatus == 1)
printf("撞墙啦!");
if (endgamestatus == 2)
printf("撞到自己啦!");
Pos(13, 14);
printf("你的游戏得分为: %d", score);
exit(0);//终止退出游戏
}
void gamecircle()
{
Pos(57, 4);
printf("操作说明");
Pos(57, 5);
printf("w a s d分别对应上 左 下 右 ");
Pos(57, 6);
printf("按空格键暂停");
while (1)
{
Pos(57, 7);
printf("游戏分数:%d", score);
if (_kbhit())
key = _getch();
switch (key)
{
case Key_Right:
if (Status != L)
Status = R;
break;
case Key_Left:
if (Status != R)
Status = L;
break;
case Key_Up:
if (Status != D)
Status = W;
break;
case Key_Down:
if (Status != W)
Status = D;
break;
case Key_Space:
pause();
break;
default:
break;
}
Sleep(150);
SnakeMoving();
}
}
void Welcome()
{
Pos(27, 13);
printf("欢迎来到贪吃蛇游戏");
system("pause");//等待输入
system("cls");//清屏
/* Pos(50,9);
printf("欢迎大家对源代码进行修改");
Pos(50,11);
printf("开发出更多好玩的玩法");*/
Pos(50, 12);
system("pause");
system("cls");
}
void pause()//暂停
{
while (1)
{
if ((key = getchar()) == ' ')
break;
}
}
int main()
{
Welcome();
CreatMap();
CreatFood();
InitSnake();
gamecircle();
return 0;
}
这个代码使用链表实现,没有带头节点。
基本思路为用POS控制光标的位置进行打印地图打印蛇的操作。
蛇食物与地图的生成
地图:循环+pos(不用在意重复)
食物:随机数;
蛇:链表+p遍历与光标pos结合打印;
蛇的移动
用链表首节点表示蛇的头,每次根据移动方向在头的前方创建一个新的节点表示作为新的蛇头表示蛇移动了
每次移动循环之前判断是否导致游戏结束。
比如如果处于墙体边缘,即将生成一个新节点但会撞墙就不用了,所以放在前边。
如果碰到了食物,也就是坐标相等,首节点head坐标==食物 坐标,就遍历,p!=NULL,打印@
如果没有碰到,用p->next->next!=NULL,当最后时会“新”打印出3个(本身有4个),这样会有2个重叠 ,上面吃到是4个重叠。但是重叠没关系。 也就是1234 345,34重叠。然后跳出循环时在2的位置,再用p->next打印一个空格,掩盖@。
重叠是没关系的!!!
游戏进行
初始状态定义向右,各个移动方向可以用枚举来定义,目前状态states上下左右1234(用于进行蛇的移动),define键盘输入 wsad空格; 用switch接受key
用一个while(1)循环,里面在边上打印处printf分数 %d(进程是时刻变化的)
键盘输入接受key
if (_kbhit())
key = _getch();
对应deifine处不同事件,然后相应的改变states,
再用sleep()控制蛇的速度
再用上面的moving函数来对应states进行移动
游戏结束
endstates
1:撞墙 边缘坐标判断
2:撞到自己 从第二个遍历到最后,如果坐标和首节点相同 :因为是头部在移动,撞是头撞
0:正常
结束则清屏打印分数一类

171

被折叠的 条评论
为什么被折叠?



