这是一个贪吃蛇大作战类游戏,修改特性为 AI 不互杀;
该程序有四个类:蛇基类 SnakeBase,玩家类 Player,AI 类,Game 类;
SnakeBase 和 AI 均继承自 SnakeBase,SnakeBase 提供基础接口,Game 提供数据初始化以及游戏主循环。
程序设计之初,采用“实运行”方式,即所有动画均在地图 imgMap 上真实绘制,
这样却有一些严重的问题,需要不断地记录节点背景以恢复节点经过的地方等。
后修改为“虚运行”方式,判断位置是否可视后直接绘至窗口内,这样大大降低时间开销,同时不会因为蛇靠近而产生不可擦除的颜色。
至于蛇运行,采用位置继承,即节点下一个位置为上一个节点的位置,但是会发现跨度太大。
解决办法是在这个跨度中插入适当帧数。
执行效果如下:
还准备了许多项目源码和素材以及学习资源!
需要的可以戳一戳文末下方的链接申请下载哦~
源代码
// 头文件 //
#include <easyx.h>
#include <conio.h>
#include <cstdio>
#include <ctime>
#include <cmath>
#pragma comment( lib, "MSIMG32.LIB")
// 窗口大小 //
const short ScreenWidth = 640;
const short ScreenHeight = 480;
// 全局变量 //
long ret = 0;
MOUSEMSG msg;
const short gap = 20;
const short xSide = ScreenWidth / 2 + gap;
const short ySide = ScreenHeight / 2 + gap;
IMAGE* imgMap = new IMAGE(ScreenWidth * 4, ScreenHeight * 4);
const double PI = 3.1415926;
const short nodeSize = 17;
const short nodeGap = 16;
const short stepLen = 4;
const short frame = 4;
const short snakeSpecies = 20;
int killCount = 0;
int mapX = 0;
int mapY = 0;
typedef struct _FOOD
{
int x;
int y;
int r;
COLORREF c;
}Food;
Food* food;
short nFood = 520;
IMAGE imgFood(nodeSize, nodeSize);
const COLORREF mapMainColor = WHITE;
const COLORREF playerColor0 = RGB(120, 0, 0);
const COLORREF playerColor1 = RGB(200, 0, 0);
const COLORREF playerColor2 = RGB(255, 255, 0);
const COLORREF mapLineColor = RGB(225, 225, 225);
// 透明贴图函数:(更多内容请参考官网)
// 参数:
// x, y: 目标贴图位置
// srcimg: 源 IMAGE 对象指针。NULL 表示默认窗体
// dstimg: 目标 IMAGE 对象指针。NULL 表示默认窗体
// transparentcolor: 透明色。srcimg 的该颜色并不会复制到 dstimg 上,从而实现透明贴图
void putTimage(int x, int y, IMAGE* srcimg, IMAGE* dstimg = NULL, UINT transparentcolor = 0)
{
HDC dstDC = GetImageHDC(dstimg);
HDC srcDC = GetImageHDC(srcimg);
int w = srcimg->getwidth();
int h = srcimg->getheight();
// 使用 Windows GDI 函数实现透明位图
TransparentBlt(dstDC, x, y, w, h, srcDC, 0, 0, w, h, transparentcolor);
}
// 蛇基类 //
class SnakeBase
{
public:
// 构造函数
SnakeBase()
{
Count++;
isDead = false;
length = 50 + rand() % 50;
nNode = length / 5;
maxNode = 9999;
imgHead = imgNode = imgTail = nullptr;
headNode = tailNode = nullptr;
nodeMsg = nullptr;
}
// 析构函数
virtual ~SnakeBase()
{
Count--;
Node* temp = headNode;
while (temp != nullptr)
{
headNode = headNode->nextNode;
delete temp;
temp = headNode;
}
delete imgHead, imgNode, imgTail;
if (nodeMsg != nullptr)
delete[] nodeMsg;
}
// 设置image
void SetImage(COLORREF headColor, COLORREF nodeColor, COLORREF tailColor)
{
imgHead = new IMAGE(nodeSize, nodeSize);
imgNode = new IMAGE(nodeSize, nodeSize);
imgTail = new IMAGE(nodeSize, nodeSize);
SetWorkingImage(imgHead);
setfillcolor(headColor);
solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
setfillcolor(tailColor);
solidcircle(nodeSize / 2, nodeSize / 2, 2);
SetWorkingImage(imgNode);
setfillcolor(nodeColor);
solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
SetWorkingImage(imgTail);
setfillcolor(tailColor);
solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
SetWorkingImage();
}
// 创建各节点
void Creat(int headX,