您的位置:首页 > 编程语言 > C语言/C++

简单的C++游戏载入界面设计

2015-09-05 15:46 731 查看
        源代码下载地址:

        网盘:http://pan.baidu.com/s/1eQ33c7w

        CSDN:http://download.csdn.net/detail/u011418173/9080501

        最近,看了下毛星云的书:《逐梦旅程 windows游戏编程之从零开始》,对其十分的感兴趣,这本书的内容浅显易懂,很适合像我们这些编程的入门者阅读。目前只看了该书的前半部分,也就是2D游戏的编程,自己便尝试着在浅墨大神的基础框架上做一些别的东西。

    在一些大型游戏的游戏资源载入的过程中,都是会有专门的载入界面,让玩家在等待的过程中不至于太无聊和焦虑。一般,载入界面运行是要有动态效果的,这一般可以说明该游戏没有崩溃,让玩家不要慌:别急,游戏正在加载呢,等等吧。之前玩文明5时的载入界面令我印象深刻,由于自己的电脑不好,一次载入都要好几分钟,有时候游戏死了都不知道ORZ。

1、材料的准备

首先要准备一些图片资源,一些简单的资源我都是自己制作的,这里我准备了一个旋转的loading效果图片,如下所示:



当然了,想通过C++载入gif图片是有些困难的,于是我将这些图片分解为8帧,使用透明遮罩法来显示,具体的制作方法这里就不详述。下面是制成的图片,:



载入时的背景图片:



还有正式游戏时的背景图片:



2、建立loading线程

在浅墨的框架中,有三个关键的函数,分别是:

 1
 2
 3

BOOL				Game_Init(HWND hwnd);		//在此函数中进行资源的初始化VOID				Game_Paint( HWND hwnd);		//在此函数中进行绘图代码的书写BOOL				Game_CleanUp(HWND hwnd );	//在此函数中进行资源的清理

那么载入界面的代码当然是要写在初始化中了,为了不影响其他资源的载入,我考虑创建一个线程,在这里实现loading界面的绘制。同时主程序实现加载游戏资源的任务。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30

BOOL Game_Init( HWND hwnd ){	HBITMAP bmp;
g_hdc = GetDC(hwnd); g_mdc = CreateCompatibleDC(g_hdc); //创建一个和hdc兼容的内存DC g_bufdc = CreateCompatibleDC(g_hdc);//再创建一个和hdc兼容的缓冲DC bmp = CreateCompatibleBitmap(g_hdc,WINDOW_WIDTH,WINDOW_HEIGHT); SelectObject(g_mdc,bmp); //预先加载Loading界面 g_hLoading = (HBITMAP)LoadImage(NULL,L"loading.bmp",IMAGE_BITMAP,2400,600,LR_LOADFROMFILE); g_hlLoading_bk = (HBITMAP)LoadImage(NULL,L"loading_bk.bmp",IMAGE_BITMAP,1500,1000,LR_LOADFROMFILE); //设置字体 HFONT hFont; hFont = CreateFont(80,0,0,0,700,0,0,0,GB2312_CHARSET,0,0,0,0,TEXT("钟齐段宁行书")); SelectObject(g_mdc,hFont); SetBkMode(g_mdc,TRANSPARENT);
_beginthread(ThreadFunc,0,NULL);
//加载其他各种正式的游戏资源的地方 g_hBackGround = (HBITMAP)LoadImage(NULL,L"场景1.bmp",IMAGE_BITMAP,WINDOW_WIDTH,WINDOW_HEIGHT,LR_LOADFROMFILE);
//为了测试效果,强行增加Loading时间,正常运行时,只要资源加载完后,就可以退出线程 Sleep(3000); g_bFinishThread = 1;
Game_Paint(hwnd); return TRUE;}

前面的g_hdc,g_mdc,g_bufdc三个设备上下文句柄,是用于实现三缓冲绘图用的,这里就不再详述了。后面是设置字体,这里选用的是“钟齐段宁行书”字体,个人比较喜欢这种风格。载入完成这些资源后,就可以进入线程函数ThreadFunc了。当所有的游戏资源全部完成之后,将bool类型的g_bFinishTread置为1,从而让线程退出。
由于这个例子的资源极少,载入极快,故几乎看不到载入时的效果,所以添加了一句:Sleep(3000)。这样我们能够看到3秒的loading界面,从而判断效果的好坏。

下面是线程函数的具体内容:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34

void ThreadFunc (PVOID pvoid){	srand((int)time(NULL));//设置随机种子	int i = 0;//用于帧数的循环	DWORD tNow,tPre;//保存当前时间和上一帧的时间	tPre = GetTickCount();//获得当前的时间	//若游戏资源未加载完,则g_bFinishThread一直为0,将一直循环下去	while(!g_bFinishThread)	{		//载入loading时的背景图片		SelectObject(g_bufdc,g_hlLoading_bk);		BitBlt(g_mdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_bufdc,0,0,SRCCOPY);		//载入loading时的旋转图片,使用透明遮罩法		SelectObject(g_bufdc,g_hLoading);		BitBlt(g_mdc,600,300,300,300,g_bufdc,i*300,300,SRCAND);		BitBlt(g_mdc,600,300,300,300,g_bufdc,i*300,0,SRCPAINT);		//绘制提示文字		WCHAR str[50];		swprintf_s(str,L"游戏资源正在拼命加载中,请稍后...");		SetTextColor(g_mdc,RGB(rand()%255,rand()%255,rand()%255));//使用随机数,呈现随机的颜色		TextOut(g_mdc,150,700,str,wcslen(str));		//将最后的画面显示在窗口中		BitBlt(g_hdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_mdc,0,0,SRCCOPY);
i++; if(i == 8)//每8张一个循环 i = 0; do{ tNow = GetTickCount(); }while(tNow-tPre<100);//当前后时间超过0.1s后,绘制下一帧 tPre = tNow; } return;}

为了防止在绘制loading界面的同时进行正常游戏的绘制,我在winmain函数的循环体中加入了一条判断:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16

	while( msg.message != WM_QUIT )		//使用while循环,如果消息不是WM_QUIT消息,就继续循环	{		if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。		{			TranslateMessage( &msg );		//将虚拟键消息转换为字符消息			DispatchMessage( &msg );			//分发一个消息给窗口程序。		}		else		{			g_tNow = GetTickCount();   //获取当前系统时间			if(g_tNow-g_tPre >= 100)   //当此次循环运行与上次绘图时间相差0.1秒时再进行重绘操作				if(g_bFinishThread)    //如果loading线程结束,则进行正常的游戏绘制					Game_Paint(hwnd);		}
}

3、实现效果

最后我们看到效果图为:



加载完成后为:



4、补充内容

浅墨大神在游戏中添加的音乐资源都是wav格式的,而PlaySound函数只能支持wav格式的文件,同时该格式的文件不能够进行其他的更多的操作如声音的暂停、停止、音量的控制等。所以我在程序中选择了使用mp3格式的文件,并使用MCI媒体控制接口来实现音乐的播放,今后的游戏也尽量都使用这种方法。

但是这种方法的话,在编译器中调试时是发不出声音的!一开始还以为是代码的问题,后来尝试直接运行Debug文件夹下的.exe文件,发现代码原来没有问题。。。

注:需要链接winmm.lib库
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息