概述
C语言实现简易版贪吃蛇,通过移除蛇尾和打印新的蛇头来实现移动效果,可以避免刷新整个蛇身的闪屏现象。
下面分别是头文件和实现文件:
#ifndef SNAKE_H_INCLUDED
#define SNAKE_H_INCLUDED
/***************************************************
* 文件名:snake.h
* 描
述:定义游戏的核心方法及相关结构
* 创建人:777
* 日
期:2018-01-01
* 版
本:1.0
*
**************************************************/
#define MARGIN_X 25
//游戏界面左边距
#define up 'w'
//蛇的移动方向
#define down 's'
#define left 'a'
#define right 'd'
#define stop 'p'
/*
*蛇身结构
*/
typedef struct _snake{
int x;
//节点坐标
int y;
struct _snake * next;
}SNAKE;
//声明蛇头蛇尾
SNAKE *head,*tail;
/*
*食物结构
*/
struct Food
{
int x;
int y;
}food;
//声明蛇的移动速度和蛇长变量
int speed;
/*
*游戏欢迎界面
*/
void welcome();
/*
*显示地图
*/
void creatmap();
/*
*生成蛇
*/
void showsnake();
/*
*生成食物
*/
void creatfood();
/*
*游戏运行
*/
void playgame();
/*
*打印蛇身,参数为坐标和背景颜色
*/
void gotoprint(int x, int y,int a, int b);
/*
*清除一个点(蛇尾和食物)
*/
void gotodelete(int x, int y);
/*
*移动蛇
*/
void MovingBody(char click);
/*
*移动蛇身
*/
void ChangeBody(int a,int b);
/*
*吃屎
*/
void Eating();
/*
*结束判断
*/
int Judge();
/*
*结束游戏
*/
void gameover();
#endif // SNAKE_H_INCLUDED
#ifndef SNAKELIB_H_INCLUDED
#define SNAKELIB_H_INCLUDED
/***************************************************
* 文件名:GameLib.h
* 描
述:定义游戏中常用的控制台操作
* 创建人:777
* 日
期:2018-01-01
* 版
本:1.0
*
**************************************************/
/* 设置控制台窗口标题 */
void SetTitle(char * title);
/* 设置控制台窗口颜色 */
void SetColor(int, int);
/* 设置控制台窗口尺寸 */
void SetConsoleWindowSize(int width, int height);
/* 设置光标的x、y坐标-正常坐标轴 */
void SetPosition(int x, int y);
/* 清屏 */
void Clear(int X, int Y);
#endif // SNAKELIB_H_INCLUDED
/***************************************************
* 文件名:GameLib.c
* 描
述:GameLib.h的实现文件
* 创建人:777
* 日
期:2018-01-01
* 版
本:1.0
*
**************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <windows.h>
#include "snakeLib.h"
/*
*设置窗口标题
*/
void SetTitle(char * title)
{
SetConsoleTitle(title);
}
/*
*设置窗口颜色
*/
void SetColor(int ForeColor, int BackGroundColor)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
//获取当前窗口句柄
SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//设置颜色
}
/*
*设置窗口大小
*/
void SetConsoleWindowSize(int width, int height)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
//设置控制台窗口的缓冲区大小
COORD size = {width, height};
SetConsoleScreenBufferSize(handle, size);
//设置控制台窗口大小,最大坐标是缓冲区大小-1
SMALL_RECT rect = {0, 0, width-1, height-1};
SetConsoleWindowInfo(handle, 1, &rect);
}
/*
*设置光标位置
*/
void SetPosition(int x, int y)
{
COORD cursorPosition;
//光标的坐标
HANDLE handle;
//当前窗口句柄
handle = GetStdHandle(STD_OUTPUT_HANDLE);
cursorPosition.X = x;
//设置x、y坐标
cursorPosition.Y = y;
SetConsoleCursorPosition(handle, cursorPosition);
}
/*
*清屏函数,参数为开始的行数和列数
*/
void Clear(int X, int Y)
{
DWORD written;
COORD start;
//开始坐标
HANDLE handle;
//当前窗口句柄
handle = GetStdHandle(STD_OUTPUT_HANDLE);
start.X = X;
start.Y = Y;
FillConsoleOutputAttribute(handle, 15, 120*35, start, &written);
FillConsoleOutputCharacter(handle, ' ', 120*35, start, &written);
SetConsoleCursorPosition(handle, start);
}
#include "snake.h"
#include "snakeLib.h"
int main()
{
welcome();
creatmap();
creatfood();
playgame();
gameover();
return 0;
}
/***************************************************
* 文件名:snake.c
* 描
述:实现游戏的核心玩法
* 创建人:777
* 日
期:2018-01-01
* 版
本:1.0
*
**************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include "snake.h"
#include "snakeLib.h"
/*
*运行游戏
*/
void playgame()
{
char click;
//用户按键
while (1)
{
if (Judge()== 0) break;
//判断游戏是否结束
//kbhit()函数,检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
if (_kbhit()) click = _getch();
MovingBody(click);
Eating();
}
}
/*
*生成食物
*/
void creatfood()
{
srand((int)time(NULL));
lable:
food.y = rand() % 28 + 3;
food.x = rand() % 52 + MARGIN_X + 7;
if (food.x % 2 != 0)
{
food.x = food.x + 1;
}
SNAKE *judgement = head;
while (1)
//遍历排除蛇身重复
{
if (judgement->next == NULL) break;
if (food.x == judgement->x && food.y == judgement->y)
{
goto lable;
}
judgement = judgement->next;
}
gotoprint(food.x, food.y,7,0);
//参数分别是X,Y坐标和打印的背景颜色
}
/*
*打印游戏地图
*/
void creatmap()
{
int i;
for (i = 0; i<58; i += 2)//打印上下边框
{
gotoprint(i + MARGIN_X + 5, 2, 4,0);
gotoprint(i + MARGIN_X + 5, 32, 4,0);
}
for (i = 1; i < 30; i++)
{
gotoprint(0 + MARGIN_X + 5, i + 2, 4,0);
gotoprint(56 + MARGIN_X + 5, i + 2, 4,0);
}
//创建蛇头
head = (SNAKE*)malloc(sizeof(SNAKE));
head->x = 15 + MARGIN_X + 10;
head->y = 15;
gotoprint(head->x, head->y,10, 0);
//创建蛇尾
tail = (SNAKE*)malloc(sizeof(SNAKE));
//创建蛇身
SNAKE *body = (SNAKE*)malloc(sizeof(SNAKE));
body->x = 15 + MARGIN_X + 10;
body->y = 16;
head->next = body;
body->next = tail;
gotoprint(body->x, body->y,10, 0);
//head->next = tail;
tail->next = NULL;
tail->x = 15 + MARGIN_X + 10;
tail->y = 17;
gotoprint(tail->x, tail->y,10, 0);
}
/*
*游戏欢迎界面实现
*/
void welcome()
{
SetConsoleWindowSize(121, 36);
//设置窗口大小
SetTitle("贪吃蛇1.0");
//设置标题
SetPosition(MARGIN_X,10);
/*欢迎界面
*/
printf("/***************************************************************/");
SetPosition(MARGIN_X, 20);
printf("/***************************************************************/");
SetPosition(MARGIN_X + 18, 13);
printf("欢迎来到贪吃蛇小游戏");
SetPosition(MARGIN_X, 16);
printf("请在英文输入法中操作,wasd控制蛇移动方向,反向移动等同于吃到自己,其他键暂停游戏");
SetPosition(MARGIN_X + 20, 18);
printf("按任意键开始游戏");
_getch();
Clear(0,0);
}
/*
*打印蛇身
*/
void gotoprint(int x, int y, int a,int b)
{
SetColor(a, b);
SetPosition(x, y);
printf("■");
}
/*
*清除一个点(蛇尾和食物)
*/
void gotodelete(int x, int y)
{
SetPosition(x, y);
printf("
");
}
/*
*判断游戏是否结束
*/
int Judge()
{
if (head->x == (MARGIN_X + 5)|| head->x == (MARGIN_X +61) || head->y == 2 || head->y == 32)
{
return 0;
}
SNAKE *p = head->next;
while (1)
{
//通过遍历蛇身坐标,与蛇头坐标对比,判断蛇头是否撞到蛇身
if (head->x == p->x && head->y == p->y)
{
return 0;
}
if (p->next == NULL) break; //遍历完成退出循环
p = p->next;
}
return 1;
}
/*
*移动蛇,参数为用户按键
*/
void MovingBody(char click)
{
int count = 0;
//记录蛇长
int a = head->x, b = head->y;
//记录蛇头坐标
SNAKE *p = head;
//通过清除蛇尾实现动画效果,注意在运动转态才清除蛇尾,暂停时不清除
if(click == up || click == down || click == right || click == left)
{
while (1)
{
count++;
if (p->next == NULL)
{
gotodelete(p->x, p->y);
break;
}
p = p->next;
}
}
switch (click)
{
case up:
head->y -= 1;
ChangeBody(a,b);
break;
case down:
head->y += 1;
ChangeBody(a,b);
break;
case left:
head->x -= 2;
ChangeBody(a,b);
break;
case right:
head->x += 2;
ChangeBody(a,b);
break;
default:
break;
}
//打印新的蛇头
p = head;
gotoprint(p->x, p->y,10,0);
if (count <= 10) speed = 150;
else if (count > 10 && count <= 20) speed = 100;
else if (count > 20 && count <= 40) speed = 50;
else speed = 10;
Sleep(speed);
}
/*
*移动蛇身
*/
void ChangeBody(int a,int b)
{
SNAKE *p = head->next;
int mid1, mid2,_mid1,_mid2;
mid1 = p->x;
mid2 = p->y;
while (1)
{
if (p->next == NULL) break;
_mid1 = p->next->x;
_mid2 = p->next->y;
p->next->x = mid1;
p->next->y = mid2;
mid1 = _mid1;
mid2 = _mid2;
p = p->next;
}
p = head->next;
p->x = a;
p->y = b;
}
/*
*吃屎
*/
void Eating()
{
if (head->x == food.x && head->y == food.y)
{
creatfood();
SNAKE * _new = (SNAKE*)malloc(sizeof(SNAKE));
_new->next = NULL;
SNAKE *p;
p = head;
while (1)
{
if (p->next == NULL) break;
p = p->next;
}
p->next = _new;
}
}
/*
*结束
*/
void gameover()
{
Clear(0,0);
SetPosition(MARGIN_X + 10,15);
SetColor(10,0);
printf("游戏结束!");
}
最后
以上就是繁荣水杯为你收集整理的贪吃蛇(C语言)2018-01-01的全部内容,希望文章能够帮你解决贪吃蛇(C语言)2018-01-01所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复