Win32游戏制作之---SwordsMan

Posted Loving_初衷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Win32游戏制作之---SwordsMan相关的知识,希望对你有一定的参考价值。

前言  

       今天是NBA总决赛的最后一场,还是抢七大战,伟大的James终于圆梦了,比赛之中突然发现詹姆斯胡子都有点白了,原来原先那些陪伴自己众多篮球明星都已经老了,Kobe也退役了,他们每个人都有梦想并且为之奋斗,詹姆斯为了自己的梦想奋斗了这么多年才圆梦,那么自己也应该努力实现自己心中的梦想,当然只是想实现自己心中的一个小小的梦想而已,不是每个人都可以说出为自己家乡带来总冠军那样的豪言壮语。

               

                                                          ---这句话送给伟大的詹姆斯,也送给我自己,更送给所有在梦想道路上前进的人

       前段时间由于忙着准备学校的考试,没有时间好好做自己想做的事情,再加上今天早上还有NBA总决赛,所以好久没有写博客,考试考完之后,我就开始了自己做了一个小游戏---SwordsMan,当然这只是我给取得一个名字,并不是那个SwordsMan,和真正的SwordsMan游戏还是有很大的差距的。

       游戏之中的场景图是我用Photoshop拼接而成,自己也感觉做的不好,大家看看就好。游戏中的小鸟以及Boss小龙也是用Photoshop制作的,下面来看一下实际的效果图:

游戏初始状态:


 游戏技能释放:

每次用技能击中小鸟,会获得积分,当积分达到100的时候,Boss就会出现,如图:


当然Boss会释放技能,来看一下:


       Boss的技能是一组动态图,范围是以它为中心的150个像素之内,当然,Boss会先判断玩家的位置,然后在释放技能,不过这里只是初步判断一下,人工智能是一个很大的话题。现在总算明白为什么为什么AI难以设计了,以前还总是嫌弃AI不行,比如我在玩三国志系列游戏的时候总是觉得AI不够智能,现在总算明白AI的难度之大。大家在玩dota或者LoL的时候,可能会感觉电脑弱(不过话说我从来没有感觉到dota之中的AI弱,我表示经常打不过电脑o(╯□╰)o)。

       其实我感觉最难的还是碰撞检测,我在代码之中也是做了一些比较简单地检测,其实这一块真的挺难的,首先你得想到各种情况,哪怕是边边角角碰到了,可能也是一种有效的碰撞。这样的碰撞检测在FPS类型的游戏之中显得格外的重要,比如子弹是否击中人,以及击中人的什么部位。这些方面,国外的做的很好,尤其是一些3A级大作。在他们的游戏引擎之中就有专门的检测机制。

          下面来看一下代码,为了节省篇幅,我给出重要的代码,生成窗口的代码就省略了。

//头文件
#pragma once
#include "GameEngine.h"
#include <Windows.h>
#include <tchar.h>                    //使用swprintf_s函数所需的头文件
#include "resource.h"

#define KEY_DOWN(vk_code)              ((GetAsyncKeyState(vk_code)&0x8000)?1:0)
#define KEY_UP(vk_code)                ((GetAsyncKeyState(vk_code)&0x8000)?0:1)

struct SwordBullets                     //代表主人公的剑气 
{
    int x, y;                       //人物剑气的坐标
    bool isExist;                       //剑气是否存在
};

struct BirdMaster
{
    int x, y;                       //代表经过的小鸟的坐标
    bool isExist;                       //表示小鸟是否存在
    int picNum;                       //图的标号(一共5个)
    HBITMAP hbird;                       //小鸟的位图句柄
};  

struct BossMaster
{
    int x, y;                      //代表boss的贴图坐标
    int picNum;                      //boss图的标号(一共6个)
    int ipicNum;                      //boss技能图的标号
    HBITMAP hBoss;                      //boss的位图句柄
    int boss_blood;                      //boss的血量
    HBITMAP hBossSkill;                      //boss技能句柄
    int Skill_x, Skill_y;                      //boss的技能坐标
    int boss_x, boss_y;                      //boss的中心坐标
};

int g_iX = 0, g_iY = 0;            //鼠标所在位置
<pre name="code" class="cpp"> //全局设备句柄、全局内存DC句柄、以及缓冲DC

HDC g_hdc = NULL, g_mdc = NULL, g_bufdc = NULL;

 //定义五个位图句柄,分别用来存储背景、人物、剑气、失败、胜利                                                               

