欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于C+EasyX实现的《魔塔》小游戏!献给那个还是孩子般的你!

程序员文章站 2022-03-06 14:30:15
...

游戏介绍:

  1. 键盘4个光标键控制 人物移动
  2. 怪物属性:生命值 (怪物可法移动)
  3. 玩家属性:生命值 攻击力 防御力
  4. 拿到相应的钥匙直到终点 方可结束

游戏思路解析:

  1. 地图元素由数组存储 地图元素数字化
  2. 人物行走 判断所遇到的 元素 (所有可能性)
  3. 拿到钥匙才可以打开门
  4. 判断到达终点 结点游戏

素材准备如下:
基于C+EasyX实现的《魔塔》小游戏!献给那个还是孩子般的你!
想要素材的小伙伴可以私聊我 . . .
.

游戏效果如下所示:

小游戏制作魔塔


代码如下所示:

#include <graphics.h>
#include <iostream>
#include <vector>
#include <conio.h>

#include <mmsystem.h>
#pragma comment (lib,"winmm")	


class Magic_Towers
{
private:

	IMAGE img[10];		//存储图片元素

	static const int size = 13;		//数组元素行列大小

	static const int WIDTH = 700;		//界面大小
	static const int HEIGHT = 520;

	//0 - 墙1     1 - 墙2       2 - 红水		 3 - 蓝水   4 - 钥匙    5 - 门   
	//6 - 怪物      7 - 空地	    8 - 玩家***   9 - 终点

	//地图元素符号化
	int arr[size][size] = {
			{0,0,0,0,0,0,0,0,0,0,0,0,0},
			{0,2,2,4,0,1,1,1,2,7,1,7,0},
			{0,7,7,1,6,1,7,1,7,7,1,7,0},
			{0,1,7,7,6,6,7,7,5,7,6,6,0},
			{0,7,7,1,7,1,7,1,7,1,1,1,0},
			{0,8,1,1,7,1,9,1,7,7,7,7,0},
			{0,7,1,7,6,1,1,1,1,7,1,1,0},
			{0,7,6,7,1,1,7,7,6,7,5,2,0},
			{0,3,1,7,7,7,7,1,3,1,1,1,0},
			{0,7,1,5,1,7,1,1,7,1,7,4,0},
			{0,7,5,4,1,7,7,7,7,6,7,3,0},
			{0,0,0,0,0,0,0,0,0,0,0,0,0}
	};

	//游戏人物玩家的性质及属性
	int pEo_x = 5, pEo_y = 1;		//位置
	int vItality = 600;			//生命力
	int aTtack = 600;				//攻击力

	int kEy_count = 0;				//钥匙数量   为2放可结束游戏

	int Fz = 1;			//用于标记移动元素判断 

	//怪物的性质及属性
	struct Monster_Coord	//怪物的坐标
	{
		int x;
		int y;
		int vitality = 500;			//默认生命力   攻击力
		int phylactic = 200;
	};

	std::vector<Monster_Coord> monster_arr;			//用来存储几个怪物
	int mOnster_count = 0;			//怪物数量

public:
	Magic_Towers() {}
	~Magic_Towers() {}


	void InitDraw()const;		//数据初始化		开始界面  音乐
	void LoadPic();				//加载资源	
	void PrintMap()const;		//打印地图
	void ScanMonster();			//扫描怪物 并存储数据
	void PrintText()const;		//打印文字数据


	void JudgeUp();				//判断上路
	void JudgeLeft();			//判断左路
	void JudgeRight();			//判断右路
	void JudgeDown();			//判断下路

	void PeopleMove();			//玩家移动
};




int main()
{
	Magic_Towers mag;

	mag.InitDraw();		//初始画
	mag.LoadPic();		//加载资源
	mag.PrintMap();		//打印地图
	mag.PrintText();	//打印文字数据
	mag.ScanMonster();	//扫描怪物位置 并存储

	while (1)
	{
		if (_kbhit())		//判断是否按下键值
		{
			mag.PeopleMove();

			mag.PrintMap();
		}
	}

	return 0;
}


