收藏 分享(赏)

6、游戏声音.doc

上传人:yjrm16270 文档编号:9537124 上传时间:2019-08-13 格式:DOC 页数:20 大小:332KB
下载 相关 举报
6、游戏声音.doc_第1页
第1页 / 共20页
6、游戏声音.doc_第2页
第2页 / 共20页
6、游戏声音.doc_第3页
第3页 / 共20页
6、游戏声音.doc_第4页
第4页 / 共20页
6、游戏声音.doc_第5页
第5页 / 共20页
点击查看更多>>
资源描述

1、游戏音乐与音效的播放在 Win32 环境下,播放音乐音效的方法太多了,而且有一个共同点就是:你不需要花很大的心力就可以得到你需要的东西。游戏的配乐我相信很多人一定同意音乐在游戏里面所占的地位,回想一下国内 RPG 的经典仙剑奇侠传 ,剥掉音乐这一个层面,整个游戏将会逊色不少,尤其适当的场景搭配适当的音乐,更能让玩家融入剧情当中。该哭的时候哭,该笑的时候笑,大概就很切中要领了。RPG 剩下的音效部份,并不特别突出,大抵上知道砍人的时候有挥剑的声音就可以了,所以在音效的表现方面,通常比较不那么注重。而即时战斗的游戏着重在厮杀的音效表现上,一大片人马,一片混杂的声音,这其中牵涉到混音的部份,这一章,

2、你将学习到什么时候该用什么样的代码来表现游戏的另一个生命:音乐与音效。一、理解数字声音虽然不必理解数字声音的工作方式就可以在游戏中播放声音,但是我们应该对数字声音以及它与我们在真实世界里听到的物理声音之间的关系有基本的了解。物理声音是通过空气传播的波,与海浪类似。声波实际上是空气膨胀和压缩所产生的压力的结果。换句话说,声波涉及空气中的一系列移动的压力变化。我们能够听到声音是因为移动的声波最终到达我们的耳朵,耳膜处理并解释这种压力的变化。声音的柔和或音量是由波中的能量决定的,因为声波在移动时会损失能量,所以距离越近,听到的声音越大,距离越远,声音就越柔和。当麦克风将声波转换为电信号时,得到的信号

3、是一个模拟信号。而计算机是数字机器,因此必须将模拟信号转换为数字信号。模拟/数字(A/D)转换器完成了将模拟信号转换为数字信号的任务,这种转换称为采样。采样的频率(HZ)以及在每个样本中存储的信息量决定了数字波形与模拟波形的接近程度。二、播放 WAV 声音Windows 中的数字声音称为波形声音,这是指数字声音源自于物理的声波。在 Windows 中,波形声音就像位图、图标以及光标等 windows 资源一样,这意味着可以指定波形声音作为游戏的资源脚本中的资源,并将它们直接编译到可执行程序文件中。Win32 API 提供了对播放波形声音的高级支持,所谓高级支持是指可以使用 Win32 API

4、播放声音而不必关心波形声音格式的细节或者处理内存中的原始声音数据。Win32 API 中的高级波形声音支持的一个缺点是,它不允许波形混合(波形混合是指混合波形声音,从而同时播放多个声音) 。这意味着在任何特定时刻都只能播放一个波形声音。因为有时候可能需要同时播放两个或者更多的声音,所以必须确定这一点对自己的游戏的影响。在需要解决一次只能播放一个声音的问题时,可以选择以下方法:(1)中断当前正在播放的声音,以便播放下一个声音。(2)允许每一个声音播放结束,并拒绝那些试图中断当前所播放声音的声音。至于在你的游戏中到底使用哪种方式,完全取决于游戏类型。补充:可以使用 DirectX API 来混合波

5、形声音。BOOL PlaySound( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound );(1)播放文件中的波形声音此时 PlaySound()的第一个参数 szSound 标识了波形文件的名称,第 2 个参数 hMod 只适用于播放波形资源,因此在播放波形文件时可以对第 2 个参数传递 NULL。第 3 个参数dwSound 用来确定播放波形声音的具体方式。SND_FILENAME是播放一个文件中的波形声音。举例:PlaySound(“Explosion.wav” , NULL , SND_ASYNC|SND_FILENAME)SND_RESOU

