使用精灵表

精灵表,就是一个包含了多个图片单元的平铺的图像。
我们需要做的就是,算出图片单元的左上角在位图图像中为止,然后从图像中按照精灵的宽度和高度复制出一个源矩形来。
使用这个技术绘制单个帧,我们可以编写一个能绘制精灵表中任何一帧的函数!为了让这个函数尽可能可重用,必须将能描述精灵的所有属性传递进来。

一、MyDirectX.h

#pragma once  //header files
#define WIN32_EXTRA_LEAN
#define DIRECTINPUT_VERSION 0x0800
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dinput.h>
#include <xinput.h>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;//libraries
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib,"xinput.lib")  //program values
extern const string APPTITLE;
extern const int SCREENW;
extern const int SCREENH;
extern bool gameover;//Direct3D objects
extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3ddev;
extern LPDIRECT3DSURFACE9 backbuffer;
extern LPD3DXSPRITE spriteobj; //纹理
extern LPD3DXFONT font; //文字
extern LPDIRECTINPUT8 dinput;
extern LPDIRECTINPUTDEVICE8 dimouse;
extern LPDIRECTINPUTDEVICE8 dikeyboard;
//extern ID3DXFont* g_pFont = NULL;
extern DIMOUSESTATE mouse_state;
extern XINPUT_GAMEPAD controllers[4];//Direct3D functions
bool Direct3D_Init(HWND hwnd, int width, int height, bool fullscreen);
void Direct3D_Shutdown();
LPDIRECT3DSURFACE9 LoadSurface(string filename);
LPD3DXFONT MakeFont(string name, int size); //设置字体
void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source);//DirectInput objects, devices, and states
//DirectInput functions
bool DirectInput_Init(HWND);
void DirectInput_Update();
void DirectInput_Shutdown();
int Key_Down(int);
int Mouse_Button(int);
int Mouse_X();
int Mouse_Y();
void XInput_Vibrate(int contNum = 0, int amount = 65535);
bool XInput_Controller_Found();//game functions
bool Game_Init(HWND window);
void Game_Run(HWND window);void MouseUpdate();
void KeyBoardUpdate();
void XInputUpdate();
void Game_End();LPDIRECT3DTEXTURE9 LoadTexture(string filename, D3DCOLOR transcolor = D3DCOLOR_XRGB(0, 0, 0));
D3DXVECTOR2  GetBitmapSize(string filename);
void FontPrint(LPD3DXFONT font, int x, int y, string text, D3DCOLOR color = D3DCOLOR_XRGB(255, 255, 255));void Sprite_Draw_Fram(LPDIRECT3DTEXTURE9 texture, int destx, int desty, int framenum, int framew, int frameh, int columns);
void Sprite_Animate(int &frame, int startframe, int endframe, int direction, int &starttime, int delay);


二、MyDirectX.cpp