HBITMAP g_hBackGround = NULL, g_hSwordMan = NULL, g_hSwordBlade = NULL, g_hGameOver = NULL, g_hvictory = NULL; 
int g_iXSwordMan = 0, g_iYSwordMan = 0; //人物所在位置记录当前人物的坐标,也就是贴图坐标
int g_iBGOffset = 0, g_iBulletNum = 0, g_ibirdNum = 0; //g_iBGOffset为滚动背景所要裁剪的区域宽度,g_iBulletNum记录剑气的数量
SwordBullets Bullet[30];                            
BirdMaster Bird[10];                                
BossMaster Boss;                                     
int g_Score = 0;                                    //玩家得分
int g_life = 0;                                     //玩家血量
bool g_Isboss = false;                              //boss是否存在

//时间计数
DWORD g_tPre = 0, g_tNow = 0;                       

GameEngine * g_pGame = NULL;

//游戏中检测函数,(传参看似没有必要,主要是为了便于日后代码的维护)
bool Is_in_Randge(BirdMaster &bir);
bool Is_hit_bird(BirdMaster &bir, SwordBullets &bullet);
void bird_hit_man(BirdMaster &bir);
void Boss_appear();
void Boss_Initalize();
void Is_hit_boss(BossMaster &bos, SwordBullets &bullet);
bool Boss_hit_man(BossMaster &bos);

#pragma

#include "Swordsman.h"

BOOL GameInitalize(HINSTANCE hInstance)         //游戏初始化函数
{
	PlaySound(L"仙剑三·原版主题曲", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
	try
	{
		g_pGame = new GameEngine(hInstance, L"SwordsMan", L"SwordMan", IDI_SWORDMAN, IDI_SWORDMAN_SM);
	}
	catch (...)
	{
		return FALSE;
	}
	g_pGame->SetFrameDelay(20);
	g_life = 100;
	g_Score = 0;
	Boss_Initalize();                                //初始化boss的一些信息,满足一定条件出现
	return TRUE;
}

void GameStart(HWND hWindow)                        //游戏开始函数
{
	HBITMAP bmp;
	g_hdc = GetDC(hWindow);
	g_mdc = CreateCompatibleDC(g_hdc);
	g_bufdc = CreateCompatibleDC(g_hdc);
	bmp = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);

	g_iX = 300;
	g_iY = 100;
	g_iXSwordMan = 300;
	g_iYSwordMan = 100;

	SelectObject(g_mdc, bmp);                     //选择空位图
	//加载各种位图
	g_hSwordMan = (HBITMAP)LoadImage(NULL, L"GameMedia\\\\swordman.bmp", IMAGE_BITMAP, 317, 283, LR_LOADFROMFILE);
	g_hSwordBlade = (HBITMAP)LoadImage(NULL, L"GameMedia\\\\swordblade.bmp", IMAGE_BITMAP, 100, 26, LR_LOADFROMFILE);
	g_hBackGround = (HBITMAP)LoadImage(NULL, L"GameMedia\\\\bg.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
	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);

	POINT pt, lt, rb;
	RECT rect;
	//设置光标的位置
	pt.x = 300;
	pt.y = 100;
	ClientToScreen(hWindow, &pt);
	SetCursorPos(pt.x, pt.y);

	ShowCursor(false);                             //隐藏鼠标
	GetClientRect(hWindow, &rect);
	lt.x = rect.left;
	lt.y = rect.top;
	rb.x = rect.right;
	rb.y = rect.bottom;
	ClientToScreen(hWindow, <);
	ClientToScreen(hWindow, &rb);
	rect.left = lt.x;
	rect.top = lt.y;
	rect.right = rb.x;
	rect.bottom = rb.y;
	//限制鼠标的移动区域
	ClipCursor(&rect);
	GamePaint(hWindow);
}

void GamePlay()
{
	GamePaint(g_pGame->GetWindow());
	if (g_ibirdNum <= 10)
	{
		g_tPre = GetTickCount();
		if (g_tPre - g_tNow > 1500)
		{
			for (int j = 0; j < 10; j++)
			{
				if (!Bird[j].isExist)
				{
					Bird[j].x = 0;
					Bird[j].y = rand() % WINDOW_HEIGHT;
					Bird[j].isExist = true;
					Bird[j].picNum = 0;
					Bird[j].hbird = (HBITMAP)LoadImage(NULL, L"GameMedia\\\\bird.bmp", IMAGE_BITMAP, 1250, 360, LR_LOADFROMFILE);
					g_ibirdNum++;
					g_tNow = g_tPre;
					break;
				}
			}
		}
	}
}