6、RCE波形声音是一个资源。举例:PlaySound(LPCSTR)IDW_EXPLOSION,g_hInstance, SND_ASYNC|SND_RESOURCE)SND_SYNC同步波形。即 playSound()不允许程序在完成播放之前继续操作,这在游戏中几乎不可能。SND_ASYNC异步波形。允许继续操作。SND_NOSTOP它使一个声音更 “尊重”正在播放的另一个声音。更具体地说,如果在播放一个波形声音时指定了 SND_NOSTOP 标志,那么这个声音不会中断另一个已经在播放的声音。如果要让该声音能够中断当前正在播放的声音,则不要指定 SND_NOSTOP 标志。SND_LOOP循环

7、播放波形声音。PlaySound(LPCSTR)IDW_EXPLOSION,g_hInstance,SND_ASYNC|SND_RESOURCE|SND_LOOP)循环的声音会继续无休止地循环播放,直到播放另一个波形声音以停止它,或者使用对PlaySound()的另一个调用来停止循环播放的波形声音。SND_PURGE停止播放波形声音。1、停止正在播放的某个波形声音PlaySound(LPCSTR)IDW_EXPLOSION , g_hInstance , SND_PURGE|SND_RESOURCE)2、停止播放任何声音举例:PlaySound(NULL , NULL , SND_PURGE)

8、在游戏中提供一个禁用声音的选项总是一种很好的做法。做法很简单,如响应键盘上的 S 键打开或关闭声音。举例:Brainiac2为以下游戏事件添加声效支持(1)选择一个方块(2)将两个方块配对(3)两个方块配对错误(4)将所有方块配对,赢得游戏胜利void MouseButtonDown(int x, int y, BOOL bLeft)/确定单击了哪个方块int iTileX = x/g_tileImgs0-GetWidth();int iTileY = y/g_tileImgs0-GetHeight();/确保不是点击了已经配对成功的方块if(g_bTileStatesiTileXiTileY

9、 = false) /判断是否是第一个选中方块if(g_tile1.x=-1) /播放第一个方块选择声音/PlaySound(LPCTSTR)IDW_SELECT,hinstance_app,SND_ASYNC|SND_RESOURCE);PlaySound(“Res/Select.wav“, NULL, SND_ASYNC | SND_FILENAME);g_tile1.x = iTileX; g_tile1.y = iTileY;else /判断是否表示第二个选中的方块 if( (iTileX!=g_tile1.x) | (iTileY!=g_tile1.y)/没有重复点击第一个选中方块

10、if(g_tile2.x = -1) /播放第 2 个方块选择声音/PlaySound(LPCTSTR)IDW_SELECT, hinstance_app, SND_ASYNC | SND_RESOURCE);PlaySound(“Res/Select.wav“, NULL, SND_ASYNC | SND_FILENAME);g_iTries+; g_tile2.x = iTileX; g_tile2.y = iTileY;/匹配判断if(g_iTilesg_tile1.xg_tile1.y = g_iTilesg_tile2.xg_tile2.y)/播放方块配对声音/PlaySound(L

11、PCTSTR)IDW_MATCH, hinstance_app, SND_ASYNC | SND_RESOURCE);PlaySound(“Res/Match.wav“, NULL, SND_ASYNC | SND_FILENAME);g_bTileStatesg_tile1.xg_tile1.y = true;g_bTileStatesg_tile2.xg_tile2.y = true;/清空方块选择g_tile1.x = g_tile1.y = g_tile2.x = g_tile2.y = -1;/更新配对计数,并检查是否获胜g_iMatches+;if(g_iMatches=8) /播