#include "MyDirectX.h"
#include <iostream>
using namespace std;//Direct3D variables
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 backbuffer = NULL;//DirectInput variables
LPDIRECTINPUT8 dinput = NULL;
LPDIRECTINPUTDEVICE8 dimouse = NULL;
LPDIRECTINPUTDEVICE8 dikeyboard = NULL;
DIMOUSESTATE mouse_state;
char keys[256];
XINPUT_GAMEPAD controllers[4];/**
** Direct3D initialization
**/
bool Direct3D_Init(HWND window, int width, int height, bool fullscreen)
{//initialize Direct3D  d3d = Direct3DCreate9(D3D_SDK_VERSION);if (!d3d) return false;//set Direct3D presentation parameters  D3DPRESENT_PARAMETERS d3dpp;ZeroMemory(&d3dpp, sizeof(d3dpp));d3dpp.Windowed = (!fullscreen);d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;d3dpp.BackBufferCount = 1;d3dpp.BackBufferWidth = width;d3dpp.BackBufferHeight = height;d3dpp.hDeviceWindow = window;//create Direct3D device  d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);if (!d3ddev) return false;//get a pointer to the back buffer surface  d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);D3DXCreateSprite(d3ddev, &spriteobj);  //纹理return true;
}/**
** Direct3D shutdown
**/
void Direct3D_Shutdown()
{if (spriteobj)spriteobj->Release();if (d3ddev) d3ddev->Release();if (d3d) d3d->Release();
}/**
** Draws a surface to the screen using StretchRect
**/
void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source)
{//get width/height from source surface  D3DSURFACE_DESC desc;source->GetDesc(&desc);//create rects for drawing  RECT source_rect = { 0, 0, (long)desc.Width, (long)desc.Height };RECT dest_rect = { (long)x, (long)y, (long)x + desc.Width, (long)y + desc.Height };//draw the source surface onto the dest  d3ddev->StretchRect(source, &source_rect, dest, &dest_rect, D3DTEXF_NONE);}/**
** Loads a bitmap file into a surface
**/
LPDIRECT3DSURFACE9 LoadSurface(string filename)
{LPDIRECT3DSURFACE9 image = NULL;//get width and height from bitmap file  D3DXIMAGE_INFO info;HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);if (result != D3D_OK)return NULL;//create surface  result = d3ddev->CreateOffscreenPlainSurface(info.Width,         //width of the surface  info.Height,        //height of the surface  D3DFMT_X8R8G8B8,    //surface format  D3DPOOL_DEFAULT,    //memory pool to use  &image,             //pointer to the surface  NULL);              //reserved (always NULL)  if (result != D3D_OK) return NULL;//load surface from file into newly created surface  result = D3DXLoadSurfaceFromFile(image,                  //destination surface  NULL,                   //destination palette  NULL,                   //destination rectangle  filename.c_str(),       //source filename  NULL,                   //source rectangle  D3DX_DEFAULT,           //controls how image is filtered  D3DCOLOR_XRGB(0, 0, 0),   //for transparency (0 for none)  NULL);                  //source image info (usually NULL)  //make sure file was loaded okay  if (result != D3D_OK) return NULL;return image;}LPDIRECT3DTEXTURE9 LoadTexture(string filename, D3DCOLOR transcolor) {LPDIRECT3DTEXTURE9 texture = NULL;D3DXIMAGE_INFO info;HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);if (result != D3D_OK) return NULL;result = D3DXCreateTextureFromFileEx(d3ddev, filename.c_str(), info.Width, info.Height, 1, D3DPOOL_DEFAULT, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, transcolor, &info, NULL, &texture);if (result != D3D_OK) return NULL;return texture;
}
D3DXVECTOR2 GetBitmapSize(string filename) {D3DXIMAGE_INFO info;D3DXVECTOR2 size = D3DXVECTOR2(0.0f, 0.0f);HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);if (result == D3D_OK) {size = D3DXVECTOR2((float)info.Width, (float)info.Height);}else {size = D3DXVECTOR2((float)info.Width, (float)info.Height);}return size;
}/**
** DirectInput initialization
**/
bool DirectInput_Init(HWND hwnd) {//initialize DirectInput object  HRESULT result = DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&dinput,NULL);//initialize the keyboard  dinput->CreateDevice(GUID_SysKeyboard, &dikeyboard, NULL);                     //创建设备dikeyboard->SetDataFormat(&c_dfDIKeyboard);                                    //格式dikeyboard->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);  //协作级别dikeyboard->Acquire();//initialize the mouse  dinput->CreateDevice(GUID_SysMouse, &dimouse, NULL);dimouse->SetDataFormat(&c_dfDIMouse);dimouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);dimouse->Acquire();d3ddev->ShowCursor(false);return true;
}/**
** DirectInput update
**/
void DirectInput_Update()
{//update mouse  dimouse->GetDeviceState(sizeof(mouse_state), (LPVOID)&mouse_state);//update keyboard  dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys);//update controllers  for (int i = 0; i< 4; i++){ZeroMemory(&controllers[i], sizeof(XINPUT_GAMEPAD));//get the state of the controller  XINPUT_STATE state;DWORD result = XInputGetState(i, &state);//store state in global controllers array  if (result == 0) controllers[i] = state.Gamepad;}}/**
** Return mouse x movement
**/
int Mouse_X()
{return mouse_state.lX;
}/**
** Return mouse y movement
**/
int Mouse_Y()
{return mouse_state.lY;
}/**
** Return mouse button state
**/
int Mouse_Button(int button)
{return mouse_state.rgbButtons[button] & 0x80;
}/**
** Return key press state
**/
int Key_Down(int key)
{return (keys[key] & 0x80);
}/**
** DirectInput shutdown
**/
void DirectInput_Shutdown()
{if (dikeyboard){dikeyboard->Unacquire();dikeyboard->Release();dikeyboard = NULL;}if (dimouse){dimouse->Unacquire();dimouse->Release();dimouse = NULL;}
}/**
** Returns true if controller is plugged in
**/
bool XInput_Controller_Found()
{XINPUT_CAPABILITIES caps;ZeroMemory(&caps, sizeof(XINPUT_CAPABILITIES));XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps);if (caps.Type != 0) return false;return true;
}/**
** Vibrates the controller
**/
void XInput_Vibrate(int contNum, int amount)
{XINPUT_VIBRATION vibration;ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));vibration.wLeftMotorSpeed = amount;vibration.wRightMotorSpeed = amount;XInputSetState(contNum, &vibration);
}void Sprite_Draw_Fram(LPDIRECT3DTEXTURE9 texture, int destx, int desty, int framenum, int framew, int frameh, int columns) {D3DXVECTOR3 position((float)destx, (float)desty, 0);D3DCOLOR white = D3DCOLOR_XRGB(255, 255, 255);RECT rect;rect.left = ((framenum % columns)) * framew;rect.top = ((framenum / columns)) * frameh;rect.right = rect.left + framew;rect.bottom = rect.top + frameh;spriteobj->Draw(texture, &rect, NULL, &position, white);
}
void Sprite_Animate(int &frame, int startframe, int endframe, int direction, int &starttime, int delay) {if ((int)GetTickCount() > starttime + delay) {starttime = GetTickCount();frame += direction;if (frame > endframe)frame = startframe;if (frame < startframe)frame = endframe;}
}