void Magic_Towers::InitDraw()const
{
	initgraph(WIDTH, HEIGHT);

	mciSendString("play bj.mp3 repeat", 0, 0, 0);

	setbkcolor(RGB(80, 80, 80));
	cleardevice();
	settextstyle(50, 25, "楷体");
	outtextxy(WIDTH / 2 - 80, HEIGHT / 2 - 180, "魔 塔");

	settextstyle(28, 14, "楷体");
	outtextxy(WIDTH / 2 - 75, HEIGHT / 2, "开始游戏");

	//	rectangle(WIDTH / 2 - 75, HEIGHT / 2, WIDTH / 2 - 75 + 113, HEIGHT / 2 + 28);


	MOUSEMSG msg;		//


	while (1)
	{
		msg = GetMouseMsg();

		//鼠标落在范围内变颜色
		if (msg.x - (WIDTH / 2 - 75) < 113 && msg.x - (WIDTH / 2 - 75) > 0 &&
			msg.y - (HEIGHT / 2) < 28 && msg.y - (HEIGHT / 2) > 0)
		{
			if (msg.mkLButton)break;

			settextcolor(RGB(0, 255, 255));
			outtextxy(WIDTH / 2 - 75, HEIGHT / 2, "开始游戏");
		}
		else
		{
			settextcolor(WHITE);
			outtextxy(WIDTH / 2 - 75, HEIGHT / 2, "开始游戏");
		}

	}

}

void Magic_Towers::LoadPic()
{

	char buf[32];

	for (int i = 0; i < 10; i++)
	{
		memset(buf, 0, sizeof(buf));

		sprintf(buf, "魔塔素材\\%d.jpg", i);

		loadimage(&img[i], buf, 40, 40);
	}

}


void Magic_Towers::PrintMap()const
{
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size; j++)
		{
			putimage(j * 40, i * 40, &img[arr[i][j]]);
		}
	}

}


void Magic_Towers::ScanMonster()		//扫描元素为 6的怪物
{
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < size; j++)
		{
			if (arr[i][j] == 6)
			{
				monster_arr.push_back({ i,j });		//保存怪物的位置

				mOnster_count++;	//数量 +1
			}

		}
	}
}


void Magic_Towers::PrintText()const
{

	char buf[32];

	clearrectangle(WIDTH - 170, 80, WIDTH, 120);
	sprintf(buf, "生命力:%d", vItality);
	outtextxy(WIDTH - 170, 80, buf);

	sprintf(buf, "攻击力:%d", aTtack);
	outtextxy(WIDTH - 170, 140, buf);

	sprintf(buf, "钥匙:%d", kEy_count);
	outtextxy(WIDTH - 170, 200, buf);

}

