游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3137|回复: 3

找扁的游戏制作教程(四)

[复制链接]

29

主题

421

帖子

436

积分

中级会员

Rank: 3Rank: 3

积分
436
发表于 2005-8-2 14:32:00 | 显示全部楼层 |阅读模式
找扁的游戏制作教程(三)的后一篇
写的太烂,请一定不要转载。多谢多谢。

STEP-04
添加了2个游戏常用功能。屏幕抓取和只允许一个实例程序的运行。参见MainApp.cpp的头2个函数。
正在归类编写界面lua+xml的文档,发现说话口头描述比书面描述要容易很多,这个说起来容易,写起来难啊。
呜呜呜!

km3d库的下载地址是
http://www.honorgames.com/down/km3dlib.zip
程序源代码和执行程序的下载地址是
http://www.honorgames.com/down/step-04.zip

这个没有资源文件了,资源文件和step-03的一样
下载后,请仔细详细耐心的阅读Reame.txt

Email:blizzardcrack@gmail.com


补充:收到Email
问:程序中是否可以使用bmp,tga,jpg等图像格式?
答:程序中是根据后缀来判断读取贴图文件的。目前支持的格式大概有BMP,TGA,JPG,PNG,DDS大概就是这些吧。如果你打算使用这些格式的文件。直接调用文件名就可以了。

问:程序为什么都是25fps啊?
答:程序是限帧的,如果不想限帧,修改APP_FRAME_LIMIT的定义为0就可以了。另Opengl渲染模式下的fps和屏幕刷新设定有关。

29

主题

421

帖子

436

积分

中级会员

Rank: 3Rank: 3

积分
436
 楼主| 发表于 2005-8-2 14:50:00 | 显示全部楼层

Re: 找扁的游戏制作教程(四)

目前,整个程序完成了如下功能
一、运行游戏程序前显示一个Splash图片。
二、只允许该程序同时启动一个实例。
三、程序运行时抓图。
四、2D游戏界面的XML定位+lua脚本响应消息,输入框实现,按钮消息响应。
五、打包文件的读取和非打包文件的混合读取。
六、背景音乐的播放和按钮音乐效果的播放。
七、3D动画模型的读取渲染播放。
八、粒子效果的实现。
九、(系统/非系统)字体的载入和渲染。
十、用户自定义D3D或者Opengl渲染模式的切换。

总是让我凑出个整数特色来。嘿嘿嘿。不得不提起的是,目前游戏程序中,没有用到对d3d或者opengl的调用。不过下面的章节将会少量用到一些。我还是没有办法完全将d3d和opengl的接口封装。

step-04抓图如下
sf_200582144959.jpg

29

主题

421

帖子

436

积分

中级会员

Rank: 3Rank: 3

积分
436
 楼主| 发表于 2005-8-4 07:21:00 | 显示全部楼层