12、放方块配对声音/PlaySound(LPCTSTR)IDW_WIN, hinstance_app, SND_ASYNC | SND_RESOURCE);PlaySound(“Res/Win.wav“, NULL, SND_ASYNC | SND_FILENAME);TCHAR szText64;wsprintf(szText, “You won in %d tries.“, g_iTries);MessageBox(main_window_handle, szText, TEXT(“Brainiac“), MB_OK);else /播放方块配对声音/PlaySound(LPCTSTR)IDW_

13、MISMATCH,hinstance_app,SND_ASYNC|SND_RESOURCE;PlaySound(“Res/Mismatch.wav“, NULL, SND_ASYNC | SND_FILENAME);g_tile1.x = g_tile1.y = g_tile2.x = g_tile2.y = -1;InvalidateRect(main_window_handle, NULL, false);三、播放 MIDI 音乐MIDI( Musical Instrument Digital Interface)乐器数字接口,出现于 20 世纪 80 年代初期,用来建立乐器之间的标准接口

14、。当时,MIDI 的主要用途是允许一种专用的键盘控制一个电子合成器。理解 MIDI 设备的一种方式,是在输入方面将它看作一个音符发生器,在输出方面将它看作一个声音发生器。只要 MIDI 设备与一个发生或者输出音符的 MIDI 接口相连,它的内部工作方式并不重要。由此,可能有人会把 MIDI 声音的设计对比 Windows 的设备无关设计:Windows 使得混合和匹配不同类型的硬件并使之协同工作成为可能。MIDI 使得连接不同类型的音乐设备并使之协同工作成为可能。事实上,目前的声卡都包含一个与 MIDI 兼容的接口,MIDI 设备可以通过它与计算机通信。MIDI 音乐也是存储在文件中,并具有.

15、MID 文件后缀名,与 WAV 波形声音不同,midi 占用内存空间很小。在 WINDOW 下,考量到空间的大小, MIDI 格式的音乐档绝对是最佳的选择,一首五分钟的 MIDI 了不起十万字元的大小,这跟 WAV 格式一分钟占用量以 MB 计,简直是小巫见大巫,所以网站上的音乐,游戏的音乐,都很适合用 MIDI 来表现,而音乐部份我个人注重旋律,至於一首音乐本身使用到的乐器数量,我倒是很少去注意,人的耳朵听东西有一定的极限,只要不产生杂音,配合优美的旋律,大致上都可以接受。1、理解 Windows 媒体控制接口Win32 API 组合了 MIDI 音乐以及其他类型的多媒体对象,例如视频剪辑。

16、要想在Windows 程序中播放 MIDI 歌曲,必须使用一个专门的多媒体 API,它名为媒体控制接口(Media Control Interface, MCI) 。MCI 是一个高级 API,允许开发人员控制多媒体设备,例如 MIDI 合成器或者视频播放器。MCI 背后的思路是,通过向多媒体设备发送命令来与之通信。这里的命令就是执行一个特定操作的指令,例如播放、暂停、停止一首歌曲或者一个视频剪辑。MCI 实际支持两种命令:命令消息通过向多媒体设备发送一个消息来告诉它要做什么。例如,如果想要播放一首歌曲,就发送一个命令消息,在其中包括歌曲文件的名称以及播放命令。命令字符串MCIERROR mc

17、iSendString(LPCTSTR lpszCommand, /MCI 命令字符串LPTSTR lpszReturnString, /存放反馈信息的缓冲区UINT cchReturn, /缓冲区的长度HANDLE hwndCallback /回调窗口的句柄,一般为 NULL);函数若成功则返回 0,否则返回错误码,错误码可以用如下函数分析:BOOL mciGetErrorString(DWORD fdwError, /错误码LPTSTR lpszErrorText, /接收描述错误的字符串的缓冲区UINT cchErrorText /缓冲区长度);举例:char buf50;MCIERRO

