【DirectX 2D游戏开发基础】DirectX的应用实例
2015-08-26 23:25
507 查看
这次,主要就是利用前面几篇博客里面的例子,来做几个应用练习,主要就是,让图片闪烁,一次读取多张图片,和使用随机数随机读取图片(当然,这里的随机数用的是C语言,而不是C++的随机数引擎,但是原理是一样的),这次,我把我的代码工程上传上来,希望大家下载学习,毕竟 里面会涉及到一些资源问题,把代码复制去了,改起来挺麻烦也。地址:http://download.csdn.net/detail/shangdi712/7704977
这里,关于第一个知识点,我要说明一下,我们都知道,生成窗口的时候,窗口都是带边框的,而我们在CreateWindow函数中定义的窗口的小是带边框的大小,所以我们要使用GetClientRect这个函数GetClientRect这个函数,我们可以把它写到onRander函数里,然后打断点,看返回值,假如你写的是800*600,但是函数返回来的是750*550,那我们,写代码的时候,就将定义窗口大小那,换成800+50和600+50即可,这样的话,我们得到的客户区大小就是800*600 ,而不是加上那个边框后的大小,之后删掉这个函数就行了,这就是它的用法
这个代码中,我们将图片所用到的信息放到一个结构体中,到时候,创建结构体对象的时候,所有信息都包括了,使代码更简洁
//Utility.h #ifndef WINDOWS_USEFUL_TOOLS_ #define WINDOWS_USEFUL_TOOLS_ #include <Windows.h> #include <MMSystem.h> #pragma comment(lib,"Winmm.lib") #include <wchar.h> #include <time.h> #endif #ifndef D3D_USEFUL_TOOLS_ #define D3D_USEFUL_TOOLS_ #include <d3d9.h> #pragma comment(lib,"d3d9.lib") #include <d3dx9.h> #pragma comment(lib,"d3dx9.lib") #endif #ifndef SAFE_CLEANUP_ #define SAFE_CLEANUP_ //内联函数模板,参数为 T* 类型的引用 template<typename T>inline void Safe_Delete( T* & p ) { if(p){ delete p ; p = NULL;} } template<typename T>inline void Safe_Release( T* & p ) { if(p){ p->Release() ; p = NULL;} } #endif #ifndef STL_TOOLS_ #define STL_TOOLS_ #include <vector> #include <string> using namespace std; #endif #ifdef UNICODE #define string wstring #define sprintf_s swprintf_s #else #define string string #define sprintf_s sprintf_s #endif
//WinMain.cpp #include "Utility.h" HWND g_hWnd = 0; int g_iWidth = 800; int g_iHeight = 600; HINSTANCE g_hInstance = 0; LRESULT CALLBACK WndProc(HWND hWnd ,UINT uMsg, WPARAM wParam,LPARAM lParam); LPDIRECT3D9 g_pD3D = nullptr; LPDIRECT3DDEVICE9 g_pDevice = nullptr; LPD3DXSPRITE g_pSprite = nullptr; //精灵指针 D3DXMATRIX g_matIdentity; //用于恢复渲染状态的单位矩阵 LPDIRECT3DTEXTURE9 g_pRole = nullptr; //纹理指针 D3DXIMAGE_INFO g_info; //图片信息 D3DXMATRIX g_matWorld; //世界矩阵 D3DXVECTOR2 g_vRolePos; //角色位置 UINT g_iDruation = 1000; //持续时间(毫秒单位) D3DCOLOR g_dwMainColor = D3DCOLOR_XRGB(255,255,255); //颜色 //我们自定义的图片结构体,包含指针于图片信息 struct stTexture { LPDIRECT3DTEXTURE9 pTexture; //纹理指针 D3DXIMAGE_INFO imageInfo; //纹理详细信息 D3DXVECTOR2 vPos; //在屏幕的坐标 D3DXMATRIX matWorld; //矩阵变换 }; vector<stTexture*> g_vTextures; //图片容器 /************************************************************************/ /* 有用的知识点: 1、800*600的窗口,但客户区不足800*600 GetClientRect,用于获取客户区像素数 2、加载一组图片:图片名字有共同特点:前缀+数字+后缀 3、随机数:随机数种子(整个程序有1个就够了) srand(seed)、rand() */ /************************************************************************/ VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent,DWORD dwTime) { if (g_dwMainColor == D3DCOLOR_XRGB(255, 255, 255)) g_dwMainColor = D3DCOLOR_XRGB(255, 0, 0); else if (g_dwMainColor == D3DCOLOR_XRGB(255, 0, 0)) g_dwMainColor = D3DCOLOR_XRGB(255, 255, 255); for (int i = 0; i < 10; ++i) { g_vTextures.at(i)->vPos.x = rand() % 801; g_vTextures.at(i)->vPos.y = rand() % 601; } } VOID LoadTextures(string front, int iCount, string back) { TCHAR strTemp[100] = {}; for (int i = 1; i <= iCount; ++i) { sprintf_s( strTemp, //字符串存储位置 TEXT("%s%d%s"), //格式 front.c_str(), i, back.c_str()//替换格式中%...的数据 ); stTexture * pTemp = new stTexture; ZeroMemory(pTemp, sizeof(stTexture)); D3DXCreateTextureFromFileEx( g_pDevice, strTemp, D3DX_FROM_FILE, D3DX_FROM_FILE, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR, D3DCOLOR_XRGB(254, 254, 254), &(pTemp->imageInfo), nullptr, &(pTemp->pTexture)); pTemp->vPos = D3DXVECTOR2(0, 0); D3DXMatrixIdentity(&(pTemp->matWorld)); g_vTextures.push_back(pTemp); } } VOID onInitGame() { ////获取客户区大小的函数 //RECT clientRect; //SetRectEmpty(&clientRect); //GetClientRect(g_hWnd, &clientRect); D3DXCreateSprite(g_pDevice, &g_pSprite); ZeroMemory(&g_info, sizeof(g_info)); D3DXCreateTextureFromFileEx( g_pDevice, TEXT("Resources\\Textures\\Fighter1.png"), D3DX_FROM_FILE,D3DX_FROM_FILE,0,0,D3DFMT_UNKNOWN, D3DPOOL_MANAGED,D3DX_FILTER_LINEAR,D3DX_FILTER_LINEAR, D3DCOLOR_XRGB(254,254,254),&g_info,nullptr,&g_pRole); D3DXMatrixIdentity(&g_matWorld); D3DXMatrixIdentity(&g_matIdentity); g_vRolePos.x = 400; g_vRolePos.y = 200; //激活一个定时器 SetTimer(g_hWnd, 1, g_iDruation, TimerProc); //测试 LoadTextures(TEXT("Resources\\Textures\\Fighter"), 10, TEXT(".png")); } VOID onInit() { //随机数种子 srand((unsigned)time(nullptr)); g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); D3DDISPLAYMODE d3ddm; ZeroMemory(&d3ddm, sizeof(D3DDISPLAYMODE)); g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.BackBufferCount = 1; d3dpp.Windowed = true; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pDevice); onInitGame(); } VOID onLogic(float fElapsedTime) { } VOID onRender(float fElapsedTime) { g_pDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(123, 123, 234), 1.0f, 0); g_pDevice->BeginScene(); g_pSprite->Begin(D3DXSPRITE_ALPHABLEND); //--------------------------绘制一张图片-------------------------- //得到矩阵 D3DXMatrixTransformation2D( &g_matWorld, nullptr, 0.0f, &D3DXVECTOR2(1.0f, 1.0f), &D3DXVECTOR2(0.0f, 0.0f), 0.0f, //弧度制 &g_vRolePos ); //应用矩阵 g_pSprite->SetTransform(&g_matWorld); //渲染 g_pSprite->Draw(g_pRole, nullptr, &D3DXVECTOR3(0, 0, 0), &D3DXVECTOR3(0, 0, 0), g_dwMainColor); //恢复渲染状态 g_pSprite->SetTransform(&g_matIdentity); //--------------------------------------------------------------- //----绘制一组图片---- for (int i = 0; i < 10; ++i) { D3DXMatrixTransformation2D( &(g_vTextures.at(i)->matWorld), nullptr, 0.0f, &D3DXVECTOR2(1, 1), &D3DXVECTOR2(0, 0), 0.0f, &(g_vTextures.at(i)->vPos) ); g_pSprite->SetTransform(&(g_vTextures.at(i)->matWorld)); g_pSprite->Draw( (g_vTextures.at(i))->pTexture, nullptr, &D3DXVECTOR3(0, 0, 0), &D3DXVECTOR3(0,0,0), D3DCOLOR_XRGB(255,255,255)); g_pSprite->SetTransform(&g_matIdentity); } //------------------ g_pSprite->End(); g_pDevice->EndScene(); g_pDevice->Present(nullptr, nullptr, 0, nullptr); } VOID onDestroy() { Safe_Release(g_pSprite); Safe_Release(g_pDevice); Safe_Release(g_pD3D); } INT WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) { WNDCLASS wc; ZeroMemory(&wc,sizeof(wc)); wc.cbClsExtra = NULL; wc.cbWndExtra = NULL; wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); wc.hCursor = LoadCursor(0,IDC_ARROW); wc.hIcon = LoadIcon(0,IDI_APPLICATION); wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.lpszClassName = TEXT("Alibaba"); wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); g_hWnd = CreateWindow(wc.lpszClassName, TEXT("D3D_FirstApp"),WS_OVERLAPPEDWINDOW, 50, 20, g_iWidth + 16, g_iHeight + 39, NULL, NULL, hInstance, NULL); if(g_hWnd) { g_hInstance = hInstance; onInit(); ShowWindow(g_hWnd,SW_SHOWNORMAL); UpdateWindow(g_hWnd); } MSG msg; ZeroMemory(&msg,sizeof(msg)); while ( msg.message!=WM_QUIT) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { static DWORD dwTime = timeGetTime(); DWORD dwCurrentTime = timeGetTime(); DWORD dwElapsedTime = dwCurrentTime - dwTime; float fElapsedTime = dwElapsedTime * 0.001f; onLogic(fElapsedTime); onRender(fElapsedTime); if (dwElapsedTime < 1000 / 60) Sleep(1000 / 60 - dwElapsedTime); dwTime = dwCurrentTime; } } onDestroy(); UnregisterClass(wc.lpszClassName, hInstance); return 0; } LRESULT CALLBACK WndProc(HWND hWnd ,UINT uMsg, WPARAM wParam,LPARAM lParam) { switch(uMsg) { case WM_KEYDOWN: if(wParam == VK_ESCAPE) DestroyWindow(hWnd); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hWnd,uMsg,wParam,lParam); }
这里,关于第一个知识点,我要说明一下,我们都知道,生成窗口的时候,窗口都是带边框的,而我们在CreateWindow函数中定义的窗口的小是带边框的大小,所以我们要使用GetClientRect这个函数GetClientRect这个函数,我们可以把它写到onRander函数里,然后打断点,看返回值,假如你写的是800*600,但是函数返回来的是750*550,那我们,写代码的时候,就将定义窗口大小那,换成800+50和600+50即可,这样的话,我们得到的客户区大小就是800*600 ,而不是加上那个边框后的大小,之后删掉这个函数就行了,这就是它的用法
这个代码中,我们将图片所用到的信息放到一个结构体中,到时候,创建结构体对象的时候,所有信息都包括了,使代码更简洁
相关文章推荐
- linux eth0 设置
- Linux的线程——轻进程
- MySQL性能优化的最佳20+条经验
- poj 2289 Jamie's Contact Groups 【二分 + 最大流】
- CCDrawPrimitives,CCDrawNode解析
- 移动 IOS7弹出提示
- Linux环境编程2
- Oracle exp,imp
- [转] hibernate Mysql 自增长 注解配置,表无关联的注解方式关联查询
- jst中,if的判断条件
- 同步 异步 阻塞 非阻塞机制
- 输入10个数,将其中最小的数与第一个对换,最大的数与最后一个对换
- 一个poll的简单例子
- SQL优化方法
- Httpd运维日志:通过apxs添加模块
- SEO日志:从用户搜索类型定位企业网站
- JavaScript内核笔记03-函数
- 《高性能MySQL》读书笔记(上)
- webpack 学习笔记 02 快速入门
- 常用SQL脚本操作