Re: 找扁的游戏制作教程(四)



  1. // 包含km3d引擎的头文件
  2. #include "AppInclude.h"
  3. #include "MainApp.h"
  4. // 包含资源文件[例如应用程序图标,已经程序的版本信息]
  5. #include "resource.h"
  6. // 定义的一些全局变量的东西,我都塞到这个结构里面了
  7. #include "GlobalFunction.h"
  8. // 程序开始的时候希望显示一段Splash界面
  9. #include "SplashWindow.h"
  10. // 包含鼠标控制,打算使用自己而不是系统的鼠标样子
  11. #include "GameCursor.h"       
  12. // 游戏主菜单界面[我把游戏状态分为主选菜单状态,游戏Loading状态和游戏状态]
  13. #include "MainMenuWnd.h"


  14. // 以下的应用程序主窗口和句柄我总是很多时候要用到的
  15. MainApp *        g_pApp  = NULL;       
  16. HINSTANCE        g_hInst = NULL;

  17. // 得到程序版本号
  18. int GetAppVersion(const char *pFileName)
  19. {
  20.         // 实现具体参见源代码
  21.         // 从该exe文件中得到该程序的版本信息,制作信息等等
  22. }

  23. // 装载Config设置
  24. BOOL LoadAppConfig()
  25. {
  26.         // 装载配置文件,实现参见源代码
  27.         // 从xml配置文件中获取,例如渲染模式OGL/D3D
  28.         // 或者全屏幕还是窗口运行
  29.         // 是否显示fps
  30.         // 以及程序窗口分辨率的大小等等
  31.         KM3D_XMLHANDLE*        pXmlHandle = KM3D_XmlHandle_Create("config.xml");
  32. }

  33. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR /* lParam */, INT /* nCmdShow */)
  34. {
  35.         MainApp d3dApp;
  36.         g_pApp  = &d3dApp;
  37.         g_hInst = hInst;

  38.         if( FAILED(CoInitialize(NULL)))return FALSE;
  39.         // 初始化随机的种子[游戏总是会出现随机的地方,种子先]
  40.         srand( (unsigned)time( NULL ) );

  41.         // 初始化声音
  42.         KM3D_InitSound();

  43.         // 初始化游戏全局脚本
  44.         g_Globle.pLuaWrap = new LuaWrap;
  45.         if(g_Globle.pLuaWrap == NULL
  46.                 || g_Globle.pLuaWrap->LoadFile("Data\\GlobalFunc.lua") == FALSE )
  47.         {
  48.                 return FALSE;
  49.         }

  50.         // 装载应用程序配置
  51.         if(LoadAppConfig() == FALSE)return FALSE;

  52.         // 获得程序版本号
  53.         d3dApp.m_nAppVersion = GetAppVersion("QYClient.exe");
  54.         if(d3dApp.m_nAppVersion == 0)d3dApp.m_nAppVersion = 3925;
  55.         sprintf(d3dApp.m_szAppVersion, "Qi Yuan Version %d", d3dApp.m_nAppVersion);
  56.         g_Globle.nAppVersion = d3dApp.m_nAppVersion;
  57.         // 设置打算使用的应用程序标题
  58.         d3dApp.SetWindowsTitel(d3dApp.m_szAppVersion);

  59.         // 显示一段Splash图片界面,在显示游戏窗口前
  60.         SplashWindow::S_ShowSplashWindow();

  61. #ifdef _DEBUG
  62.         // 如果是Debug模式,强制使用窗口模式运行
  63.         g_pApp->SetFullScreen(FALSE);
  64. #endif

  65.         // 建立游戏窗口,并向km3d引擎注册全局lua脚本,以便km3d引擎能够使用这些脚本
  66.         if( FAILED( d3dApp.CreateScreen( g_hInst,
  67.                 "Qi Yuan II Class",
  68.                 TRUE,
  69.                 LoadIcon( hInst, MAKEINTRESOURCE(IDI_QIYUCLIENT) ),
  70.                 (PFCALLREGAPPLUAFUNCTION)RegisterGlobalLuaFunc) ) )
  71.         {
  72.                 return FALSE;
  73.         }

  74.         // 设置游戏fps定帧,如果不需要,修改APP_FRAME_LIMIT定义为0
  75.         d3dApp.SetLimitFps(APP_FRAME_LIMIT);

  76.         return d3dApp.Run();
  77. }

  78. MainApp::MainApp(void)
  79. {
  80.         //...
  81.         //...
  82.         // 设置抓取屏幕开关关闭
  83.         m_bScreenShotFlag = FALSE;
  84. }

  85. MainApp::~MainApp(void)
  86. {
  87.         KM3D_SAFE_DELETE_ARRAY(m_pEnglistTextureData);
  88.         KM3D_FontHandle_Close(m_pSytemFont);
  89.         KM3D_FontHandle_Close(m_pDefaultFont);
  90.         m_pDefaultFont = NULL;
  91. }

  92. HRESULT MainApp::ConfirmDevice( D3DCAPS9* pCaps, uint32 dwBehavior,
  93.         D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat )
  94. {
  95.         // d3d设备确认
  96.         // d3d模式下需要或者不需要,opengl模式下直接返回好了
  97. }

  98. HRESULT MainApp::OneTimeSceneInit()
  99. {
  100.         // 注意这里不要初始化和设备相关的
  101.         // 例如读取设置其他游戏数据信息等等
  102.         // 好比读取某些数据配置文件等.网络初始化也可以放在这里,但是不建议放在这里
  103. }

  104. HRESULT MainApp::InitDeviceObjects()
  105. {
  106.         // 初始化和设备相关的东西,例如贴图,模型等
  107.         HRESULT hr;
  108.        
  109.         // 如果用km3d引擎,这个需要放在本函数的开始,因为km3d它自己要初始化一些东西
  110.         if(FAILED (hr = KM3D_InitDeviceObjects() ) )
  111.         {
  112.                 return hr;
  113.         }

  114.         // 我们开始读取一张字体的贴图
  115.         // 该贴图必须放在data目录下.程序会先找相应的目录下的文件,
  116.         // 如果找不到则到Textures的包文件中去读取
  117.         long nWidth, nHeight;
  118.         if( KM3D_Texture_LoadToBuffer("Textures\\Font\\DefaultFont.blp",
  119.                 &m_pEnglistTextureData, nWidth, nHeight) == FALSE )
  120.                 return E_FAIL;

  121.         // 初始化一个非系统安装的字体,也许游戏中我们想要自己定义一个字体
  122.         char szFontName[128];
  123.         char szFontPathName[MAX_PATH];
  124.         strncpy(szFontName,
  125.                 g_Globle.pLuaWrap->GetGlobal<const char*>("DEFALUT_FONT_FILENAME"), 128);
  126.         _snprintf(szFontPathName, MAX_PATH, "Fonts\\%s", szFontName);
  127.         DeleteFile("QIYUN_D.FOT");
  128.         CreateScalableFontResource(1, "QIYUN_D.FOT", szFontName, "Fonts");
  129.         if( AddFontResource(szFontPathName) == 0)return E_FAIL;

  130.         m_pDefaultFont = KM3D_FontHandle_Create(
  131.                         g_Globle.pLuaWrap->GetGlobal<const char*>("DEFALUT_FONT_FACENAME"),
  132.                         m_pEnglistTextureData);
  133.         if(m_pDefaultFont == NULL)return E_FAIL;
  134.         if(FAILED ( hr = KM3D_Font_InitDevice(m_pDefaultFont) ) )
  135.         {
  136.                 return hr;
  137.         }

  138.         // 添加一种系统字体[注意请自行判断系统中是否有该字体]
  139.         m_pSytemFont = KM3D_FontHandle_Create(
  140.                 g_Globle.pLuaWrap->GetGlobal<const char*>("SYSTEM_FONT_FACENAME"),
  141.                 m_pEnglistTextureData);
  142.         if(m_pSytemFont == NULL)return E_FAIL;
  143.         if(FAILED ( hr = KM3D_Font_InitDevice(m_pSytemFont) ) )
  144.         {
  145.                 return hr;
  146.         }

  147.         // 装载游戏的鼠标
  148.         // 为什么用3d模型文件来做鼠标呢?参照readme说明,我这里极力推荐
  149.         g_pGameCursor = new GameCursor;
  150.         if( g_pGameCursor == NULL
  151.                 || !g_pGameCursor->Load("Interface\\Cursor\\Cursor.mdx")
  152.                 || FAILED(g_pGameCursor->InitDeviceObjects() ) )
  153.         {
  154.                 return E_FAIL;
  155.         }

  156.         g_pMainMenuWnd = new MainMenuWnd;
  157.         if(g_pMainMenuWnd==NULL
  158.                 || g_pMainMenuWnd->Init() == FALSE
  159.                 || FAILED(g_pMainMenuWnd->InitDeviceObjects()) )
  160.         {
  161.                 return E_FAIL;
  162.         }

  163.         // 将游戏的界面状态设置为主选菜单窗口
  164.         g_Globle.nGameStata = S_MAIN_MENU_WND;

  165.         // 初始化所有的模型和贴图相关的东西
  166.         // 为什么需要这样做了, 这里是对调入模型和贴图进行一个规整.
  167.         // 也就是统个计,排个序什么的

  168.         // 当然因为km3d引擎也都提供d3d和ogl接口,所以如果你打算自己管理,也没有问题
  169.         // 这里的管理只是针对偷懒的调入
  170.         KM3D_MDX_InitDeviceObject_All();
  171.         KM3D_Texture_InitDeviceObject_All();
  172. }

  173. HRESULT MainApp::RestoreDeviceObjects()
  174. {
  175.         // 恢复设备内容, 除非你自己管理的设备内容,否则引擎已经自己会恢复的
  176. }

  177. HRESULT MainApp::InvalidateDeviceObjects()
  178. {
  179.         // 使设备无效, 除非你自己管理的设备内容,否则引擎已经自己会恢复的
  180. }

  181. HRESULT MainApp::DeleteDeviceObjects()
  182. {
  183.         // 退出游戏前,清理一下设备里面的内容
  184.         // ..
  185.         // ..

  186.         // 让引擎自己清理一下引擎内部自己创建的
  187.         KM3D_MDX_DeleteDeviceObject_All();
  188.         KM3D_Texture_DeleteDeviceObject_All();
  189. }


  190. // 关闭程序前,你要做的一些扫尾工作
  191. HRESULT MainApp::FinalCleanup()
  192. {
  193.         // 参见代码实现
  194. }

  195. HRESULT MainApp::FrameMove()
  196. {
  197.         // 这里抓图
  198.         if(m_bScreenShotFlag)
  199.         {
  200.                 m_bScreenShotFlag = FALSE;
  201.                 KM3D_ScreenShot();
  202.         }

  203.         // 计算和渲染是分开的,意思就是算好了一起画,而不要一边计算一边画,那时傻子做的事
  204.         // 参见代码实现
  205. }

  206. // 描述: 渲染部分
  207. HRESULT MainApp::Render()
  208. {
  209.         HRESULT hr;
  210.         // 清理一下屏幕
  211.         if(FAILED (hr = KM3D_3D_ClearScreen(0L, NULL,
  212.                 D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0, 1.0f, 0L) ) )return hr;
  213.         // 通知引擎说,我打算开始要画东西了,让其准备一下.意思就是说我要尿尿了,你端个盆来
  214.         if(FAILED (hr = KM3D_3D_BeginScreen() ) )return hr;

  215.         // 告诉引擎,我下面要画3D的东西
  216.         KM3D_Set3DView_Start(g_Globle.matWorld);
  217.         // 开始画3D的东西
  218.         KM3D_Set3DView_End();
  219.         // 画3D的东西结束


  220.         // 告诉引擎,我下面要画2D的东西
  221.         KM3D_Set2DPlaneView_Start();
  222.         // 开始画2D的东西
  223.         KM3D_Set2DPlaneView_End();
  224.         // 画2D的东西结束

  225.         // 通知引擎说,我画完东西了,让其结束一下.意思就是说我要尿完了,你端个盆走吧
  226.         if(FAILED (hr = KM3D_3D_EndScreen() ) )return hr;
  227.         return S_OK;
  228. }

  229. // 处理窗口消息[所有的键盘鼠标事件,网络消息等等等等]
  230. LRESULT MainApp::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
  231.                                                  LPARAM lParam )
  232. {
  233.         // 开始的时候,纪录以下鼠标位置
  234.         // 在GameCursor种告诉引擎不知道鼠标位置,这个放在第一步处理
  235.         switch( msg )
  236.         {
  237.         case WM_MOUSEMOVE:
  238.                 if( m_bActive )
  239.                 {
  240.                         POINT ptCursor;
  241.                         GetCursorPos( &ptCursor );
  242.                         if( g_pApp->GetAppIsWindow() )ScreenToClient( hWnd, &ptCursor );
  243.                         g_pGameCursor->SetPos(ptCursor);
  244.                 }
  245.                 break;
  246.         case WM_SETCURSOR:
  247.                 {
  248.                         SetCursor( NULL );
  249.                         return 1;
  250.                 }
  251.                 break;
  252.         }
  253.        
  254.         // 然后处理各个窗口的消息
  255.         // 将这些window信息传递给相应的界面窗口
  256.         switch(g_Globle.nGameStata)
  257.         {
  258.         case S_MAIN_MENU_WND:
  259.                 {
  260.                         if(g_pMainMenuWnd)
  261.                         {
  262.                                 g_pMainMenuWnd->MsgProc(hWnd, msg, wParam, lParam);
  263.                         }
  264.                 }
  265.                 break;
  266.         case S_LOADING_WND:
  267.         case S_GAME_WND:
  268.                 break;
  269.         }

  270.         // 如果上面没有处理的消息,交给引擎处理以下,
  271.         // 其实里面就只是处理的一些窗口大小变化,是否窗口激活隐藏
  272.         // close窗口等信息
  273.         // 如果你不愿意他处理,那么自己接管,不要调用下面的就可以了
  274.         return KM3DScreen::MsgProc( hWnd, msg, wParam, lParam );
  275. }

