【游戏开发】简易实现回合制游戏
//Windows窗口头文件
#include <windows.h>
//使用swprintf_s函数所需的头文件
#include <tchar.h>
//使用获取系统时间time()函数需要包含的头文件
#include <time.h>
//PlaySound函数所需库文件
#pragma comment(lib,"winmm.lib")
//TransparentBlt函数所需的库文件
#pragma comment(lib,"Msimg32.lib")
//窗口宽度
#define WINDOW_WIDTH800
//窗口高度
#define WINDOW_HEIGHT600
//窗口标题
#define WINDOW_TITLEL"【游戏开发】简易实现回合制游戏"
//粒子数量
#define PARTICLE_NUMBER50
//角色结构体
struct CHARACTER
{
//当前生命值
intNowHp;
//最大生命值
intMaxHp;
//当前魔法值
intNowMp;
//最大魔法值
intMaxMp;
//角色等级
intLevel;
//角色力量值
intStrength;
//角色智力值
intIntelligence;
//角色敏捷值
intAgility;
};
//雪花粒子结构体
struct SNOW
{
//雪花的X坐标
int x;
//雪花的Y坐标
int y;
//雪花是否存在
BOOL exist;
};
//动作枚举体
enum ActionTypes
{
//普通攻击
ACTION_TYPE_NORMAL=0,
//致命一击
ACTION_TYPE_CRITICAL=1,
//魔法攻击
ACTION_TYPE_MAGIC=2,
//攻击落空
ACTION_TYPE_MISS=3,
//释放恢复魔法
ACTION_TYPE_RECOVER=4,
};
//全局环境设备,全局内存设备,全局缓存设备
HDCg_hdc=NULL,g_mdc=NULL,g_bufdc=NULL;
//上一次绘图时间,当前绘图时间
DWORDg_tPre=0,g_tNow=0;
//储存窗口区域坐标
RECTg_rect;
//帧数,文字数量
intg_iFrameNum,g_iTxtNum;
//存储输出文字
wchar_ttext[8][100];
//状态标志:角色是否可以攻击,游戏是否结束
BOOLg_bCanAttack,g_bGameOver;
//雪花粒子
SNOWSnowFlowers[PARTICLE_NUMBER];
//雪花的数量
intg_SnowNum=0;
//角色:英雄,BOSS
CHARACTERHero,Boss;
//动作:英雄动作,BOSS动作
ActionTypesHeroActionType,BossActionType;
//背景,游戏结束,游戏胜利,雪花
HBITMAPg_hBackGround,g_hGameOver,g_hVictory,g_hSnow;
//BOSS角色图,英雄角色图,恢复技能图的位图句柄
HBITMAPg_hMonsterBitmap,g_hHeroBitmap,g_hRecoverSkill;
//4个技能按钮
HBITMAPg_hSkillButton1,g_hSkillButton2,g_hSkillButton3,g_hSkillButton4;
//3个英雄技能效果
HBITMAPg_hHeroSkill1,g_hHeroSkill2,g_hHeroSkill3;
//3个BOSS技能效果
HBITMAPg_hBossSkill1,g_hBossSkill2,g_hBossSkill3;
//窗口过程函数
LRESULT CALLBACKWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
//初始化资源
BOOLGame_Init(HWND hwnd);
//绘图
VOIDGame_Main( HWND hwnd);
//清理资源
BOOLGame_ShutDown(HWND hwnd );
//死亡检查
VOIDDie_Check(int NowHp,bool isHero);
//文字消息处理
VOIDMessage_Insert(wchar_t* str);
//英雄动作逻辑
VOIDHeroAction_Logic();
//英雄动作绘图
VOIDHeroAction_Paint();
//怪物动作逻辑
VOIDBossAction_Logic();
//怪物动作绘图
VOIDBossAction_Paint();
//雪花粒子
VOIDSnow_Paint();
//主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
//定义窗口类
WNDCLASSEX wndClass = { 0 };
//结构体的字节数大小
wndClass.cbSize = sizeof( WNDCLASSEX ) ;
//设置窗口的样式
wndClass.style = CS_HREDRAW | CS_VREDRAW;
//设置指向窗口过程函数的指针
wndClass.lpfnWndProc = WndProc;
//窗口类的附加内存,取0就可以了
wndClass.cbClsExtra= 0;
//窗口的附加内存,依然取0就行了
wndClass.cbWndExtra= 0;
//指定包含窗口过程的程序的实例句柄
wndClass.hInstance = hInstance;
//图标
wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
//光标
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
//为hbrBackground成员指定一个白色画刷句柄
wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
//菜单资源的名字
wndClass.lpszMenuName = NULL;
//窗口类的名字
wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";
//注册窗口类
if( !RegisterClassEx( &wndClass ) )
return -1;
//创建窗口
HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
//移动窗口到(250,80)处
MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
//显示窗口
ShowWindow( hwnd, nShowCmd );
//更新窗口
UpdateWindow(hwnd);
//游戏资源的初始化,若初始化失败,弹出一个消息框,并返回FALSE
if (!Game_Init (hwnd))
{
//使用MessageBox函数,创建一个消息窗口
MessageBox(hwnd, L"资源初始化失败", L"消息窗口", 0);
return FALSE;
}
//循环播放背景音乐
PlaySound(L"GameMedia\\徐鲤 - 大理1.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP);
//定义并初始化msg
MSG msg = { 0 };
//消息循环过程
while( msg.message != WM_QUIT )
{
//查看应用程序消息队列,有消息时将队列中的消息派发出去。
if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{
//将虚拟键消息转换为字符消息
TranslateMessage( &msg );
//分发一个消息给窗口程序
DispatchMessage( &msg );
}
else
{
//获取当前系统时间
g_tNow = GetTickCount();
//当此次循环运行与上次绘图时间相差0.06秒时再进行重绘操作
if(g_tNow-g_tPre >= 60)
Game_Main(hwnd);
}
}
//窗口类的注销
UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance);
return 0;
}
//窗口过程函数
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
//按键消息
case WM_KEYDOWN:
//按下【Esc】键
if(wParam==VK_ESCAPE)
PostQuitMessage(0);
break;
//鼠标左键消息
case WM_LBUTTONDOWN:
if(!g_bCanAttack)
{
//X坐标
int x = LOWORD(lParam);
//Y坐标
int y = HIWORD(lParam);
if(x >= 530 && x <= 570 && y >=420 && y <= 470)
{g_bCanAttack = true;
HeroActionType=ACTION_TYPE_NORMAL;
}
if(x >= 590 && x <= 640 && y >=420 && y <= 470)
{
g_bCanAttack = true;
HeroActionType=ACTION_TYPE_MAGIC;
}
if(x >= 650 && x <= 700 && y >=420 && y <= 470)
{
g_bCanAttack = true;
HeroActionType=ACTION_TYPE_RECOVER;
}
}
break;
//窗口销毁
case WM_DESTROY:
//资源清理
Game_ShutDown(hwnd);
//向系统表明有个线程有终止请求。用来响应WM_DESTROY消息
PostQuitMessage( 0 );
break;
//缺省
default:
return DefWindowProc( hwnd, message, wParam, lParam );
}
return 0;
}
//游戏资源的初始化
BOOL Game_Init( HWND hwnd )
{
//用系统时间初始化随机种子
srand((unsigned)time(NULL));
HBITMAP bmp;
//三缓冲体系的创建
g_hdc = GetDC(hwnd);
//创建一个和hdc兼容的内存DC
g_mdc = CreateCompatibleDC(g_hdc);
//创建一个和hdc兼容的缓冲DC
g_bufdc = CreateCompatibleDC(g_hdc);
//创建一个和窗口兼容的空的位图对象
bmp = CreateCompatibleBitmap(g_hdc,WINDOW_WIDTH,WINDOW_HEIGHT);
//将空位图对象放到mdc中
SelectObject(g_mdc,bmp);
//载入一系列游戏资源图到位图句柄中
//游戏结束位图
g_hGameOver=(HBITMAP)LoadImage(NULL,L"GameMedia\\gameover.bmp",IMAGE_BITMAP,1086,396,LR_LOADFROMFILE);
//游戏胜利位图
g_hVictory=(HBITMAP)LoadImage(NULL,L"GameMedia\\victory.bmp",IMAGE_BITMAP,800,600,LR_LOADFROMFILE);
//背景位图
g_hBackGround = (HBITMAP)LoadImage(NULL,L"GameMedia\\bg.bmp",IMAGE_BITMAP,800,600,LR_LOADFROMFILE);
//怪物角色位图
g_hMonsterBitmap = (HBITMAP)LoadImage(NULL,L"GameMedia\\monster.bmp",IMAGE_BITMAP,360,360,LR_LOADFROMFILE);
//英雄角色位图
g_hHeroBitmap = (HBITMAP)LoadImage(NULL,L"GameMedia\\hero.bmp",IMAGE_BITMAP,360,360,LR_LOADFROMFILE);
//英雄1技能位图
g_hHeroSkill1=(HBITMAP)LoadImage(NULL,L"GameMedia\\heroslash.bmp",IMAGE_BITMAP,364,140,LR_LOADFROMFILE);
//英雄2技能位图
g_hHeroSkill2=(HBITMAP)LoadImage(NULL,L"GameMedia\\heromagic.bmp",IMAGE_BITMAP,374,288,LR_LOADFROMFILE);
//英雄3技能位图
g_hHeroSkill3=(HBITMAP)LoadImage(NULL,L"GameMedia\\herocritical.bmp",IMAGE_BITMAP,574,306,LR_LOADFROMFILE);
//技能1图标位图
g_hSkillButton1 = (HBITMAP)LoadImage(NULL,L"GameMedia\\skillbutton1.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);
//技能2图标位图
g_hSkillButton2= (HBITMAP)LoadImage(NULL,L"GameMedia\\skillbutton2.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);
//技能3图标位图
g_hSkillButton3= (HBITMAP)LoadImage(NULL,L"GameMedia\\skillbutton3.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);
//怪物1技能位图
g_hBossSkill1= (HBITMAP)LoadImage(NULL,L"GameMedia\\monsterslash.bmp",IMAGE_BITMAP,234,188,LR_LOADFROMFILE);
//怪物2技能位图
g_hBossSkill2= (HBITMAP)LoadImage(NULL,L"GameMedia\\monstermagic.bmp",IMAGE_BITMAP,387,254,LR_LOADFROMFILE);
//怪物3技能位图
g_hBossSkill3= (HBITMAP)LoadImage(NULL,L"GameMedia\\monstercritical.bmp",IMAGE_BITMAP,574,306,LR_LOADFROMFILE);
//雪花位图
g_hSnow = (HBITMAP)LoadImage(NULL,L"GameMedia\\snow.bmp",IMAGE_BITMAP,30,30,LR_LOADFROMFILE);
//恢复技能位图
g_hRecoverSkill = (HBITMAP)LoadImage(NULL,L"GameMedia\\recover.bmp",IMAGE_BITMAP,150,150,LR_LOADFROMFILE);
//取得内部窗口区域的大小
GetClientRect(hwnd,&g_rect);
//设定玩家的各项属性值
//设定玩家生命值的当前值及上限
Hero.NowHp = Hero.MaxHp = 1000;
//设定玩家角色等级
Hero.Level = 6;
//玩家魔法值的当前值及上限
Hero.NowMp=Hero.MaxMp=60;
//设定玩家的力量值
Hero.Strength = 10;
//设定玩家的敏捷值
Hero.Agility=20;
//设定玩家的智力值
Hero.Intelligence=10;
//设定BOSS的各项属性值
//设定BOSS生命值的当前值及上限
Boss.NowHp = Boss.MaxHp = 2000;
//设定BOSS的等级
Boss.Level = 10;
//设定BOSS的力量值
Boss.Strength = 10;
//设定BOSS的敏捷值
Boss.Agility=10;
//设定BOSS的智力值
Boss.Intelligence=10;
//初始化显示消息数目
g_iTxtNum = 0;
//设置字体
HFONT hFont;
hFont=CreateFont(20,0,0,0,700,0,0,0,GB2312_CHARSET,0,0,0,0,TEXT("微软雅黑"));
SelectObject(g_mdc,hFont);
//设置文字显示背景透明
SetBkMode(g_mdc, TRANSPARENT);
//调用一次游戏Main函数
Game_Main(hwnd);
return TRUE;
}
//游戏Main函数
VOID Game_Main( HWND hwnd )
{
wchar_t str[100];
//先在mdc中贴上背景图
SelectObject(g_bufdc,g_hBackGround);
BitBlt(g_mdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_bufdc,0,0,SRCCOPY);
//如果游戏未结束
if (!g_bGameOver)
{
//调用封装了雪花飞舞粒子效果的函数,模拟下雪场景
Snow_Paint();
}
//显示对战消息
SetTextColor(g_mdc,RGB(255,255,255));
for(int i=0;i<g_iTxtNum;i++)
TextOut(g_mdc,20,410+i*18,text[i],wcslen(text[i]));
//贴上怪物图以及显示怪物血量
if(Boss.NowHp>0)
{
//贴上怪物图
SelectObject(g_bufdc,g_hMonsterBitmap);
//采用TransparentBlt透明贴图函数
TransparentBlt(g_mdc,0,50,360,360,g_bufdc,0,0,360,360,RGB(0,0,0));
//显示怪物血量
swprintf_s(str,L"%d / %d",Boss.NowHp,Boss.MaxHp);
SetTextColor(g_mdc,RGB(255,10,10));
TextOut(g_mdc,100,370,str,wcslen(str));
}
//贴上玩家图以及玩家生命值,魔法值的显示
if(Hero.NowHp>0)
{
//贴上人物图
SelectObject(g_bufdc,g_hHeroBitmap);
//透明色为RGB(0,0,0)
TransparentBlt(g_mdc,400,50,360,360,g_bufdc,0,0,360,360,RGB(0,0,0));
//显示血量
swprintf_s(str,L"%d / %d",Hero.NowHp,Hero.MaxHp);
SetTextColor(g_mdc,RGB(255,10,10));
TextOut(g_mdc,600,350,str, wcslen(str));
//显示魔法值
swprintf_s(str,L"%d / %d",Hero.NowMp,Hero.MaxMp);
SetTextColor(g_mdc,RGB(10,10,255));
TextOut(g_mdc,600,370,str, wcslen(str));
}
//判断游戏是否结束
if(g_bGameOver)
{
//玩家阵亡,就贴出“gameover”图片
if(Hero.NowHp <= 0)
{
SelectObject(g_bufdc,g_hGameOver);
BitBlt(g_mdc,120,50,543,396,g_bufdc,543,0,SRCAND);
BitBlt(g_mdc,120,50,543,396,g_bufdc,0,0,SRCPAINT);
}
//怪物阵亡,就贴出“victory”图片
else
{
SelectObject(g_bufdc,g_hVictory);
//透明色为RGB(0,0,0)
TransparentBlt(g_mdc,0,0,800,600,g_bufdc,0,0,800,600,RGB(0,0,0));
}
}
//如果游戏没结束,且为玩家可攻击状态,便依次贴上技能图标
else if(!g_bCanAttack)
{
//贴上技能按钮
SelectObject(g_bufdc,g_hSkillButton1);
BitBlt(g_mdc,530,420,50,50,g_bufdc,0,0,SRCCOPY);
SelectObject(g_bufdc,g_hSkillButton2);
BitBlt(g_mdc,590,420,50,50,g_bufdc,0,0,SRCCOPY);
SelectObject(g_bufdc,g_hSkillButton3);
BitBlt(g_mdc,650,420,50,50,g_bufdc,0,0,SRCCOPY);
}
//游戏没结束,且为玩家不可攻击状态,便开始接下来的绘图
else
{
g_iFrameNum++;
//第5~10个画面时显示玩家攻击效果图
if(g_iFrameNum>=5 && g_iFrameNum<=10)
{
//第5个画面时根据之前的输入计算出游戏逻辑并进行消息显示
if(g_iFrameNum == 5)
{
HeroAction_Logic( );
Die_Check(Boss.NowHp,false);
}
//根据人物的动作类型进行相应贴图
HeroAction_Paint();
}
//第15个画面时判断怪物进行哪项动作
if(g_iFrameNum == 15)
{
BossAction_Logic();
}
//第26~30个画面时显示怪物攻击图标
if(g_iFrameNum>=26 && g_iFrameNum<=30)
{
BossAction_Paint();
}
//回合结束
if(g_iFrameNum == 30)
{
g_bCanAttack = false;
g_iFrameNum = 0;
//每回合的魔法自然恢复,6点固定值加上0到智力值之间的一个随机值的三倍
if(!g_bGameOver)
{
int MpRecover=2*(rand()%Hero.Intelligence)+6;
Hero.NowMp+=MpRecover;
if (Hero.NowMp>=Hero.MaxMp)
{
Hero.NowMp=Hero.MaxMp;
}
swprintf_s(str,L"回合结束,自动恢复了【%d】点魔法值",MpRecover);
Message_Insert(str);
}
}
}
//将mdc中的全部内容贴到hdc中
BitBlt(g_hdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_mdc,0,0,SRCCOPY);
//记录此次绘图时间
g_tPre = GetTickCount();
}
//对战消息
void Message_Insert(wchar_t* str)
{
//如果未满8行消息,直接新开一条消息
if(g_iTxtNum < 8)
{
swprintf_s(text[g_iTxtNum],str);
g_iTxtNum++;
}
//如果满了8行消息,只有挤走最上面的一条消息
else
{
for(int i=0;i<g_iTxtNum;i++)
swprintf_s(text[i],text[i+1]);
swprintf_s(text[7],str);
}
}
//生命值判断
void Die_Check(int NowHp,bool isHero)
{
wchar_t str[100];
//生命值小于等于0了
if(NowHp <= 0)
{
g_bGameOver = true;
//如果是英雄的生命值小于零,表示游戏失败
if(isHero)
{
//播放失败音乐
PlaySound(L"GameMedia\\failure.wav", NULL, SND_FILENAME | SND_ASYNC);
//输出失败提示语
swprintf_s(str,L": ( 胜败乃兵家常事,大侠请重新来过......");
//插入到文字消息中
Message_Insert(str);
}
else
{
//播放胜利音乐
PlaySound(L"GameMedia\\victory.wav", NULL, SND_FILENAME | SND_ASYNC);
//输出胜利提示语
swprintf_s(str,L"少年,你赢了,有两下子啊~~~~~!!!!");
//插入到文字消息中
Message_Insert(str);
}
}
}
//玩家动作逻辑判断函数
VOID HeroAction_Logic( )
{
int damage=0;
wchar_t str[100];
switch( HeroActionType)
{
case ACTION_TYPE_NORMAL:
//20%几率触发幻影刺客的大招,恩赐解脱,4倍暴击伤害
if (1==rand()%4)
{
HeroActionType=ACTION_TYPE_CRITICAL;
damage = (int)(4.5f*(float)(3*(rand()%Hero.Agility) + Hero.Level*Hero.Strength+20));
Boss.NowHp -= (int)damage;
swprintf_s(str,L"恩赐解脱触发,这下牛逼了,4.5倍暴击...对怪物照成了【%d】点伤害",damage);
}
//没有触发”恩赐解脱“,还是用普通攻击”无敌斩“
else
{
damage = 3*(rand()%Hero.Agility) + Hero.Level*Hero.Strength+20;
Boss.NowHp -= (int)damage;
swprintf_s(str,L"玩家圣殿骑士使用了普通攻击“无敌斩”,伤害一般般...对怪物照成了【%d】点伤害",damage);
}
Message_Insert(str);
break;
//释放烈火剑法
case ACTION_TYPE_MAGIC:
if(Hero.NowMp>=30)
{
damage = 5*(2*(rand()%Hero.Agility) + Hero.Level*Hero.Intelligence);
Boss.NowHp -= (int)damage;
Hero.NowMp-=30;
swprintf_s(str,L"玩家圣殿骑士释放烈火剑法...对怪物照成了【%d】点伤害",damage);
}
else
{
HeroActionType=ACTION_TYPE_MISS;
swprintf_s(str,L"你傻啊~!,魔法值不足30点,施法失败,这回合白费了~!");
}
Message_Insert(str);
break;
//使用气疗术
case ACTION_TYPE_RECOVER:
if(Hero.NowMp>=40)
{
Hero.NowMp-=40;
int HpRecover=5*(5*(rand()%Hero.Intelligence)+40);
Hero.NowHp+=HpRecover;
if (Hero.NowHp>=Hero.MaxHp)
{
Hero.NowHp=Hero.MaxHp;
}
swprintf_s(str,L"玩家圣殿骑士使用了气疗术,恢复了【%d】点生命值,感觉好多了。",HpRecover);
}
else
{
HeroActionType=ACTION_TYPE_MISS;
swprintf_s(str,L"你傻啊~!,魔法值不足40点,施法失败,这回合白费了~!");
}
Message_Insert(str);
break;
}
}
//玩家动作贴图
VOID HeroAction_Paint()
{
switch (HeroActionType)
{
//普通攻击
case ACTION_TYPE_NORMAL:
SelectObject(g_bufdc,g_hHeroSkill1);
TransparentBlt(g_mdc,50,170,364,140,g_bufdc,0,0,364,140,RGB(0,0,0));
break;
//魔法攻击
case ACTION_TYPE_MAGIC:
SelectObject(g_bufdc,g_hHeroSkill2);
TransparentBlt(g_mdc,50,100,374,288,g_bufdc,0,0,374,288,RGB(0,0,0));
break;
//恢复
case ACTION_TYPE_RECOVER:
SelectObject(g_bufdc,g_hRecoverSkill);
TransparentBlt(g_mdc,560,170,150,150,g_bufdc,0,0,150,150,RGB(0,0,0));
break;
}
}
//Boss动作逻辑判断
VOID BossAction_Logic()
{
//用系统时间初始化随机种子
srand((unsigned)time(NULL));
//生命值大于1/2时
if(Boss.NowHp > (Boss.MaxHp/2))
{
switch(rand()%3)
{
//释放普通攻击
case 0:
BossActionType = ACTION_TYPE_NORMAL;
break;
//释放致命一击
case 1:
BossActionType = ACTION_TYPE_CRITICAL;
break;
//使用嗜血咒
case 2:
BossActionType = ACTION_TYPE_MAGIC;
break;
}
}
//生命值小于1/2时
else
{
switch(rand()%3)
{
//释放嗜血咒
case 0:
BossActionType = ACTION_TYPE_MAGIC;
break;
//释放致命一击
case 1:
BossActionType = ACTION_TYPE_CRITICAL;
break;
//恢复
case 2:
BossActionType = ACTION_TYPE_RECOVER;
break;
}
}
}
//Boss动作贴图
VOID BossAction_Paint()
{
int damage=0,recover=0;
wchar_t str[100];
switch(BossActionType)
{
//释放普通攻击
case ACTION_TYPE_NORMAL:
SelectObject(g_bufdc,g_hBossSkill1);
TransparentBlt(g_mdc,500,150,234,188,g_bufdc,0,0,234,188,RGB(0,0,0));
//第30个画面时计算玩家受伤害程度并加入显示消息
if(g_iFrameNum == 30)
{
damage = rand()%Boss.Agility+ Boss.Level*Boss.Strength;
Hero.NowHp -= (int)damage;
swprintf_s(str,L"黄金魔龙君释放幽冥鬼火...对玩家照成【 %d】 点伤害",damage);
Message_Insert(str);
Die_Check(Hero.NowHp,true);
}
break;
//释放嗜血咒
case ACTION_TYPE_MAGIC:
SelectObject(g_bufdc,g_hBossSkill2);
TransparentBlt(g_mdc,450,150,387,254,g_bufdc,0,0,387,254,RGB(0,0,0));
//第30个画面时计算玩家受伤害程度并加入显示消息
if(g_iFrameNum == 30)
{
//嗜血咒的伤害值计算
damage = 2*(2*(rand()%Boss.Agility) + Boss.Strength*Boss.Intelligence);
//让英雄血量减掉一个计算出来的伤害值
Hero.NowHp -= damage;
//吸血量20%
recover=(int)((float)damage*0.2f);
//怪物恢复吸到的血量
Boss.NowHp+=recover;
//将数字格式化到文字中
swprintf_s(str,L"黄金魔龙君释放嗜血咒...对玩家照成【 %d 】点伤害,自身恢复【%d】点生命值",damage,recover);
//插入文字消息
Message_Insert(str);
Die_Check(Hero.NowHp,true);
}
break;
//释放致命一击
case ACTION_TYPE_CRITICAL:
SelectObject(g_bufdc,g_hBossSkill3);
TransparentBlt(g_mdc,280,100,574,306,g_bufdc,0,0,574,306,RGB(0,0,0));
//第30个画面时计算玩家受伤害程度并加入显示消息
if(g_iFrameNum == 30)
{
damage = 2*(rand()%Boss.Agility+ Boss.Level*Boss.Strength);
Hero.NowHp -= (int)damage;
swprintf_s(str,L"黄金魔龙君致命一击...对玩家照成【%d】点伤害.",damage);
Message_Insert(str);
Die_Check(Hero.NowHp,true);
}
break;
//恢复
case ACTION_TYPE_RECOVER:
SelectObject(g_bufdc,g_hRecoverSkill);
TransparentBlt(g_mdc,150,150,150,150,g_bufdc,0,0,150,150,RGB(0,0,0));
//第30个画面时怪物回复生命值并加入显示消息
if(g_iFrameNum == 30)
{
recover= 2*Boss.Intelligence*Boss.Intelligence;
Boss.NowHp +=recover;
swprintf_s(str,L"黄金魔龙君使用梅肯斯姆...恢复了【%d】点生命值",recover);
Message_Insert(str);
}
break;
}
}
//雪花飞舞粒子效果
VOID Snow_Paint()
{
//创建粒子
//当粒子数小于规定的粒子数时,便产生新的粒子,设定每个粒子的属性值
if(g_SnowNum< PARTICLE_NUMBER)
{
//将粒子的X坐标设为窗口中水平方向上的任意位置
SnowFlowers[g_SnowNum].x = rand()%g_rect.right;
//将每个粒子的Y坐标都设为"0",即从窗口上沿往下落
SnowFlowers[g_SnowNum].y = 0;
//设定粒子存在
SnowFlowers[g_SnowNum].exist = true;
//每产生一个粒子后进行累加计数
g_SnowNum++;
}
//首先判断粒子是否存在,若存在,进行透明贴图操作
for(int i=0;i<PARTICLE_NUMBER;i++)
{
//粒子还存在
if(SnowFlowers[i].exist)
{
//贴上粒子图
SelectObject(g_bufdc,g_hSnow);
TransparentBlt(g_mdc,SnowFlowers[i].x,SnowFlowers[i].y,30,30,g_bufdc,0,0,30,30,RGB(0,0,0));
//随机决定横向的移动方向和偏移量
if(rand()%2==0)
//x坐标加上0~5之间的一个随机值
SnowFlowers[i].x+=rand()%6;
else
//y坐标加上0~5之间的一个随机值
SnowFlowers[i].x-=rand()%6;
//纵方向上做匀速运动
//纵坐标加上10
SnowFlowers[i].y+=10;
//如果粒子坐标超出了窗口长度,就让它以随机的x坐标出现在窗口顶部
if(SnowFlowers[i].y > g_rect.bottom)
{
SnowFlowers[i].x = rand()%g_rect.right;
SnowFlowers[i].y = 0;
}
}
}
}
//资源清理
BOOL Game_ShutDown( HWND hwnd )
{
//释放资源对象
DeleteObject(g_hBackGround);
DeleteObject(g_hBackGround);
DeleteObject(g_hGameOver);
DeleteObject(g_hVictory);
DeleteObject(g_hSnow);
DeleteObject(g_hMonsterBitmap);
DeleteObject(g_hHeroBitmap);
DeleteObject(g_hRecoverSkill);
DeleteObject(g_hSkillButton1);
DeleteObject(g_hSkillButton2);
DeleteObject(g_hSkillButton3);
DeleteObject(g_hSkillButton4);
DeleteObject(g_hHeroSkill1);
DeleteObject(g_hHeroSkill2);
DeleteObject(g_hHeroSkill3);
DeleteObject(g_hBossSkill1);
DeleteObject(g_hBossSkill2);
DeleteObject(g_hBossSkill3);
DeleteDC(g_bufdc);
DeleteDC(g_mdc);
ReleaseDC(hwnd,g_hdc);
return TRUE;
}