void GamePaint(HWND hWindow)                                     //游戏绘制函数
{
	//先在内存DC之中贴上背景图
	SelectObject(g_bufdc, g_hBackGround);
	BitBlt(g_mdc, 0, 0, g_iBGOffset, WINDOW_HEIGHT, g_bufdc, WINDOW_WIDTH - g_iBGOffset, 0, SRCCOPY);
	BitBlt(g_mdc, g_iBGOffset, 0, WINDOW_WIDTH - g_iBGOffset, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);
	TCHAR str[20] = {};
	//计算剑侠的贴图坐标,设定每次进行贴图时,剑侠都会慢慢以10个像素的单位向目标接近

	if (g_iX > g_iXSwordMan)                         //若当前鼠标X坐标大于人物的坐标,则前进(往左)
	{
		g_iXSwordMan += 10;
		if (g_iXSwordMan > g_iX)
		{
			g_iXSwordMan = g_iX;
		}
	}
	else                                             //若当前的鼠标X坐标小于人物的坐标,则后退(往右)
	{
		g_iXSwordMan -= 10;
		if (g_iXSwordMan < g_iX)
		{
			g_iXSwordMan = g_iX;
		}
	}

	if (g_iY > g_iYSwordMan)
	{
		g_iYSwordMan += 10;
		if (g_iYSwordMan > g_iY)
		{
			g_iYSwordMan = g_iY;
		}
	}

	else
	{
		g_iYSwordMan -= 10;
		if (g_iYSwordMan < 0)
		{
			g_iYSwordMan = 0;
		}
	}

	//贴上剑侠的图
	SelectObject(g_bufdc, g_hSwordMan);
	TransparentBlt(g_mdc, g_iXSwordMan, g_iYSwordMan, 317, 283, g_bufdc, 0, 0, 317, 283, RGB(0, 0, 0));

	//剑气(子弹)的贴图,先判断剑气(子弹)数目“g_iBulletNum”的值是否为“0”。若不为0,则对剑气(子弹)数组中各个还存在的剑气(子弹)按照其所在的坐标(b[i].x,b[i].y)循环进行贴图操作
	SelectObject(g_bufdc, g_hSwordBlade);

	if (g_iBulletNum != 0)
	{
		for (int i = 0; i < 30; i++)
		{
			if (Bullet[i].isExist)
			{
				//检测有无击中boss
				Is_hit_boss(Boss, Bullet[i]);
				if (Boss.boss_blood <= 0)                         //若boss死亡,就贴出胜利的图片
				{
					g_Isboss = false;
					SelectObject(g_bufdc, g_hvictory);
					TransparentBlt(g_mdc, 250, 50, 800, 600, g_bufdc, 0, 0, 800, 600, RGB(0, 0, 0));
					g_pGame->SetGameState(TRUE);
				}

				//依次判断有无击中小鸟
				for (int j = 0; j < 10; j++)
				{
					if (Is_hit_bird(Bird[j], Bullet[i]))
					{
						Bullet[i].isExist = false;
						g_iBulletNum--;
						Bird[j].isExist = false;
						g_ibirdNum--;
						g_Score += 10;
						if (g_Score >= 100)
						{
							g_Isboss = true;
						}
					}
				}
				if (Bullet[i].isExist)
				{
					TransparentBlt(g_mdc, Bullet[i].x - 70, Bullet[i].y + 100, 100, 33, g_bufdc, 0, 0, 100, 26, RGB(0, 0, 0));
				}
				//设置下一个剑气(子弹)的坐标。剑气(子弹)是从右向左发射的,因此,每次其X轴上的坐标值递减10个单位,这样贴图会产生往左移动的效果。而如果剑气(子弹)下次的坐标已超出窗口的可见范围(h[i].x<0),那么剑气(子弹)设为不存在,并将剑气(子弹)总数g_iBulletNum变量值减1.
				Bullet[i].x -= 10;

				if (Bullet[i].x < 0)
				{
					g_iBulletNum--;
					Bullet[i].isExist = false;
				}
			}
		}
	}

	//判断小鸟的数量“g_ibirdNum”的值是否为“0”。若不为0,则对剑气(子弹)数组中各个还存在的剑气(子弹)按照其所在的坐标,循环进行贴图操作
	if (g_ibirdNum != 0)
	{
		for (int i = 0; i < 10; i++)
		{
			if (Bird[i].isExist)
			{
				if (Bird[i].picNum >= 5)
				{
					Bird[i].picNum = 0;
				}
				SelectObject(g_bufdc, Bird[i].hbird);
				BitBlt(g_mdc, Bird[i].x, Bird[i].y, 250, 180, g_bufdc, Bird[i].picNum * 250, 180, SRCAND);
				BitBlt(g_mdc, Bird[i].x, Bird[i].y, 250, 180, g_bufdc, Bird[i].picNum * 250, 0, SRCPAINT);

				if (Is_in_Randge(Bird[i]))
				{
					if (Bird[i].y < g_iYSwordMan)
					{
						Bird[i].y += 10;
					}
					else
					{
						Bird[i].y -= 10;
					}
					Bird[i].x += 10;
				}
				else
				{
					Bird[i].x += 10;                                   //设定小鸟的前进路线
				}

				if (Bird[i].x > WINDOW_WIDTH)
				{
					Bird[i].isExist = false;
					g_ibirdNum--;
				}
				Bird[i].picNum++;
				bird_hit_man(Bird[i]);
			}
		}
	}

	//判断boss是否存在
	if (g_Isboss)
	{
		Boss_appear();
	}

	//创建字体
	HFONT hfont;
	hfont = CreateFont(35, 20, 0, 0, 300, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("微软雅黑"));
	//把字体选入g_mdc
	SelectObject(g_mdc, hfont);
	//设置背景颜色透明
	SetBkMode(g_mdc, TRANSPARENT);
	//设置文字颜色
	SetTextColor(g_mdc, RGB(255, 0, 0));

	//在右上角进行文字输出
	swprintf_s(str, L"玩家血量(life): %d%%", g_life);
	TextOut(g_mdc, 850, 0, str, wcslen(str));
	swprintf_s(str, L"玩家得分(score): %d", g_Score);
	TextOut(g_mdc, 50, 0, str, wcslen(str));

	//贴上图
	BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);

	//背景的移动
	g_iBGOffset += 5;
	if (g_iBGOffset >= WINDOW_WIDTH)                    //如果大于窗口宽度,就变为0
	{
		g_iBGOffset = 0;
	}
}

