///////////////////////////////////////////////////
// 程序名称:迷宫 游戏
// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版
// 作 者:krissi <zhaoh1987@qq.com>
// 最后修改:2011-3-12
//
#include <graphics.h>
#include <conio.h>
#include <time.h>
//////////////////////////////////////////////////////
// 定义全局变量
//
BYTE** g_imgMap = NULL; // 迷宫地图
SIZE g_szMap; // 迷宫地图的尺寸
IMAGE g_imgSight(360, 280); // 游戏的视野
RECT g_rtSight; // 游戏的视野的范围
IMAGE g_imgItem(180, 20); // 地图元素
IMAGE g_imgGPS; // 迷你地图,用于显示游戏者在地图中的位置
POINT g_ptGPS; // 迷你地图的显示位置
SIZE g_szGPS; // 迷你地图的尺寸
POINT g_ptPlayer; // 游戏者的位置
// 枚举地图元素,兼做元素位置的 x 坐标
enum MAPITEM { MAP_WALL = 0, MAP_PLAYER = 20, MAP_GROUND = 40, MAP_MARKRED = 60, MAP_MARKGREEN = 80, MAP_MARKYELLOW = 100, MAP_ENTRANCE = 120, MAP_EXIT = 140, MAP_OUTSIDE = 160 };
// 枚举用户的控制命令
enum CMD { CMD_QUIT = 1, CMD_UP = 2, CMD_DOWN = 4, CMD_LEFT = 8, CMD_RIGHT = 16, CMD_MARKRED = 32, CMD_MARKGREEN = 64, CMD_MARKYELLOW = 128, CMD_CLEARMARK = 256 };
//////////////////////////////////////////////////////
// 函数声明
//
void Welcome(); // 绘制游戏界面
void InitImage(); // 初始化游戏图片
void InitGame(); // 初始化游戏数据
void GetMazeSize(); // 提示用户输入迷宫大小
void MakeMaze(int width, int height); // 生成迷宫:初始化(注:宽高必须是奇数)
void TravelMaze(int x, int y); // 生成迷宫:遍历 (x, y) 四周
MAPITEM GetMazeItem(int x, int y); // 获取指定坐标的迷宫元素
void Paint(); // 绘制视野范围内的迷宫
int GetCmd(int* c); // 获取用户输入的命令
void DispatchCmd(int cmd); // 处理用户输入的命令
void OnUp(); // 向上移动
void OnLeft(); // 向左移动
void OnRight(); // 向右移动
void OnDown(); // 向下移动
void OnMark(MAPITEM value); // 在地图中做标记
bool CheckWin(); // 检查是否到出口
bool Quit(); // 询问用户是否退出游戏
//////////////////////////////////////////////////////
// 函数定义
//
// 主程序
void main()
{
// 初始化
initgraph(640, 480); // 创建绘图窗口
srand((unsigned)time(NULL)); // 设置随机种子
// 显示主界面
Welcome();
// 初始化
InitImage();
InitGame();
// 游戏过程
int c;
while( !((GetCmd(&c) == CMD_QUIT) && Quit()) )
{
DispatchCmd(c);
Paint();
if (CheckWin())
break;
// 延时
Sleep(100);
}
// 清理迷宫地图占用的内存
for(int x = 0; x < g_szMap.cx + 2; x++)
delete[] g_imgMap[x];
delete [] g_imgMap;
// 关闭图形模式
closegraph();
}
// 绘制游戏界面
void Welcome()
{
// 绘制渐变色外框
for(int i=0; i<128; i++)
{
setcolor(RGB(0, 0, (127 - i) << 1));
rectangle(149 - i, 109 - (i >> 1), 490 + i, 370 + (i >> 1));
}
// 设置字体样式
setcolor(WHITE);
setbkmode(TRANSPARENT);
// 绘制标题
setfont(36, 0, "宋体");
outtextxy(248, 40, "迷 宫");
// 绘制操作说明
setfont(12, 0, "宋体");
outtextxy(50, 382, "控制说明:");
outtextxy(74, 400, "方向键或 A/S/D/W:移动");
outtextxy(74, 418, "空格、Y、G:在地图上做红、黄、绿色 M 标记");
outtextxy(74, 436, "C:清除地图上的标记");
outtextxy(74, 454, "ESC:退出程序");
}
// 初始化游戏图片
void InitImage()
{
// 预绘制游戏图片到 IMAGE 缓存(可以修改为加载图片以获得更好效果)
SetWorkingImage(&g_imgItem);
cleardevice();
// 绘制 PLAYER
setorigin(MAP_PLAYER, 0);
setfillstyle(YELLOW);
setcolor(YELLOW);
fillellipse(2, 2, 17, 17);
setcolor(BLACK);
line(7, 7, 7, 8);
line(12, 7, 12, 8);
arc(5, 6, 14, 14, 3.34, 6.08);
// 绘制墙壁
setorigin(MAP_WALL, 0);
setfillstyle(BROWN, PATTERN_FILL, "\x20\x20\x20\xff\x04\x04\x04\xff");
setcolor(BROWN);
bar(1, 1, 18, 18);
rectangle(0, 0, 19, 19);
// 绘制红色标记
setorigin(MAP_MARKRED, 0);
setcolor(RED);
moveto(5, 15);
linerel(0, -10); linerel(5, 5); linerel(5, -5); linerel(0, 10);
// 绘制绿色标记
setorigin(MAP_MARKGREEN, 0);
setcolor(GREEN);
moveto(5, 15);
linerel(0, -10); linerel(5, 5); linerel(5, -5); linerel(0, 10);
// 绘制黄色标记
setorigin(MAP_MARKYELLOW, 0);
setcolor(YELLOW);
moveto(5, 15);
linerel(0, -10); linerel(5, 5); linerel(5, -5); linerel(0, 10);
// 绘制入口
setorigin(MAP_ENTRANCE, 0);
setcolor(GREEN);
setfont(12, 0, "宋体");
outtextxy(4, 4, "入");
// 绘制出口
setorigin(MAP_EXIT, 0);
outtextxy(4, 4, "出");
// 绘制迷宫外面的空地
setorigin(MAP_OUTSIDE, 0);
setfillstyle(GREEN, PATTERN_FILL, "\x50\x55\x22\x20\x05\x55\x22\x02");
bar(0, 0, 19, 19);
// 恢复坐标系
setorigin(0, 0);
// 显示作者
SetWorkingImage();
setcolor(BLUE);
char author[] = "Powered by zhaoh1987@qq.com";
outtextxy(471, 4, author);
setcolor(LIGHTBLUE);
outtextxy(470, 3, author);
}
// 初始化游戏数据
void InitGame()
{
// 提示用户输入迷宫大小
GetMazeSize();
// 初始化参数
if (g_imgMap != NULL)
{ // 清理迷宫地图占用的内存
for(int x = 0; x < g_szMap.cx + 2; x++)
delete[] g_imgMap[x];
delete [] g_imgMap;
}
MakeMaze(g_szMap.cx, g_szMap.cy); // 创建迷宫
g_ptPlayer.x = 2; // 设置游戏者的位置
g_ptPlayer.y = 2;
g_rtSight.left = 0; // 设置视野范围
g_rtSight.top = 0;
g_rtSight.right = 17;
g_rtSight.bottom= 13;
// 设置 GPS 显示区
setfillstyle(BLUE);
bar(522, 368, 637, 471);
if (g_szMap.cx > g_szMap.cy) { g_szGPS.cx = 100; g_szGPS.cy = (int)(100.0 * g_szMap.cy / g_szMap.cx + 0.5); }
else { g_szGPS.cy = 100; g_szGPS.cx = (int)(100.0 * g_szMap.cx / g_szMap.cy + 0.5); }
Resize(&g_imgGPS, g_szGPS.cx, g_szGPS.cy);
g_ptGPS.x = 530 + 50 - g_szGPS.cx / 2;
g_ptGPS.y = 370 + 50 - g_szGPS.cy / 2;
// 画迷你地图外框
setcolor(RED);
rectangle(g_ptGPS.x - 1, g_ptGPS.y - 1, g_ptGPS.x + g_szGPS.cx, g_ptGPS.y + g_szGPS.cy);
// 画迷你地图入口和出口
setcolor(YELLOW);
moveto(g_ptGPS.x - 8, g_ptGPS.y + g_szGPS.cy / g_szMap.cy);
linerel(7, 0); linerel(-3, -3); moverel(3, 3); linerel(-3, 3);
moveto(g_ptGPS.x + g_szGPS.cx, g_ptGPS.y + g_szGPS.cy - g_szGPS.cy / g_szMap.cy);
linerel(7, 0); linerel(-3, -3); moverel(3, 3); linerel(-3, 3);
// 绘制游戏区
Paint();
}
// 提示用户输入迷宫大小
void GetMazeSize()
{
g_szMap.cx = g_szMap.cy = 0;
// 获取用户输入的宽高
char s[4];
while(g_szMap.cx < 20 || g_szMap.cx > 200)
{
InputBox(s, 4, "请输入迷宫的宽度\n范围:20~200", "输入", "25");
g_szMap.cx = atoi(s);
}
while(g_szMap.cy < 20 || g_szMap.cx > 200)
{
InputBox(s, 4, "请输入迷宫的高度\n范围:20~200", "输入", "25");
g_szMap.cy = atoi(s);
}
// 确保宽高为奇数
if (g_szMap.cx % 2 != 1) g_szMap.cx++;
if (g_szMap.cy % 2 != 1) g_szMap.cy++;
}
// 生成迷宫:初始化(注:宽高必须是奇数)
void MakeMaze(int width, int height)
{
if (width % 2 != 1 || height % 2 != 1)
return;
int x, y;
// 定义迷宫尺寸,并分配迷宫内存
g_imgMap = new BYTE*[width + 2];
for(x = 0; x < width + 2; x++)
{
g_imgMap[x] = new BYTE[height + 2];
memset(g_imgMap[x], MAP_WALL, height + 2);
}
// 定义边界
for (x = 0; x <= width + 1; x++)
g_imgMap[x][0] = g_imgMap[x][height + 1] = MAP_GROUND;
for (y = 1; y <= height; y++)
g_imgMap[0][y] = g_imgMap[width + 1][y] = MAP_GROUND;
// 定义入口和出口
g_imgMap[1][2] = MAP_ENTRANCE;
g_imgMap[width][height - 1] = MAP_EXIT;
// 从任意点开始遍历生成迷宫
TravelMaze(((rand() % (width - 1)) & 0xfffe) + 2, ((rand() % (height - 1)) & 0xfffe) + 2);
// 将边界标记为迷宫外
for (x = 0; x <= width + 1; x++)
g_imgMap[x][0] = g_imgMap[x][height + 1] = MAP_OUTSIDE;
for (y = 1; y <= height; y++)
g_imgMap[0][y] = g_imgMap[width + 1][y] = MAP_OUTSIDE;
}
// 生成迷宫:遍历 (x, y) 四周
void TravelMaze(int x, int y)
{
// 定义遍历方向
int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
// 将遍历方向乱序
int n, t, i;
for(i = 0; i < 4; i++)
{
n = rand() % 4;
t = d[i][0], d[i][0] = d[n][0], d[n][0] = t;
t = d[i][1], d[i][1] = d[n][1], d[n][1] = t;
}
评论20
最新资源