void Magic_Towers::JudgeUp()
{
	if (arr[pEo_x - 1][pEo_y] == 7)		//空地的情况
	{
		arr[pEo_x - 1][pEo_y] += 1;
		arr[pEo_x][pEo_y] -= Fz;

		Fz = 1;
		pEo_x -= 1;
		return;
	}

	if (arr[pEo_x - 1][pEo_y] == 2 || arr[pEo_x - 1][pEo_y] == 3)		//红蓝药水
	{
		arr[pEo_x - 1][pEo_y] == 2 ? vItality += 200 : aTtack += 100;		//增加生命力 攻击力  
		PrintText();

		arr[pEo_x - 1][pEo_y] += 8 - arr[pEo_x - 1][pEo_y];
		arr[pEo_x][pEo_y] -= Fz;

		Fz = 1;
		pEo_x -= 1;


		return;
	}

	if (arr[pEo_x - 1][pEo_y] == 4)		//钥匙
	{
		arr[pEo_x - 1][pEo_y] += 8 - arr[pEo_x - 1][pEo_y];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_x -= 1;

		kEy_count += 1;
		PrintText();

		return;
	}

	if (arr[pEo_x - 1][pEo_y] == 5 && kEy_count >= 1)
	{
		arr[pEo_x - 1][pEo_y] += 8 - arr[pEo_x - 1][pEo_y];
		arr[pEo_x][pEo_y] -= 1;

		pEo_x -= 1;

		Fz = 3;

		return;
	}

	if (arr[pEo_x - 1][pEo_y] == 6)
	{
		char buf[32];
		for (int i = 0; i < mOnster_count; i++)	//扫描是哪一个怪物
		{
			if (pEo_x - 1 == monster_arr[i].x && pEo_y == monster_arr[i].y)
			{
				while (monster_arr[i].vitality > 0)
				{
					clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);
					sprintf(buf, "怪物:%d", monster_arr[i].vitality);
					outtextxy(WIDTH - 170, 280, buf);

					monster_arr[i].vitality -= aTtack / (rand() % 10 + 6);

					Sleep(500);

					vItality -= monster_arr[i].phylactic / (rand() % 10 + 6);

					PrintText();
					Sleep(500);
				}

				clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);

				arr[pEo_x - 1][pEo_y] += 2;
				arr[pEo_x][pEo_y] -= 1;

				pEo_x -= 1;

				monster_arr.erase(monster_arr.begin() + i);
				break;
			}


		}

		return;
	}

	if (arr[pEo_x - 1][pEo_y] == 9 && kEy_count == 3)
	{
		arr[pEo_x - 1][pEo_y] += 8 - arr[pEo_x - 1][pEo_y];

		arr[pEo_x][pEo_y] -= 1;

		PrintMap();

		MessageBox(nullptr, "      Game Over!", "Magic Towers", MB_OK);

		exit(0);
	}

}
void Magic_Towers::JudgeLeft()
{
	if (arr[pEo_x][pEo_y - 1] == 7)		//空地的情况
	{
		arr[pEo_x][pEo_y - 1] += 1;
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;

		pEo_y -= 1;
		return;
	}

	if (arr[pEo_x][pEo_y - 1] == 2 || arr[pEo_x][pEo_y - 1] == 3)		//红药水
	{
		arr[pEo_x][pEo_y - 1] == 2 ? vItality += 200 : aTtack += 100;		//增加攻击力
		PrintText();



		arr[pEo_x][pEo_y - 1] += 8 - arr[pEo_x][pEo_y - 1];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_y -= 1;

		return;
	}
	if (arr[pEo_x][pEo_y - 1] == 4)
	{
		arr[pEo_x][pEo_y - 1] += 8 - arr[pEo_x][pEo_y - 1];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_y -= 1;

		kEy_count += 1;
		PrintText();

		return;
	}
	if (arr[pEo_x][pEo_y - 1] == 5 && kEy_count >= 1)
	{
		arr[pEo_x][pEo_y - 1] += 8 - arr[pEo_x][pEo_y - 1];
		arr[pEo_x][pEo_y] -= 1;

		pEo_y -= 1;

		Fz = 3;

		return;
	}

	if (arr[pEo_x][pEo_y - 1] == 6)
	{
		char buf[32];
		for (int i = 0; i < mOnster_count; i++)	//扫描是哪一个怪物
		{
			if (pEo_x == monster_arr[i].x && pEo_y - 1 == monster_arr[i].y)
			{
				while (monster_arr[i].vitality > 0)
				{
					clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);
					sprintf(buf, "怪物:%d", monster_arr[i].vitality);
					outtextxy(WIDTH - 170, 280, buf);

					monster_arr[i].vitality -= aTtack / (rand() % 10 + 6);

					Sleep(500);

					vItality -= monster_arr[i].phylactic / (rand() % 10 + 6);

					PrintText();
					Sleep(500);
				}

				clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);

				arr[pEo_x][pEo_y - 1] += 2;
				arr[pEo_x][pEo_y] -= 1;

				pEo_y -= 1;

				monster_arr.erase(monster_arr.begin() + i);
				break;
			}


		}

		return;
	}

	if (arr[pEo_x][pEo_y - 1] == 9 && kEy_count == 3)
	{
		arr[pEo_x][pEo_y - 1] += 8 - arr[pEo_x][pEo_y - 1];

		arr[pEo_x][pEo_y] -= 1;
		PrintMap();
		MessageBox(nullptr, "      Game Over!", "Magic Towers", MB_OK);

		exit(0);
	}
}
void Magic_Towers::JudgeRight()
{
	if (arr[pEo_x][pEo_y + 1] == 7)		//空地的情况
	{
		arr[pEo_x][pEo_y + 1] += 1;
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;

		pEo_y += 1;
		return;
	}

	if (arr[pEo_x][pEo_y + 1] == 2 || arr[pEo_x][pEo_y + 1] == 3)		//红药水
	{
		arr[pEo_x][pEo_y + 1] == 2 ? vItality += 200 : aTtack += 100;		//增加攻击力
		PrintText();


		arr[pEo_x][pEo_y + 1] += 8 - arr[pEo_x][pEo_y + 1];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_y += 1;


		return;
	}

	if (arr[pEo_x][pEo_y + 1] == 4)
	{
		arr[pEo_x][pEo_y + 1] += 8 - arr[pEo_x][pEo_y + 1];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_y += 1;

		kEy_count += 1;
		PrintText();

		return;
	}

	if (arr[pEo_x][pEo_y + 1] == 5 && kEy_count >= 1)
	{
		arr[pEo_x][pEo_y + 1] += 8 - arr[pEo_x][pEo_y + 1];
		arr[pEo_x][pEo_y] -= 1;

		pEo_y += 1;

		Fz = 3;

		return;
	}
	if (arr[pEo_x][pEo_y + 1] == 6)
	{
		char buf[32];
		for (int i = 0; i < mOnster_count; i++)	//扫描是哪一个怪物
		{
			if (pEo_x == monster_arr[i].x && pEo_y + 1 == monster_arr[i].y)
			{
				while (monster_arr[i].vitality > 0)
				{
					clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);
					sprintf(buf, "怪物:%d", monster_arr[i].vitality);
					outtextxy(WIDTH - 170, 280, buf);

					monster_arr[i].vitality -= aTtack / (rand() % 10 + 6);

					Sleep(500);

					vItality -= monster_arr[i].phylactic / (rand() % 10 + 6);

					PrintText();
					Sleep(500);
				}

				clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);

				arr[pEo_x][pEo_y + 1] += 2;
				arr[pEo_x][pEo_y] -= 1;

				pEo_y += 1;

				monster_arr.erase(monster_arr.begin() + i);
				break;
			}


		}

		return;
	}
	if (arr[pEo_x][pEo_y + 1] == 9 && kEy_count == 3)
	{
		arr[pEo_x][pEo_y + 1] += 8 - arr[pEo_x][pEo_y + 1];

		arr[pEo_x][pEo_y] -= 1;
		PrintMap();
		MessageBox(nullptr, "      Game Over!", "Magic Towers", MB_OK);

		exit(0);
	}
}