三、MyWindows.cpp

#include "MyDirectX.h"
using namespace std;
bool gameover = false;/**
** Windows event handler
**/
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{switch (msg){case WM_DESTROY:gameover = true;PostQuitMessage(0);return 0;}return DefWindowProc(hWnd, msg, wParam, lParam);
}/**
** Windows entry point
**/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{//initialize window settings  WNDCLASSEX wc;wc.cbSize = sizeof(WNDCLASSEX);wc.style = CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc = (WNDPROC)WinProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = NULL;wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName = NULL;wc.lpszClassName = APPTITLE.c_str();wc.hIconSm = NULL;RegisterClassEx(&wc);//create a new window  HWND window = CreateWindow(APPTITLE.c_str(), APPTITLE.c_str(),WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,SCREENW, SCREENH, NULL, NULL, hInstance, NULL);if (window == 0) return 0;//display the window  ShowWindow(window, nCmdShow);UpdateWindow(window);//initialize the game  if (!Game_Init(window)) return 0;// main message loop  MSG message;while (!gameover){if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&message);DispatchMessage(&message);}//process game loop   Game_Run(window);}//shutdown  Game_End();return message.wParam;
}

四、MyGame.cpp

#include "MyDirectX.h"
using namespace std;
const string APPTITLE = "Animate Sprite Demo";
const int SCREENW = 800;
const int SCREENH = 600;
LPDIRECT3DTEXTURE9 explosion = NULL;
LPD3DXSPRITE spriteobj = NULL; //定义为null
int frame = 0;
int starttime = 0;bool Game_Init(HWND window) {if (!Direct3D_Init(window, SCREENW, SCREENH, false)) {MessageBox(0, "Error initializing Driect3D", "ERROR", 0);return false;}if (!DirectInput_Init(window)) {MessageBox(0, "Error initializing DriectInput", "ERROR", 0);}explosion = LoadTexture("F:/5.png");if (!explosion)return false;
}void Game_Run(HWND window) {if (!d3ddev)return;DirectInput_Update();d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 100), 1.0f, 0);if (d3ddev->BeginScene()) {spriteobj->Begin(D3DXSPRITE_ALPHABLEND);Sprite_Animate(frame, 0, 29, 1, starttime, 30);Sprite_Draw_Fram(explosion, 20, 200, frame, 42, 42, 4);spriteobj->End();d3ddev->EndScene();d3ddev->Present(NULL, NULL, NULL, NULL);}if (Key_Down(VK_ESCAPE))gameover = true;if (controllers[0].wButtons & XINPUT_GAMEPAD_BACK) {gameover = true;}}
void Game_End() {explosion->Release();DirectInput_Shutdown();Direct3D_Shutdown();
}                      

