游戏介绍:
- 键盘4个光标键控制 人物移动
- 怪物属性:生命值 (怪物可法移动)
- 玩家属性:生命值 攻击力 防御力
- 拿到相应的钥匙直到终点 方可结束
游戏思路解析:
- 地图元素由数组存储 地图元素数字化
- 人物行走 判断所遇到的 元素 (所有可能性)
- 拿到钥匙才可以打开门
- 判断到达终点 结点游戏
游戏效果如下所示:
小游戏制作魔塔
#include
#include
#include
#include
#include
#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;
}
}