void Magic_Towers::JudgeDown()
{
	if (arr[pEo_x + 1][pEo_y] == 7)		//空地的情况
	{
		arr[pEo_x + 1][pEo_y] += 1;
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;

		pEo_x += 1;
		return;
	}
	if (arr[pEo_x + 1][pEo_y] == 2 || arr[pEo_x + 1][pEo_y] == 3)		//红药水
	{
		arr[pEo_x + 1][pEo_y] == 2 ? vItality += 200 : aTtack += 100;		//增加攻击力
		PrintText();

		arr[pEo_x + 1][pEo_y] += 8 - arr[pEo_x + 1][pEo_y];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_x += 1;
		return;
	}
	if (arr[pEo_x + 1][pEo_y] == 4)
	{
		arr[pEo_x + 1][pEo_y] += 8 - arr[pEo_x + 1][pEo_y];
		arr[pEo_x][pEo_y] -= Fz;
		Fz = 1;
		pEo_x += 1;

		kEy_count += 1;
		PrintText();
		return;
	}

	if (arr[pEo_x + 1][pEo_y] == 5 && kEy_count >= 1)
	{
		arr[pEo_x + 1][pEo_y] += 8 - arr[pEo_x + 1][pEo_y];
		arr[pEo_x][pEo_y] -= 1;

		pEo_x += 1;

		Fz = 3;

		return;
	}

	if (arr[pEo_x + 1][pEo_y] == 6)
	{
		char buf[32];
		for (int i = 0; i < mOnster_count; i++)	//扫描是哪一个怪物
		{
			if (pEo_x + 1 == monster_arr[i].x && pEo_y == monster_arr[i].y)
			{
				while (monster_arr[i].vitality > 0)
				{
					clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);
					sprintf(buf, "怪物:%d", monster_arr[i].vitality);
					outtextxy(WIDTH - 170, 280, buf);

					monster_arr[i].vitality -= aTtack / (rand() % 10 + 6);

					Sleep(500);

					vItality -= monster_arr[i].phylactic / (rand() % 10 + 6);

					PrintText();
					Sleep(500);
				}

				clearrectangle(WIDTH - 170, 280, WIDTH - 50, 320);

				arr[pEo_x + 1][pEo_y] += 2;
				arr[pEo_x][pEo_y] -= 1;

				pEo_x += 1;

				monster_arr.erase(monster_arr.begin() + i);
				break;
			}
		}
		return;
	}

	if (arr[pEo_x + 1][pEo_y] == 9 && kEy_count == 3)
	{
		arr[pEo_x + 1][pEo_y] += 8 - arr[pEo_x + 1][pEo_y];

		arr[pEo_x][pEo_y] -= 1;
		PrintMap();
		MessageBox(nullptr, "      Game Over!", "Magic Towers", MB_OK);

		exit(0);
	}
}


void Magic_Towers::PeopleMove()
{
	char ch = getch();

	switch (ch)
	{
	case 72:
		JudgeUp();
		break;
	case 75:
		JudgeLeft();
		break;
	case 77:
		JudgeRight();
		break;
	case 80:
		JudgeDown();
		break;
	}
}