void GameActivate(HWND hWindow)                   //游戏被激活
{
	HDC hdc;
	RECT rect;
	GetClientRect(hWindow, &rect);
	hdc = GetDC(hWindow);
	DrawText(hdc, L"Welcome to back", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	ReleaseDC(hWindow, hdc);
}

void GameDeactivate(HWND hWindow)                   //游戏未被激活
{
	HDC hdc;
	RECT rect;
	GetClientRect(hWindow, &rect);
	hdc = GetDC(hWindow);
	DrawText(hdc, L"Pause", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
	ReleaseDC(hWindow, hdc);
}

void GameEnd()                                       //游戏结束函数
{
	//资源的清理
	DeleteObject(g_hBackGround);
	DeleteDC(g_bufdc);
	DeleteDC(g_mdc);
	ReleaseDC(g_pGame->GetWindow(), g_hdc);
}

void HandleKeys()                                         //按键处理函数
{
	if (KEY_DOWN(VK_ESCAPE))                              //按下Esc退出
	{
		DestroyWindow(g_pGame->GetWindow());
		return;
	}
	if (KEY_DOWN(VK_UP))                                 //按下up(向上的箭头)玩家向上移动
	{
		g_iYSwordMan -= 50;
		if (g_iYSwordMan < 0)
		{
			g_iYSwordMan = 0;
		}
	}
	if (KEY_DOWN(VK_SHIFT))                              //按下shift进行加速
	{
		g_iBGOffset += 15;
	}
	if (KEY_DOWN(VK_LBUTTON))                            //按下鼠标左键
	{
		for (int i = 0; i < 30; i++)
		{
			if (!Bullet[i].isExist)
			{
				Bullet[i].x = g_iXSwordMan;
				Bullet[i].y = g_iYSwordMan + 30;
				Bullet[i].isExist = true;
				g_iBulletNum++;
				break;
			}
		}
	}
	if (KEY_DOWN(VK_DOWN))                            //按下up(向上的箭头)玩家向上移动
	{
		g_iYSwordMan += 50;
		if (g_iYSwordMan > WINDOW_HEIGHT)
		{
			g_iYSwordMan = WINDOW_HEIGHT;
		}
	}
}

bool Is_in_Randge(BirdMaster &bir)                             //判断玩家是否在小鸟的视野半径内,若是,则飞向玩家
{
	if (bir.isExist)
	{
		if (bir.x < g_iXSwordMan)
		{
			if (((bir.x - g_iXSwordMan)*(bir.x - g_iXSwordMan) + (bir.y - g_iYSwordMan)*(bir.y - g_iYSwordMan)) <= 90000)   //检测是否在一个圆内
			{
				return true;
			}
		}
		return false;
	}
	else
	{
		return false;
	}
}

bool Is_hit_bird(BirdMaster &bir, SwordBullets &bullet)               //判断技能有没有击中小鸟
{
	if (bir.isExist)
	{
		if ((bullet.y + 13 > bir.y + 25) && (bullet.y + 13 < bir.y + 45))
		{
			if ((bullet.x < bir.x + 220) && (bullet.x > bir.x + 125))
			{
				return true;
			}
		}
	}
	return false;
}

void bird_hit_man(BirdMaster &bir)                                 //小鸟与玩家的碰撞
{
	if (bir.isExist)
	{
		if (((bir.y + 45) <= g_iYSwordMan + 250) && ((bir.y + 45) >= g_iYSwordMan + 80))
		{
			if (((bir.x + 220) > (g_iXSwordMan + 35)) && ((bir.x + 220) < (g_iXSwordMan + 125)))
			{
				bir.isExist = false;
				g_life -= 10;
				if (g_life == 0)
				{
					SelectObject(g_bufdc, g_hGameOver);                    //玩家死亡,贴出失败的图片
					BitBlt(g_mdc, 400, 100, 543, 396, g_bufdc, 543, 0, SRCAND);
					BitBlt(g_mdc, 400, 100, 543, 396, g_bufdc, 0, 0, SRCPAINT);
					g_pGame->SetGameState(TRUE);
				}
			}
		}
	}
}

void Boss_appear()                                             //Boss出现
{ 
	if (Boss.picNum >= 6)
	{
		Boss.picNum = 0;
	}
	SelectObject(g_bufdc, Boss.hBoss);                       //贴上Boss的图片
	BitBlt(g_mdc, Boss.x, Boss.y, 220, 200, g_bufdc, Boss.picNum * 220, 200, SRCAND);
	BitBlt(g_mdc, Boss.x, Boss.y, 220, 200, g_bufdc, Boss.picNum * 220, 0, SRCPAINT);
	Boss.picNum++;
	if (((Boss.boss_x - g_iXSwordMan)*(Boss.boss_x - g_iXSwordMan) + (Boss.boss_y - g_iYSwordMan)*(Boss.boss_y - g_iYSwordMan))<360000)
	{
		if (Boss.ipicNum >= 6)
		{
			Boss.ipicNum = 0;
		}
		if (Boss.Skill_x - Boss.x >= 380)
		{
			Boss.Skill_x = Boss.x + 200;
		}
		if (Boss.Skill_y - Boss.y >= 280)
		{
			Boss.Skill_y = Boss.y + 100;
		}
		SelectObject(g_bufdc, Boss.hBossSkill);                     //贴上Boss的技能图
		BitBlt(g_mdc, Boss.Skill_x, Boss.Skill_y, 150, 150, g_bufdc, Boss.ipicNum * 150, 150, SRCAND);
		BitBlt(g_mdc, Boss.Skill_x, Boss.Skill_y, 150, 150, g_bufdc, Boss.ipicNum * 150, 0, SRCPAINT);
		Boss.ipicNum++;
		if (Boss_hit_man(Boss))
		{
			g_life -= 20;
			if (g_life <= 0)                                       //判断玩家是否还有血量,若没有,则贴出失败的图片
			{
				g_life = 0;
				SelectObject(g_bufdc, g_hGameOver);                 
				BitBlt(g_mdc, 400, 100, 543, 396, g_bufdc, 543, 0, SRCAND);
				BitBlt(g_mdc, 400, 100, 543, 396, g_bufdc, 0, 0, SRCPAINT);
				g_pGame->SetGameState(TRUE);
			}
		}
	}
	else
	{
		if (Boss.x >= g_iXSwordMan - 400)
		{
			Boss.x -= rand() % 40;
		}
		else
		{
			if (Boss.y > g_iYSwordMan)
			{
				Boss.y -= 15;
				if (Boss.x < g_iXSwordMan)
				{
					Boss.x += 10;
				}
				else
				{
					Boss.x -= 20;
				}
			}
			else if (Boss.y < g_iYSwordMan)
			{
				Boss.y += 15;
				if (Boss.x < g_iXSwordMan)
				{
					Boss.x += 10;
				}
				else
				{
					Boss.x -= 20;
				}
			}
			else
			{
				if (Boss.x < g_iXSwordMan)
				{
					Boss.x += 10;
				}
				else
				{
					Boss.x -= 20;
				}
			}
		}
	}
}

void Boss_Initalize()                                      //Boss的初始化
{
	g_Isboss = false;
	Boss.boss_blood = 100;
	Boss.hBoss = (HBITMAP)LoadImage(NULL, L"GameMedia\\\\boss.bmp", IMAGE_BITMAP, 1320, 400, LR_LOADFROMFILE);    //加载boss位图
	Boss.hBossSkill = (HBITMAP)LoadImage(NULL, L"GameMedia\\\\bossSkill.bmp", IMAGE_BITMAP, 900, 300, LR_LOADFROMFILE);  //加载boss技能图
	Boss.picNum = 0;
	Boss.ipicNum = 0;
	Boss.x = 0;
	Boss.y = rand() % WINDOW_HEIGHT;
	Boss.Skill_x = Boss.x + 200;                     //技能设置的初始位置
	Boss.Skill_y = Boss.y + 100;
	Boss.boss_x = Boss.x + 150;                      //Boss的中心位置
	Boss.boss_y = Boss.y + 100;
}

bool Boss_hit_man(BossMaster &bos)                   //判断Boss是否碰撞到玩家,或者Boss技能是否击中玩家
{
	bos.Skill_x += 30;
	if (bos.Skill_y + 75 < g_iYSwordMan)
	{
		bos.y += 5;
		bos.Skill_y += 20;
	}
	else if (bos.Skill_y + 75 > g_iYSwordMan)
	{
		bos.y -= 5;
		bos.Skill_y -= 20;
	}
	else
	{
		bos.y = bos.y;
		bos.Skill_y = bos.Skill_y;
	}
	//判断boss是否碰到玩家
	if ((bos.boss_y <= g_iYSwordMan + 250) && (bos.boss_y >= g_iYSwordMan + 80))
	{
		if ((bos.boss_x > (g_iXSwordMan + 35)) && (bos.boss_x < (g_iXSwordMan + 125)))
		{
			g_life -= 15;
		}
	}
	//判断boss技能是否击中玩家
	if ((bos.Skill_y + 75 <= g_iYSwordMan + 250) && ((bos.Skill_y + 75) >= g_iYSwordMan + 80))
	{
		if (((bos.Skill_x + 75) >(g_iXSwordMan + 35)) && ((bos.Skill_x + 75) < (g_iXSwordMan + 125)))
		{
			return true;
		}
	}
	return false;
}

void Is_hit_boss(BossMaster &bos, SwordBullets &bullet)           //玩家是否击中Boss
{
	if ((bullet.y + 13 > (bos.boss_y - 30)) && (bullet.y + 13 < bos.boss_y + 15))
	{
		if ((bullet.x < bos.boss_x + 50) && (bullet.x > bos.boss_x - 30))
		{
			bos.boss_blood -= 15;
			g_Score += 20;
			bullet.isExist = false;                               //子弹击中之后消失
			g_iBulletNum--;
		}
	}
}

            
在代码之中基本都有注释,这里就不分析了,Boss有500点血量,还真不是那么简单地:


            不过要想简单也很容易,把Boss血量降到1就可以了,O(∩_∩)O,来一张胜利作为结束:


         当然这只是一个很简单的游戏,大家可以看看,也欢迎大家给出一些建议!(PS:窗口生成那一部分WIN32的代码是一个固定的格式,为了节省篇幅所以没有贴出)


以上是关于Win32游戏制作之---SwordsMan的主要内容,如果未能解决你的问题,请参考以下文章

Win32游戏制作之---FreakOut

在井字游戏 C++ 中使用“新游戏”按钮,win32 应用程序初学者

Cocos2d-x 3.0游戏开发之win32配置环境搭建project

游戏更新就出现发生致命错误Win32Error怎么回事

win32编程之俄罗斯方块

棋牌源码搭建教程之棋牌游戏AI算法