Direct3D学习笔记(二)——精灵动画(Sprite)相关推荐

  1. Direct3D学习笔记(一)——精灵(Bomo_catcher游戏)

    一.Visual Studio 2015设置 1.Bomo_Catcher属性-常规-字符集-使用多字节字符集 2.Bomo_Catcher属性- VC++目录-包含目录 C:\Program Fil ...

  2. direct3D 学习笔记

    DirectX SDK 2006学习笔记1--框架 2008-01-31 13:20 友情提醒:所谓的框架是指SDK目录下/Samples/C++/Common路径下的DXUT系列函数包装.学习框架的 ...

  3. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  4. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  5. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

  6. PyTorch学习笔记(二)——回归

    PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...

  7. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

  8. Scapy学习笔记二

    Scapy学习笔记二 Scapy Sniffer的用法: http://blog.csdn.net/qwertyupoiuytr/article/details/54670489 Scapy Snif ...

  9. Ethernet/IP 学习笔记二

    Ethernet/IP 学习笔记二 原文链接:http://wiki.mbalib.com/wiki/Ethernet/IP 1.通信模式 不同于源/目的通信模式,EtherNet/IP 采用生产/消 ...

最新文章

  1. 2017辽宁冬令营-4.蚂蚁
  2. 虚拟机linux配置armip,arm-PC-虚拟机环境搭建
  3. 第三次学JAVA再学不好就吃翔(part17)--数组
  4. win10安装ensp启动40_装系统不求人,快速制作启动U盘,傻瓜式重装WIN10
  5. 嵌套集合模型(Nested set model)介绍
  6. 如何引用传递参数从一个函数中得到多个返回值
  7. 你不得不知道的HTML5的新型标签
  8. opencv 图像几何变换
  9. arcgis栅格邻域统计_运用ArcGIS进行影像分类
  10. dubbo yml配置_Dubbo常见配置说明
  11. 杀毒软件可能令企业用户陷入更大危机
  12. EnableQ在线问卷调查引擎在学校教学教评中的作用
  13. 天正的计算机快捷命令大全,新手必看-史上最全CAD快捷键大全
  14. spring MVC3 集成 freemarker
  15. 基于深度学习的目标检测的IOU损失函数介绍
  16. btb和oto,btc模式是什么意思
  17. Unity3D 如何干净的解除父子关系
  18. 记一次稀里糊涂的面试
  19. node.js+uni计算机毕设项目计算机配件价格查询微信小程序(程序+小程序+LW)
  20. webpack 配置不同环境, 以及配置 baseUrl

热门文章

  1. 实现全排列算法(C++)
  2. 体系结构 第二章习题知识点
  3. 父爱如山——别因为工作而忘记家人
  4. 阿里云服务器ECS安装Docker提示No match for argument: docker-ce,No match for argument: docker-ce-cli
  5. 弘辽科技:淘宝必做活动有哪些?具体活动介绍
  6. CAD如何设置多个视口同步?CAD视口同步设置技巧
  7. 42、基于51单片机数控电源稳压电源电压数码管显示系统设计
  8. MATLAB绘图笔记——画圆的几种方法
  9. php工程导致系统蓝屏,为什么电脑总是蓝屏
  10. 为什么需要基于用户故事的角色指标?