C++实验指导书.docx
- 文档编号:3729436
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:34
- 大小:1.45MB
C++实验指导书.docx
《C++实验指导书.docx》由会员分享,可在线阅读,更多相关《C++实验指导书.docx(34页珍藏版)》请在冰豆网上搜索。
C++实验指导书
一、简介
1.本设计采用MicrosoftVisualC++6.0编译,并能够在WIN98,WIN2000下运行
2.游戏基于WindowsGameEngine(WGE游戏引擎,添翼虎科技)(没提供源程序,不过不用担心,你可以把它看成是利用DirectX快速处理图片、声音、键鼠的类库),该引擎需要DirectX7.0SDK支持(仅有Runtime运行库不够,必须包含开发语言需要的Header&Libs头文件和库文件)
二、开发软件的安装:
1.安装VisualC++6.0
2.安装DirectXSDK:
思路:
Runtime与Header&Libs必须配套,且高于7.0版本。
由于DirectX不太容易卸载,所以建议安装高于当前系统Runtime的DirectX(升级当前DirectXRuntime,并补上Header&Libs)
1)检查当前DirectX版本:
windows下“开始”|“运行”|dxdiag
2)如果版本低于9.0c安装,安装(90COK)directx_9c_Jun05sdk_redist.exe以升级运行库;安装适合c++的SDK:
dx9sdkcp.exe(运行类型:
Retail速度快;Debug便于调试),建议装在c:
\dxsdk。
3)检查DirectXSDK安装是否正确:
运行dxdiag|“显示”|“测试DirectXDraw”,确保2D显示正确。
(以后若用到3D,至少要保证DirectX3D7正确。
)
3.安装WGE游戏引擎:
WgeSetup,建议安装在c:
\wgesdk
4.设置VC++6.0环境,以便找到上述SDK的头文件和库文件:
1)VC++6.0|“Tools”|“Option”,选Directors(路径)(缺省的“ShowDirectoriesfor”列表为“Includefiles”),加入DirectXSDK和WGE游戏引擎的头文件路径:
c:
\dxsdk\include(注意要移到首行,以便优先于VC自带的旧文件),c:
\wgesdk\include,见下图:
从“ShowDirectoriesfor”列表选“Libraryfiles”,加入c:
\dxsdk\lib,c:
\wgesdk\lib,见下图:
5.测试所有软件安装是否正确:
1)VC|File|New|Project|WindowsGameEngineSDKAppWizard工程向导,输入工程名Test和路径|OK;
2)输入屏幕宽(必须偶数)、高为400,300,游戏名Test,显示模式GDI_MODE(窗口模式,当前显示设置不应少于16bit),见下图:
4)finish完成。
编译:
VC|“Build”|“BuildTest.exe”,运行:
“Build”|“ExecuteTest.exe”,看到如下界面表示上述安装正确(ESC退出):
三、熟悉WGE游戏引擎的使用
1.以上向导生成的游戏框架的代码:
//==================================================================
//Test.cpp:
//该文件由WindowGamesEngineSDK向导生成
#include"stdafx.h"//引用预编译头文件,注意每个CPP文件都应该引用它
LPSTRTITLE="WGEDemo";//游戏窗口标题
LPSTRICON=(LPSTR)IDI_DEMO;//游戏窗口的图标
LPSTRNAME="Test";//游戏窗口类名
//===================================================================
//当游戏结束时,系统会调用该函数,主要用于释放自己分配的内存
voidExitGame()
{
//在此加入游戏代码
//以下内容不要删除
EAudio:
:
Destroy();
WGE_Input.Destroy();
}
//====================================================================
//初始化函数,当游戏开始运行时系统会调用该函数,主要用于初始化屏幕、声音、输入设备、加载游戏资源等
//成功返回TRUE,失败返回FALSE,游戏退出
BOOLInitGame()
{
intwidth=400;//屏幕宽度
intheight=300;//屏幕高度
//设置游戏屏幕显示模式
WGE_pScreen->CreateScreenDisplay(width,height,GDI_MODE);
//初始化声音
EAudio:
:
Init();
//初始化键盘和鼠标设备
WGE_Input.Init();
//以下加入游戏初始化代码
returnTRUE;
}
//=============================================================
//主循环。
《在该向导生成的程序中看不到标准WIN32程序中的消息循环,同样也看不到WinMain(并不是没有,而是被封装在WGESDK中了),不用奇怪,MFCAppWizard也是这么做的,请自行研究(搜索含WinMain的cpp文件,设断点,跟踪)。
BOOLGameLoop()
{
WGE_Input.GetKeyboardState();//读取键盘状态
WGE_Input.GetMouseState();//读取鼠标状态
WGE_Surface.Clear(255,255,255);//清屏幕
//以下加入游戏代码
returnTRUE;
}
2.WGE框架流程如下:
3.通过实例研究WGE的使用
用VC打开c:
\wgesdk\examples\demo下的demo.dsp工程,编译运行,效果如下:
鼠标左键爆炸声、右键MIDI、鼠标移动则士兵移动、键盘光标键移动圆环。
代码如下(带阴影的是在向导基础上增加的):
//==================================================================
//Demo.cpp:
//该文件由WindowGamesEngineSDK向导生成
#include"stdafx.h"//引用预编译头文件,注意每个CPP文件都应该引用它
LPSTRTITLE="WGEDemo";//游戏窗口标题
LPSTRICON=(LPSTR)IDI_DEMO;//游戏窗口的图标
LPSTRNAME="DEMO";//游戏窗口类名
//___________全局变量GLOBALS_________________
ESurfacesBack;//背景《由内存模拟的屏幕,多个虚拟屏幕分别处理后叠加到“物理屏幕”WGE_pScreen的“缓冲区”(图面)WGE_Surface上(也同样是WGE_Surface对象)》
ESurfacesLight;//光照
ESurfacesRing;//圈
ESurfacesRing0;//圈
EGroupPicgArms;//兵士《多幅同尺寸(只是走动方向、动作不同)图片,形成动画的不同帧。
游戏中很多活动的东西不是用视频文件实现的、也不是由程序实时画的,而是美工事先画好不同图片,然后切换》
EPGeTank;//坦克《多幅不同尺寸(将来会有更强的大坦克)图片,
EMusicmTest;//音乐
ESoundsndBomb;//音效《玩过DOS游戏的都知道设置声音和音乐是不同的》
//===================================================================
//当游戏结束时,系统会调用该函数,主要用于释放自己分配的内存
voidExitGame()
{
//在此加入游戏代码
sBack.Destroy();
sLight.Destroy();
sRing.Destroy();
sRing0.Destroy();
eTank.Destroy();
gArms.Destroy();
mTest.Destroy();
sndBomb.Destroy();
//以下内容不要删除
EAudio:
:
Destroy();
WGE_Input.Destroy();
}
//====================================================================
//初始化函数,当游戏开始运行时系统会调用该函数,主要用于初始化屏幕、声音、输入设备、加载游戏资源等
//成功返回TRUE,失败返回FALSE,游戏退出
BOOLInitGame()
{
intwidth=400;//屏幕宽度
intheight=300;//屏幕高度
//设置游戏屏幕显示模式
WGE_pScreen->CreateScreenDisplay(width,height,GDI_MODE);//《WGE_pScreen是WGESDK预先设置的代表物理屏幕的唯一EScreen对象(内含一个width*height尺寸的Esurface对象WGE_Surface,代表屏幕缓冲区(图面)),作用1是设置显示模式,作用2是把缓冲区(图面)画到物理屏幕上。
多个虚拟屏幕Esurface对象自己处理好以后就依次往WGE_Surface上画》
//初始化声音
EAudio:
:
Init();
//初始化键盘和鼠标设备
WGE_Input.Init();
//以下加入游戏初始化代码
//加载JPG图像
if(!
sBack.LoadJPG("../media/back.jpg",0,NULL))//《图片资源在同层的media目录下(两点表示当前目录,一点表示上层目录,大家可以把media改到demo目录下)》
{
:
:
MessageBox(WGE_hWndMain,"加载back.jpg文件失败","错误",0);
returnFALSE;
}
//加载BMP图像
if(!
sLight.LoadBMP("../media/light.bmp",0,NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载light.bmp文件失败","错误",0);
returnFALSE;
}
//加载PSD图像
if(!
sRing.LoadPSD("../media/ring.psd",SF_ALPHA,NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载ring.psd文件失败","错误",0);
returnFALSE;
}
//加载PSD文件中和第0层图像
if(!
sRing0.LoadPSD("../media/ring.psd",SF_ALPHA,0,NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载ring.psd文件第0层失败","错误",0);
returnFALSE;
}
//加载EPG格式的图像《WGE自己的格式,对应EPG对象》
//if(!
eTank.Load("../media/tank24.epg",NULL))
if(!
eTank.Load("../media/1.epg",NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载tank.epg文件失败","错误",0);
returnFALSE;
}
//加载GRP格式的图像《WGE自己的格式,对应EGroupPic对象》
if(!
gArms.Load("../media/armswalk.grp",NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载armswalk.grp文件失败","错误",0);
returnFALSE;
}
//加载MIDI音乐
if(!
mTest.LoadMidi("../media/test.mid",NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载bomb.wav文件失败","错误",0);
returnFALSE;
}
//加载声音
if(!
sndBomb.LoadWave("../media/bomb.wav",1,0,NULL))
{
:
:
MessageBox(WGE_hWndMain,"加载bomb.wav文件失败","错误",0);
returnFALSE;
}
returnTRUE;
}
//=============================================================
//主循环。
BOOLGameLoop()
{
WGE_Input.GetKeyboardState();//读取键盘状态
WGE_Input.GetMouseState();//读取鼠标状态
WGE_Surface.Clear(255,255,255);//清屏幕
//以下加入游戏代码
//显示水平滚动的背景
staticintx;《思考一下静态变量的作用?
》
WGE_Surface.Blt(sBack,x,0);//《Esurface类最重要的函数是多个重载函数Blt。
其主要形式是“目标图面.Blt(源对象,x,y)”,源对象包括ESurface,EGroupPic,EPG,作用是把源对象画到目标图面的(x,y)位置,另外还有一些带帧、透明度Alpha等重载形式》
WGE_Surface.Blt(sBack,x-400,0);
WGE_Surface.Blt(sBack,x+400,0);//《目的是让背景图头尾相接,因为Blt会自动裁剪》
++x%=400;//《背景图不断移动》
//把士兵做为鼠标《把小人画到鼠标当前位置》
staticDWORDdwArmsTimer;
statici,j;
//让动画每100ms动一次《士兵改变方向。
同样游戏世界中的状态演变也不是依赖GameLoop的循环速度(机器快慢),而是采用定时器》
if(GetTickCount()-dwArmsTimer>100)
{
dwArmsTimer=GetTickCount();
++i%=gArms.GetFrameCount();
}
WGE_Surface.Blt(gArms,i,WGE_Input.MouseX(),WGE_Input.MouseY());
//如果单击鼠标左键,播放声音
if(WGE_Input.ButtonClick(BUTTON_LEFT_MASK))
{
sndBomb.Play();
}
//如果单击鼠标右键,播放MIDI音乐
if(WGE_Input.ButtonClick(BUTTON_RIGHT_MASK))
{
if(mTest.IsPlaying()==FALSE)
mTest.Play();
}
//处理键盘,移动坦克
staticinttank_x,tank_y;
if(WGE_Input.Key()[DIK_UP])
tank_y--;
if(WGE_Input.Key()[DIK_DOWN])
tank_y++;
if(WGE_Input.Key()[DIK_LEFT])
tank_x--;
if(WGE_Input.Key()[DIK_RIGHT])
tank_x++;
if(WGE_Input.Key()[DIK_PGUP])
++j%=eTank.GetFrameCount();
//显示坦克
WGE_Surface.Blt(eTank,j,tank_x,tank_y);
//显示光照效果
WGE_Surface.Additive(sLight,x,100);
//显示圈
WGE_Surface.Blt(sRing,100,50);
WGE_Surface.Blt(sRing0,0,50);
//显示绿色文字
WGE_Surface.SetDrawColor(0,255,0);
WGE_Surface.OutTextXY(0,300-8,"ClickLEFTbuttontoplaybomb.wavandRIGHTbuttonplaytest.mid");
returnTRUE;
}
4.研究WGE游戏引擎的使用—坦克大战(TankWar)的实现
WGE游戏引擎提供了一个游戏开发框架,但你可以把它看成是利用DirectX快速处理图片、声音、键鼠的类库。
按照MVC的观点,游戏的“视图层”(游戏界面)与其联系最为紧密,因此我们先这里入手,研究WGE游戏引擎的实际应用。
(游戏规则显然属于“模型层”,但模型层中最重要的的部分(也是我们学习的重点)是游戏对象的设计(类层次、交互),为此我把这部分单独抽出来写在“TankWar剖析.doc(或pdf)”中,以期引起同学们的注意;另外本文后面介绍的‘状态机‘是否可以理解成“控制层”呢?
)
4.1游戏规则及资源准备
由于需要“观众”参与,所以除了有剧本外,游戏还比电影多一个规则。
剧情:
“玩家坦克”打掉“邪恶源
”即可过关。
(共3关,可循环玩)
游戏规则:
1)玩家坦克
移动:
4个方向箭头,“机动力”由升级次数决定
型号:
“青铜战士”,“白银战士”,“黄金战士”
防护:
由“经验值(打掉木箱,捡
)”决定“最大防护值”,捡恢复物品
可提高当前防护值
武器:
左ctrl开火,只有“光弹”(匀速),“射程”由型号决定,“破坏力”由“金钱数(捡
)”决定
2)敌军坦克
总之有3种:
双导弹、单导弹、火坦克,性能各有所长。
3)“邪恶源”
防护值很大
4)木箱
5)奖励物品
恢复、金钱、升级
6)背景地图
草地、泥地、白石头、黑石头、白石高地(地形障碍)
列出上述角色所需的资源(图片、声音)需求,请美工、乐师制作:
1)角色图片24x24像束,地形块48x48
2)活的角色都要有多帧图片,其中有方向性(坦克、子弹)的也事先画好不同方向的不同活动效果的多帧图片(如“火弹”有4个方向,每方向3帧)
3)除4种地形图片外,还应有过渡图片,如白石与泥地在左上方向的过渡
上述资源都在TankWar\DATA下(建议把C:
\WGESDK\TOOLS下的几个EXE也拷过来),执行makeres.bat可将资源打包成游戏资源文件gamedata.gdp.
4.2地图设计和实现(不要求掌握)
采用TILE地图:
由小图拼大图,但要考虑图块间的平滑过渡,这由地图编辑器mapedit处理(类似于插值)。
地图编辑器生成地图文件*.map(每关一个),保存地形拼接信息和敌我态势(必须有一个“始”和“邪恶源”)
4.3坦克大战主框架
游戏进程由一个状态机控制:
externGAME_STATUSg_game_status;//游戏状态,其定义为:
enumGAME_STATUS{//《状态机
GAME_MAINMENU,//主菜单状态
GAME_SHOWINFO,//显示游戏信息
GAME_LOADING,//加载资源状态
GAME_PLAY,//玩游戏状态
GAME_QUIT,//退出状态
GAME_OVER,//失败
GAME_STAGECLEAR//过关状态
};
4.3.1初始化InitGame()
BOOLInitGame()
{
intwidth=400;//屏幕宽度
intheight=300;//屏幕高度
//设置游戏屏幕显示模式
//《先尝试全屏,再窗口模式,建议只用窗口模式GDI_MODE,好调试》
if(WGE_pScreen->CreateScreenDisplay(width,height,TV_MODE))
TRACE(0,"SELECTTV_MODE");
elseif(WGE_pScreen->CreateScreenDisplay(width,height,GDI_MODE))
TRACE(0,"SELECTGDI_MODE");
else
{
MessageBox(NULL,"设置显示模式错误","错误",MB_OK);
returnFALSE;
}
//初始化声音
EAudio:
:
Init();
//初始化键盘和鼠标设备
WGE_Input.Init(IDF_NONEXCLUSIVE|IDF_FOREGROUND,NULL);//《没用鼠标,所以null》
//以下是加入的游戏初始化代码
//用黑色清除屏幕
WGE_Surface.Clear(0,0,0);
//打开数据包文件《通过EDataFile对象访问资源包gamedata.gdp》
TRACE(0,"打开数据包文件gamedata.gdp");
g_pData=NEWEDataFile;
if(g_pData->Open("gamedata.gdp")==FALSE)
{
MessageBox(NULL,"打开gamedata.gdp错误","错误",MB_OK);
deleteg_pData;
returnFALSE;
}
//设置游戏状态为主菜单
g_game_status=GAME_MAINMENU;
returnTRUE;
}
接着进入主循环GameLoop()
4.3.2主循环GameLoop()
自动循环,根据g_game_status调相应函数,进行状态转换。
所以本质上就是一个CASE语句。
--------------------游戏代码-----------------------
#include
#include
#include
#include
#include
#defineKEY_ESC0x01
#defineKEY_SPACE0x39
#defineKEY_UP0x48
#defineKEY_LEFT0x4b
#defineKEY_RIG
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 实验 指导书