18、R mciError;mciError = mciSendString(“open waveaudio“ , buf , strlen(buf) , NULL);if(mciError)mciGetErrorString(mciError , buf , strlen(buf);AfxMessageBox(buf);return;表 1 MCI 设备类型设备类型 描述animation 动画设备cdaudio CD 播放器dat 数字音频磁带机digitalvideo 某一窗口中的数字视频other 未定义的 MCI 设备overlay 重叠设备(窗口中的模拟视频)scanner 图像扫描仪s

19、equencer MIDI 序列器videodisc 视频waveaudio 播放数字波形文件的音频设备表 2 常用的 MCI命令命令 描述capacility 查询设备能力close 关闭设备info 查询设备的信息open 打开设备pause 暂停设备的播放或记录play 开始设备播放record 开始resume 恢复暂停播放或记录的设备seek 改变媒体的当前位置set 改变设置status 查询设备状态信息stop 停止设备的播放或记录6MCI设备可分为简单设备和复合设备两类。cdaudio 这样的不使用文件的设备为简单设备,而复合设备在播放时要用到数据文件。例如打开一个波形音频设备

20、:open mysound.wav type waveaudio2、使用 MCI 播放 MIDI 音乐在游戏中播放 MIDI 音乐的设备是 MIDI 合成器,它的工作是获得音乐的音符并大声播放出来。目前几乎每一块声卡都内置了一个 MIDI 合成器,因此播放 MIDI 音乐应该没有任何问题。使用 MCI 播放 MIDI 音乐的很大一部分工作是建立与 MIDI 合成设备的联系。(1)打开 MIDI 设备(2)播放 MIDI 歌曲(3)暂停 MIDI 歌曲(4)关闭 MIDI 设备在使用 MCI 处理 MIDI 设备时,要理解,设备是使用一个唯一的设备标识符引用的。因此,在打开一个 MIDI 设备以

21、播放 MIDI 音乐时,需要跟踪最初打开设备时返回的设备 ID。可以将设备 ID 看作呼叫设备并告诉它希望做什么所需的电话号码。MCIERROR mciSendCommand( MCIDEVICEID IDDevice, UINT uMsg, DWORD fdwCommand, DWORD dwParam ); (1)打开消息为 MCI_OPEN,它需要一个 MCI_OPEN_PARAMS 的特殊数据结构,其定义如下:typedef struct DWORD dwCallback; MCIDEVICEID wDeviceID; /存储了设备 ID(在打开设备时,将使用设备 ID 填写 wDev

22、iceID 成员)LPCSTR lpstrDeviceType; /打开时指定, “sequencer”,表示 MIDI 编曲器LPCSTR lpstrElementName; /打开时指定, “midi 文件名”( 这里揭示了 MCI 的一个有趣之处,在打开一个设备时就必须指定一个多媒体对象。 )LPCSTR lpstrAlias; MCI_OPEN_PARMS; 举例:UNIT uiMIDIPlayerID;MCI_OPEN_PARAMS mciOpenParms;mciOpenParms.lpstrDeviceType = “sequencer”;mciOpenParms.lpstrEl

23、ementName = “Music.mid”;If(mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT, (LPDWORD)(2)播放 MIDI 歌曲的命令是 MCI_PLAY,且需要涉及另一个数据结构 MCI_PLAY_PARMS,但是从头到尾地播放一首歌曲时,可以不必初始化这个数据结构。举例:MCI_PLAY_PARMS mciPlayParms;7mciSendCommand(uiMIDIPlayerID, MCI_PLAY, 0 , (LPDWORD)(3)暂停 MIDI 歌曲使用 MCI_PAUSE 命令举例:mc

24、iSendCommand(uiMIDIPlayerID, MCI_PAUSE, 0 , NULL );(4)关闭 MIDI 设备使用 MCI_CLOSE 命令举例:mciSendCommand(uiMIDIPlayerID, MCI_CLOSE, 0 , NULL );注意:对于播放和关闭设备,我没有阐明一点,在尝试播放一首 MIDI 歌曲时可能会遇到问题,这种情况下,在发出 MCI_PLAY 命令时,mciSendCommand()函数将返回一个值而不是 0,此时应该关闭设备,所以检查返回值并查看是否成功播放了歌曲是一种很好的做法。举例:MCI_PLAY_PARMS mciPlayParms

25、;If(mciSendCommand(uiMIDIPlayerID, MCI_PLAY, 0 , (LPDWORD)uiMIDIPlayerID = 0;/同时清空了设备 ID,防止再向该设备发送其他任何命令。3、向游戏引擎添加 MIDI 音乐支持首先,需要记录 MIDI 编曲设备 ID,并在 WinMain()中初始化为 0。UINT m_uiMIDIPlayerID;/记录 MIDI 设备 ID。当 m_uiMIDIPlayerID 不为 0,表示打开了设备,准备好播放音乐。如果为 0,则关闭了设备。其次,添加 MIDI 相关方法。/*播放 MIDI 歌曲szMIDIFileName=“时

26、表示已经开始播放了一首歌曲,并且现在暂停了播放,需要继续播放歌曲bRestart 表示如何播放歌曲,如果继续播放,则为 false;如果从头开始播放,则为 true*/void PlayMIDISong(LPTSTR szMIDIFileName, BOOL bRestart)/ See if the MIDI player needs to be openedif (m_uiMIDIPlayerID = 0) / Open the MIDI player by specifying the device and filenameMCI_OPEN_PARMS mciOpenParms;mciO

27、penParms.lpstrDeviceType = “sequencer“;mciOpenParms.lpstrElementName = szMIDIFileName;if (mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,(DWORD)else/ There was a problem, so just returnreturn;8/ Restart the MIDI song, if necessaryif (bRestart) MCI_SEEK_PARMS mciSeekParms;if (mciSend

28、Command(m_uiMIDIPlayerID, MCI_SEEK, MCI_SEEK_TO_START,(DWORD)/ Play the MIDI songMCI_PLAY_PARMS mciPlayParms;if (mciSendCommand(m_uiMIDIPlayerID, MCI_PLAY, 0, (DWORD)void PauseMIDISong()/ Pause the currently playing song, if possibleif (m_uiMIDIPlayerID != 0)mciSendCommand(m_uiMIDIPlayerID, MCI_PAUS

29、E, 0, NULL);void CloseMIDIPlayer()/ Close the MIDI player, if possibleif (m_uiMIDIPlayerID != 0) mciSendCommand(m_uiMIDIPlayerID, MCI_CLOSE, 0, NULL);m_uiMIDIPlayerID = 0;举例:Henway2第一步:void GameStart(HDC hDC) PlayMIDISong(TEXT(“Res/Music.mid“);/打开 MIDI 设备void GameEnd() CloseMIDIPlayer();/关闭 MIDI 设备第

30、二步:窗口停用时暂停 MIDI 歌曲,窗口重新激活时再次播放。void GameActivate(HWND hWindow) PlayMIDISong(TEXT(“), FALSE); /激活窗口时,继续背景音乐9void GameDeactivate(HWND hWindow) PauseMIDISong();/窗口停用时,暂停背景音乐第三步:在游戏循环中添加声效void GameCycle(HDC hDC)if (!g_bGameOver) /随机播放一个随机的汽车声音,每个游戏周期中有 1/100 的机会播放一次汽车喇叭声if(rand() % 100 = 0)if(rand() % 2

31、 = 0)PlaySound(LPCTSTR)IDW_CARHORN1, hinstance_app, SND_ASYNC | SND_RESOURCE);elsePlaySound(LPCTSTR)IDW_CARHORN2, hinstance_app, SND_ASYNC | SND_RESOURCE);第四步:重新开始游戏时,重启背景音乐void MouseButtonDown(int x, int y, BOOL bLeft)if (g_bGameOver) PlayMIDISong();/重新启动背景音乐 第五步:添加小鸡被汽车压过、游戏结束时的声效BOOL SpriteCollis

32、ion(Sprite* pSpriteHitter, Sprite* pSpriteHittee)/判断是否是小鸡发生了碰撞,本游戏汽车相互不会碰撞if (pSpriteHittee = g_pChickenSprite) / Move the chicken back to the startg_pChickenSprite-SetPosition(4, 175);/ See if the game is overif (-g_iNumLives 0)/MessageBox(main_window_handle, TEXT(“Ouch!“), TEXT(“Henway“), MB_OK);/

33、播放小鸡被撞上的声音PlaySound(LPCTSTR)IDW_SQUISH,hinstance_app,SND_ASYNC|SND_RESOURCE);else /播放游戏终止声音PlaySound(LPCTSTR)IDW_GAMEOVER,hinstance_app,SND_ASYNC|SND_RESOURCE);/ Display game over messageTCHAR szText64;wsprintf(szText, “Game Over! You scored %d points.“, g_iScore);MessageBox(main_window_handle, szTe

34、xt, TEXT(“Henway“), MB_OK);g_bGameOver = TRUE;10return FALSE;return TRUE;第六步:小鸡通过时的庆祝声效void MoveChicken(int iXDistance, int iYDistance)/使用 SND_NOSTOP 选项播放 bok 小鸡声音,这样它就不会中断其他任何正在播放的声音PlaySound(LPCTSTR)IDW_BOK, hinstance_app, SND_ASYNC | SND_NOSTOP | SND_RESOURCE);/ Move the chicken to its new positi

35、ong_pChickenSprite-OffsetPosition(iXDistance, iYDistance);/ See if the chicken made it acrossif (g_pChickenSprite-GetPosition().left 400) /播放小鸡安全通过的声音PlaySound(LPCTSTR)IDW_CELEBRATE,hinstance_app,SND_ASYNC|SND_RESOURCE);/ Move the chicken back to the start and add to the scoreg_pChickenSprite-SetPos

36、ition(4, 175);g_iScore += 150;/MessageBox(main_window_handle, TEXT(“You made it!“), TEXT(“Henway“), MB_OK);四、示例游戏Battle Office设计游戏:1、首先需要一张背景图像来显示办公室(游戏地图) 。2、游戏中包含的精灵对象有:5 个办公室同事(其中 3 个同事精灵是静止的,位于桌子后面,11它们只是出现和隐藏,而另外两个同事在办公室后面的走廊上跑来跑去) ,靶心精灵,爆炸精灵。在了解了游戏中涉及的图形对象后,下面考虑游戏必须维护的其他数据。首先,很显然,需要记录未能击中的人数,这

37、决定了游戏将在何时结束。记录击中数量也是很重要的,这样才能记录得分。同时还需要一个布尔变量来记录游戏是否已经结束。另外两个不太明显的数据与显示办公室同事的方式有关。游戏以随机的时间间隔显示 5 个不同的同事,这就使游戏有一种更自然的感觉。为了确定这些时间间隔,需要记录每一个同事的时间延迟。此外,如果随着玩的时间变长游戏就会逐渐增加难度,那么游戏会更好。因此,使用一个主延迟来慢慢缩短静止的同事在屏幕上出现的时间长度。换句话说,桌面后面的同事出现的时间慢慢变得更短,向他们开火也变得更困难。简要总结一下 Battle Office 游戏的数据需求,根据游戏的设计,游戏必须管理以下信息:1、未击中的人

38、数2、击中的人数3、表示游戏结束的布尔变量4、每个同事的延迟变量5、控制游戏难度级别的主延迟变量。代码:/GameEngine.h#pragma once#include “Sprite.h“#include “resource.h“#include #include using namespace std;/ MACROS /#define KEYDOWN(vk_code) (GetAsyncKeyState(vk_code) /记录 MIDI 设备 ID,当 m_uiMIDIPlayerID 不为 0,表示打开了设备,准备好播放音乐。如果为 0,则关闭了设备void PlayMIDISon

39、g(LPTSTR szMIDIFileName = TEXT(“), BOOL bRestart = TRUE);void PauseMIDISong();void CloseMIDIPlayer();/extern vector m_vSprites;BOOL SpriteCollision(Sprite* pSpriteHitter, Sprite* pSpriteHittee);12BOOL CheckSpriteCollision(Sprite* pTestSprite);void AddSprite(Sprite* pSprite);void DrawSprites(HDC hDC)

40、;void UpdateSprites();void CleanupSprites();Sprite* IsPointInSprite(int x, int y);*/GameEngine.cpp#include “GameEngine.h“UINT m_uiMIDIPlayerID;vector m_vSprites;void PlayMIDISong(LPTSTR szMIDIFileName, BOOL bRestart)void PauseMIDISong()void CloseMIDIPlayer()/该游戏的工作方式,没有理由需要响应任何精灵碰撞BOOL SpriteCollisi

41、on(Sprite* pSpriteHitter, Sprite* pSpriteHittee) return FALSE;/BOOL CheckSpriteCollision(Sprite* pTestSprite) void AddSprite(Sprite* pSprite) void DrawSprites(HDC hDC) void UpdateSprites()void CleanupSprites()Sprite* IsPointInSprite(int x, int y) */GameMain.cpp#include “GameEngine.h“#define WINDOW_W

42、IDTH 500#define WINDOW_HEIGHT 430Bitmap* g_pOfficeBitmap;/办公室背景图Bitmap* g_pTargetBitmap;/靶心图Bitmap* g_pPowBitmap;/爆炸图Bitmap* g_pGuyBitmaps5;/同事图Bitmap* g_pSmallGuyBitmap;/同事小图标Bitmap* g_pGameOverBitmap;/游戏结束图13Sprite* g_pTargetSprite;/靶心精灵在整个游戏过程中都是可见的Sprite* g_pPowSprite;/爆炸精灵只有在击中时才是可见的Sprite* g_p

43、GuySprites5;int g_iGuyDelay5;/每个同事的延迟变量int g_iGuyMasterDelay;/控制游戏难度级别的主延迟变量int g_iHits;int g_iMisses;BOOL g_bGameOver;/void GameStart(HDC hDC)srand(GetTickCount();/生成随机生成器种子/创建屏幕外设备环境和位图g_hOffscreenDC = CreateCompatibleDC(hDC);g_hOffscreenBitmap = CreateCompatibleBitmap(hDC,WINDOW_WIDTH, WINDOW_HEI

44、GHT);SelectObject(g_hOffscreenDC, g_hOffscreenBitmap);/创建并加载位图g_pOfficeBitmap = new Bitmap(hDC, “Res/Office.bmp“);g_pTargetBitmap = new Bitmap(hDC, “Res/Target.bmp“);g_pPowBitmap = new Bitmap(hDC, “Res/Pow.bmp“);g_pGuyBitmaps0 = new Bitmap(hDC, “Res/Guy1.bmp“);g_pGuyBitmaps1 = new Bitmap(hDC, “Res/G

45、uy2.bmp“);g_pGuyBitmaps2 = new Bitmap(hDC, “Res/Guy3.bmp“);g_pGuyBitmaps3 = new Bitmap(hDC, “Res/Guy4.bmp“);g_pGuyBitmaps4 = new Bitmap(hDC, “Res/Guy5.bmp“);g_pSmallGuyBitmap = new Bitmap(hDC, “Res/SmallGuy.bmp“);g_pGameOverBitmap = new Bitmap(hDC, “Res/GameOver.bmp“);/创建靶心、爆炸及同事精灵/靶心在到达屏幕的边界时停止。这确保

46、了不管将鼠标拖动到什么位置,靶心在屏幕上总是可见的RECT rcBounds = 0, 0, 500, 400 ;g_pTargetSprite = new Sprite(g_pTargetBitmap, rcBounds, BA_STOP);g_pTargetSprite-SetZOrder(4);AddSprite(g_pTargetSprite);/爆炸只有在击中时才会显示g_pPowSprite = new Sprite(g_pPowBitmap, rcBounds, BA_STOP);g_pPowSprite-SetZOrder(3);g_pPowSprite-SetHidden(TRUE);AddSprite(g_pPowSprite);14/靶心精灵的 z 顺序最高,然后是爆炸精灵和同事精灵g_pGuySprites0 = new

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报