复制代码

29

主题

421

帖子

436

积分

中级会员

Rank: 3Rank: 3

积分
436
 楼主| 发表于 2005-8-4 07:32:00 | 显示全部楼层

Re: 找扁的游戏制作教程(四)


  1. #include "AppInclude.h"
  2. #include "GameCursor.h"
  3. #include "MainApp.h"

  4. //全局的,因为游戏中始终用到这个,一般来说也只有一个
  5. GameCursor* g_pGameCursor = NULL;

  6. GameCursor::GameCursor(void)
  7. {
  8.         // 是否显示
  9.         m_bShow = TRUE;
  10.         // 鼠标模型
  11.         m_pModel = NULL;
  12. }

  13. GameCursor::~GameCursor(void)
  14. {
  15.         DeleteDeviceObjects();
  16. }

  17. // 装载鼠标
  18. // 参数 * 鼠标名称
  19. BOOL GameCursor::Load(const char *szFileName)
  20. {
  21.         m_pModel = KM3D_ModelMdx_CreateHandel(szFileName);
  22.         if(m_pModel == NULL)return FALSE;

  23.         // 0.78125f.根据模型做的一些调整。你可以在制作鼠标模型的时候注意
  24.         // 也可以将该参数放在其他配置文件中
  25.         m_vScale = D3DXVECTOR3(KM3D_Screen_GetScreenWidthScale()*0.78125f,
  26.                         KM3D_Screen_GetScreenWidthScale()*0.78125f,
  27.                         1.0f);
  28.         //你可以尝试使用SetAnimateByID(1-12)看看不同的鼠标效果
  29.         默认初始化是0

  30.         return TRUE;
  31. }

  32. // 根据编号设置播放动画
  33. BOOL GameCursor::SetAnimateByID(uint32 dwID)
  34. {
  35.         // 根据需要变化鼠标形状状态等
  36.         return KM3D_MDX_SetAnimateByID(m_pModel, dwID);
  37. }

  38. // 根据名称设置播放动画
  39. BOOL GameCursor::SetAnimateByName(const char *pszAnimateName)
  40. {
  41.         // 根据需要变化鼠标形状状态等,这个是根据动画名称变化的
  42.         return KM3D_MDX_SetAnimateByName(m_pModel, pszAnimateName);
  43. }

  44. // 设置当前鼠标位置
  45. void GameCursor::SetPos(POINT ptCursor)
  46. {
  47.         m_ptCursor = ptCursor;
  48.         // 告诉引擎当前的鼠标位置,
  49.         // 如果引擎不知道的话,所有的界面都不会相应消息了
  50.         KM3D_Screen_SetCursorPos((float)m_ptCursor.x, (float)m_ptCursor.y);

  51.         // 设置以下鼠标的矩正
  52.         D3DXVECTOR3 vTran = D3DXVECTOR3(
  53.                 -KM3D_Screen_GetScreenWidth()/2.0f+(float)ptCursor.x,
  54.                 KM3D_Screen_GetScreenHeight()/2.0f-(float)ptCursor.y, 0.0f);

  55.         // 这里借用了d3d的矩正函数,可以替换成你自己的
  56.         D3DXMatrixTransformation(&m_Matrix,
  57.                 NULL,
  58.                 NULL,
  59.                 &m_vScale,
  60.                 NULL,
  61.                 NULL,
  62.                 &vTran);
  63. }

  64. HRESULT GameCursor::InitDeviceObjects(){...}
  65. HRESULT GameCursor::RestoreDeviceObjects(){...}
  66. HRESULT GameCursor::DeleteDeviceObjects()
  67. {
  68.         KM3D_ModelMdx_CloseHandel(m_pModel);
  69.         m_pModel = NULL;//你需要自己设置为NULL,避免出错
  70.         return S_OK;
  71. }

  72. void GameCursor::FrameMove()
  73. {
  74.         if(m_bShow)KM3D_MDX_FrameMove(m_pModel);
  75. }

  76. // 渲染
  77. void GameCursor::Render()
  78. {
  79.         if(m_bShow)KM3D_MDX_Render(m_pModel, &m_Matrix);
  80. }

复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-26 16:29

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表