【游戏开发】简易实现回合制游戏

//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_WIDTH	800	

//窗口高度
#define WINDOW_HEIGHT	600						

//窗口标题
#define WINDOW_TITLE		L"【游戏开发】简易实现回合制游戏"

//粒子数量
#define PARTICLE_NUMBER	50			

//角色结构体
struct CHARACTER  
{
	//当前生命值
	int		NowHp;	

	//最大生命值
	int		MaxHp;		

	//当前魔法值
	int		NowMp;	

	//最大魔法值
	int		MaxMp;	

	//角色等级
	int		Level;	

	//角色力量值
	int		Strength;

	//角色智力值
	int		Intelligence; 

	//角色敏捷值
	int		Agility;		
};

//雪花粒子结构体
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,	
};

//全局环境设备,全局内存设备,全局缓存设备
HDC				g_hdc=NULL,g_mdc=NULL,g_bufdc=NULL;      

//上一次绘图时间,当前绘图时间
DWORD		g_tPre=0,g_tNow=0;		

//储存窗口区域坐标
RECT				g_rect;				

//帧数,文字数量
int					g_iFrameNum,g_iTxtNum;  

//存储输出文字
wchar_t			text[8][100];  

//状态标志:角色是否可以攻击,游戏是否结束
BOOL			g_bCanAttack,g_bGameOver;   

//雪花粒子
SNOW			SnowFlowers[PARTICLE_NUMBER];  

//雪花的数量
int					g_SnowNum=0; 

//角色:英雄,BOSS
CHARACTER	Hero,Boss;  

//动作:英雄动作,BOSS动作
ActionTypes	HeroActionType,BossActionType; 

//背景,游戏结束,游戏胜利,雪花
HBITMAP		g_hBackGround,g_hGameOver,g_hVictory,g_hSnow; 

//BOSS角色图,英雄角色图,恢复技能图的位图句柄
HBITMAP		g_hMonsterBitmap,g_hHeroBitmap,g_hRecoverSkill; 

//4个技能按钮
HBITMAP		g_hSkillButton1,g_hSkillButton2,g_hSkillButton3,g_hSkillButton4; 

//3个英雄技能效果
HBITMAP		g_hHeroSkill1,g_hHeroSkill2,g_hHeroSkill3; 

//3个BOSS技能效果
HBITMAP		g_hBossSkill1,g_hBossSkill2,g_hBossSkill3;  

//窗口过程函数
LRESULT CALLBACK	WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );

//初始化资源
BOOL						Game_Init(HWND hwnd);			

//绘图
VOID							Game_Main( HWND hwnd);		

//清理资源
BOOL						Game_ShutDown(HWND hwnd );	

//死亡检查
VOID							Die_Check(int NowHp,bool isHero);   

//文字消息处理
VOID							Message_Insert(wchar_t* str);  

//英雄动作逻辑
VOID							HeroAction_Logic(); 

//英雄动作绘图
VOID							HeroAction_Paint();  

//怪物动作逻辑
VOID							BossAction_Logic(); 

//怪物动作绘图
VOID							BossAction_Paint(); 

//雪花粒子
VOID							Snow_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;
}

猜你喜欢

转载自blog.csdn.net/qq_23996157/article/details/89164641