D3DXSprite简单检测精灵碰撞

检测精灵碰撞主要有两种算法:基于边界矩形及基于距离的碰撞检测。首先学习边界矩形碰撞检测,关键在于识别两个精灵在屏幕上的位置,然后比较它们的边界框,看是否重叠,可以使用函数IntersectRect来判断两个矩形是否相交。对于基于距离的碰撞检测,只需要用精灵的坐标x与y计算两点之间的距离,然后与两个精灵的半径之和比较即可判断是否发生碰撞。下面看代码,首先是头文件DirectX.h,添加了新的结构体SPRITE,然后在末尾添加了两个新的函数用于碰撞检测,Collision是基于矩形框的碰撞检测,CollisionD是基于距离的检测。

View Code
 1 #pragma once
 2 
 3 #define WIN32_EXTRA_LEAN
 4 #define DIRECTINPUT_VERSION 0x0800
 5 #include <Windows.h>
 6 #include <d3d9.h>
 7 #include <d3dx9.h>
 8 #include <dinput.h>
 9 #include <XInput.h>
10 #include <ctime>
11 #include <iostream>
12 #include <iomanip>
13 using namespace std; 14 
15 #pragma comment(lib, "winmm.lib")
16 #pragma comment(lib, "user32.lib")
17 #pragma comment(lib, "gdi32.lib")
18 #pragma comment(lib, "dxguid.lib")
19 #pragma comment(lib, "d3d9.lib")
20 #pragma comment(lib, "d3dx9.lib")
21 #pragma comment(lib, "dinput8.lib")
22 #pragma comment(lib, "xinput.lib")
23 
24 extern const string APPTITLE; 25 extern const int SCREENW; 26 extern const int SCREENH; 27 extern bool gameover; 28 
29 extern LPDIRECT3D9 d3d; 30 extern LPDIRECT3DDEVICE9 d3ddev; 31 extern LPDIRECT3DSURFACE9 backbuffer; 32 
33 //sprite structure
34 struct SPRITE 35 { 36     float x, y; 37     int frame, columns; 38     int width, height; 39     float scaling, rotation; 40     int startframe, endframe; 41     int starttime, delay; 42     int direction; 43     float velx, vely; 44  D3DCOLOR color; 45 
46  SPRITE() 47  { 48         frame = 0; 49         columns = 1; 50         width = height = 0; 51         scaling = 1.0f; 52         startframe = endframe = 0; 53         direction = 1; 54         starttime = delay = 0; 55         velx = vely = 0.0f; 56         color = D3DCOLOR_XRGB(255, 255, 255); 57  } 58 }; 59 
60 //Direct3D functions
61 bool Direct3D_Init(HWND hwnd, int width, int height, bool fullscreen); 62 void Direct3D_Shutdown(); 63 bool LoadSurface(string filename, D3DXIMAGE_INFO &info, LPDIRECT3DSURFACE9 &image); 64 void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source); 65 D3DXVECTOR2 GetBitmapSize(string filename); 66 LPDIRECT3DTEXTURE9 LoadTexture(string filename, D3DCOLOR transcolor = D3DCOLOR_XRGB(0,0,0)); 67 
68 //DirectInput objects, devices, and states
69 extern LPDIRECTINPUT8 dinput; 70 extern LPDIRECTINPUTDEVICE8 dimouse; 71 extern LPDIRECTINPUTDEVICE8 dikeyboard; 72 extern DIMOUSESTATE mouse_state; 73 extern LPD3DXSPRITE spriteobj; 74 
75 //DirectInput functions
76 bool DirectInput_Init(HWND); 77 void DirectInput_Update(); 78 void DirectInput_Shutdown(); 79 int Key_Down(int); 80 int Mouse_Button(int); 81 int Mouse_X(); 82 int Mouse_Y(); 83 
84 //game functions
85 bool Game_Init(HWND window); 86 void Game_Run(HWND window); 87 void Game_End(); 88 
89 //sprite functions
90 void Sprite_Draw_Frame(LPDIRECT3DTEXTURE9 texture, int destx, int desty, 91     int framenum, int framew, int frameh, int columns); 92 void Sprite_Animate(int &frame, int startframe, int endframe, 93     int direction, int &starttime, int delay); 94 void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, 95     int frame, int columns, float rotation, float scaling, D3DCOLOR color); 96 
97 //physics functions
98 int Collision(SPRITE sprite1, SPRITE sprite2); 99 bool CollisionD(SPRITE sprite1, SPRITE sprite2);


接着是DirectX.cpp文件,先看看前面的一些函数,这些在前面的例子已经说得很清楚了,使用Sprite_Animate与 Sprite_Transform_Draw来实现动画效果

View Code
 1 #include "DirectX.h"
 2 #include <iostream>
 3 using namespace std;  4 
 5 //Direct3D variables
 6 LPDIRECT3D9 d3d = NULL;  7 LPDIRECT3DDEVICE9 d3ddev = NULL;  8 LPDIRECT3DSURFACE9 backbuffer = NULL;  9 LPD3DXSPRITE spriteobj;  10 
 11 //DirectInput variables
 12 LPDIRECTINPUT8 dinput = NULL;  13 LPDIRECTINPUTDEVICE8 dimouse = NULL;  14 LPDIRECTINPUTDEVICE8 dikeyboard = NULL;  15 DIMOUSESTATE mouse_state;  16 char keys[256];  17 
 18 bool Direct3D_Init(HWND window, int width, int height, bool fullscreen)  19 {  20     //Initialize Direct3D
 21     d3d = Direct3DCreate9(D3D_SDK_VERSION);  22     if (!d3d)  23         return false;  24 
 25     //set Direct3D presentation parameters
 26  D3DPRESENT_PARAMETERS d3dpp;  27     ZeroMemory(&d3dpp, sizeof(d3dpp));  28     d3dpp.hDeviceWindow = window;  29     d3dpp.Windowed = (!fullscreen);  30     d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;  31     d3dpp.EnableAutoDepthStencil = 1;  32     d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;  33     d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;  34     d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;  35     d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;  36     d3dpp.BackBufferCount = 1;  37     d3dpp.BackBufferWidth = width;  38     d3dpp.BackBufferHeight = height;  39 
 40     //create Direct3D device
 41     d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,  42         D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);  43     if (!d3ddev)  44         return false;  45 
 46     //get a pointer to the back buffer surface
 47     d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);  48 
 49     //create sprite object
 50     D3DXCreateSprite(d3ddev, &spriteobj);  51 
 52     return true;  53 }  54 
 55 void Direct3D_Shutdown()  56 {  57     if (spriteobj)  58         spriteobj->Release();  59     if (d3ddev)  60         d3ddev->Release();  61     if (d3d)  62         d3d->Release();  63 }  64 
 65 void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source)  66 {  67     //get width height from source surface
 68  D3DSURFACE_DESC desc;  69     source->GetDesc(&desc);  70 
 71     //create rects for drawing
 72     RECT source_rect = {0, 0, (long)desc.Width, (long)desc.Height };  73     RECT dest_rect = { (long)x, (long)y, (long)x + desc.Width, (long)y + desc.Height};  74 
 75     //draw the source surface onto the dest
 76     d3ddev->StretchRect(source, &source_rect, dest, &dest_rect, D3DTEXF_NONE);  77 }  78 
 79 bool LoadSurface(string filename, D3DXIMAGE_INFO &info, LPDIRECT3DSURFACE9 &image)  80 {  81     //get width and height from bitmap file
 82     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);  83     if (result != D3D_OK)  84         return false;  85 
 86     //create surface
 87     result = d3ddev->CreateOffscreenPlainSurface(  88  info.Width, info.Height,  89  D3DFMT_X8R8G8B8,  90  D3DPOOL_DEFAULT,  91         &image,  92  NULL);  93     if (result != D3D_OK)  94         return false;  95 
 96     //load surface from file into newly created surface
 97     result = D3DXLoadSurfaceFromFile(  98         image,    //destination surface
 99         NULL,    //destination palette
100         NULL,    //destination rectangle
101  filename.c_str(), 102         NULL,    //source rectangle
103         D3DX_DEFAULT, //controls how image is filtered
104         D3DCOLOR_XRGB(0,0,0), 105         NULL);    //source image info
106     if (result != D3D_OK) 107         return false; 108 
109     return true; 110 } 111 
112 bool DirectInput_Init(HWND hwnd) 113 { 114     //initialize DirectInput object
115     HRESULT result = DirectInput8Create( 116  GetModuleHandle(NULL), 117  DIRECTINPUT_VERSION, 118  IID_IDirectInput8, 119         (void**)&dinput, 120  NULL); 121 
122     //initialize the keyboard
123     dinput->CreateDevice(GUID_SysKeyboard, &dikeyboard, NULL); 124     dikeyboard->SetDataFormat(&c_dfDIKeyboard); 125     dikeyboard->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); 126     dikeyboard->Acquire(); 127 
128     //initialize the mouse
129     dinput->CreateDevice(GUID_SysMouse, &dimouse, NULL); 130     dimouse->SetDataFormat(&c_dfDIMouse); 131     dimouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); 132     dimouse->Acquire(); 133     
134     ShowCursor(true); 135 
136     return true; 137 } 138 
139 void DirectInput_Update() 140 { 141     //update mouse
142     dimouse->GetDeviceState(sizeof(mouse_state), (LPVOID)&mouse_state); 143 
144     //update keyboard
145     dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys); 146 } 147 
148 int Mouse_X() 149 { 150     return mouse_state.lX; 151 } 152 
153 int Mouse_Y() 154 { 155     return mouse_state.lY; 156 } 157 
158 //return mouse button state
159 int Mouse_Button(int button) 160 { 161     return mouse_state.rgbButtons[button] & 0x80; 162 } 163 
164 //return key press state
165 int Key_Down(int key) 166 { 167     return (keys[key] & 0x80); 168 } 169 
170 void DirectInput_Shutdown() 171 { 172     if (dikeyboard) 173  { 174         dikeyboard->Unacquire(); 175         dikeyboard->Release(); 176         dikeyboard = NULL; 177  } 178 
179     if (dimouse) 180  { 181         dimouse->Unacquire(); 182         dimouse->Release(); 183         dimouse = NULL; 184  } 185 } 186 
187 //load texture
188 LPDIRECT3DTEXTURE9 LoadTexture(string filename, D3DCOLOR transcolor) 189 { 190     LPDIRECT3DTEXTURE9 texture = NULL; 191     
192     //get width and height from bitmap file
193  D3DXIMAGE_INFO info; 194     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info); 195     if (result != D3D_OK) 196         return NULL; 197 
198     //create the new texture by loading a bitmap image file
199     result = D3DXCreateTextureFromFileEx( 200         d3ddev, //Direct3D device object
201         filename.c_str(), //filename
202         info.Width, //image width
203         info.Height, //image height
204         1, //mip-map levels (1 for no chain)
205         D3DPOOL_DEFAULT, //the type of surface
206         D3DFMT_UNKNOWN, //surface format
207         D3DPOOL_DEFAULT, //memory class for the texture
208         D3DX_DEFAULT, //image filter
209         D3DX_DEFAULT, //mip filter
210         transcolor, //color key for transparency
211         &info, //bitmap file info
212         NULL, //color palette
213         &texture); //destination texture
214     if (result != D3D_OK) 215         return NULL; 216 
217     return texture; 218 } 219 
220 D3DXVECTOR2 GetBitmapSize(string filename) 221 { 222  D3DXIMAGE_INFO info; 223     D3DXVECTOR2 size = D3DXVECTOR2(0.0f, 0.0f); 224     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info); 225     if (result == D3D_OK) 226         size = D3DXVECTOR2((float)info.Width, (float)info.Height); 227 
228     return size; 229 } 230 
231 //draw sprite frame
232 void Sprite_Draw_Frame(LPDIRECT3DTEXTURE9 texture, int destx, int desty, 233     int framenum, int framew, int frameh, int columns) 234 { 235     D3DXVECTOR3 position((float)destx, (float)desty, 0); 236     D3DCOLOR white = D3DCOLOR_XRGB(255, 255, 255); 237 
238  RECT rect; 239     rect.left = (framenum % columns) * framew; 240     rect.top = (framenum / columns) * frameh; 241     rect.right = rect.left + framew; 242     rect.bottom = rect.top + frameh; 243 
244     spriteobj->Draw(texture, &rect, NULL, &position, white); 245 } 246 
247 void Sprite_Animate(int &frame, int startframe, int endframe, 248     int direction, int &starttime, int delay) 249 { 250     if ((int)GetTickCount() > starttime + delay) 251  { 252         starttime = GetTickCount(); 253 
254         frame += direction; 255         if (frame > endframe) 256             frame = startframe; 257         if (frame < startframe) 258             frame = endframe; 259  } 260 } 261 
262 void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, 263     int frame, int columns, float rotation, float scaling, D3DCOLOR color) 264 { 265     //create a scale vector
266  D3DXVECTOR2 scale(scaling, scaling); 267 
268     //create a translate vector, for moving
269  D3DXVECTOR2 trans(x, y); 270 
271     //set rotation center
272     D3DXVECTOR2 center((float)(width*scaling)/2, (float)(height*scaling)/2); 273 
274     //create 2D transformation matrix
275  D3DXMATRIX mat; 276     D3DXMatrixTransformation2D(&mat, NULL, 0, &scale, &center, rotation, &trans); 277 
278     //tell sprite object to use the transform
279     spriteobj->SetTransform(&mat); 280 
281     //calculate frame location in source image
282     int fx = (frame % columns) * width; 283     int fy = (frame / columns) * height; 284     RECT srcRect = {fx, fy, fx + width, fy + height}; 285 
286     //draw the sprite frame
287     spriteobj->Draw(image, &srcRect, NULL, NULL, color); 288 }

 

下面是基于矩形框的碰撞检测的实现,用结构体SPRITE表示所需要的精灵的参数,然后构造两个矩形框rect1与rect2,最后调用函数IntersectRect来检测是否发生碰撞,dest表示发生碰撞的区域,这里不需要使用。

 1 //bounding box collision detection
 2 int Collision(SPRITE sprite1, SPRITE sprite2)  3 {  4  RECT rect1;  5     rect1.left = (long)sprite1.x;  6     rect1.top = (long)sprite1.y;  7     rect1.right = (long)sprite1.x + sprite1.width * sprite1.scaling;  8     rect1.bottom = (long)sprite1.y + sprite1.height * sprite1.scaling;  9 
10  RECT rect2; 11     rect2.left = (long)sprite2.x; 12     rect2.top = (long)sprite2.y; 13     rect2.right = (long)sprite2.x + sprite2.width * sprite2.scaling; 14     rect2.bottom = (long)sprite2.y + sprite2.height * sprite2.scaling; 15 
16     RECT dest;//ignored, the intersected area between rectangles
17     return IntersectRect(&dest, &rect1, &rect2);//detect if there is collision
18 }

 

CollisionD表示基于距离的检测,把每个精灵都看成由正方形包围的,对于本实验,可以粗略计算出精灵的半径radius1与radius2,同时算上缩放因子的影响。有了半径,很容易计算正方形的中心点坐标vector1与vector2。最后,根据distance = sqrt(x*x + y*y)这个公式计算两点间的距离,再与rasius1 + radius2进行比较。

 1 bool CollisionD(SPRITE sprite1, SPRITE sprite2)  2 {  3     double radius1, radius2;  4 
 5     //Calculate radius 1
 6     if (sprite1.width > sprite1.height)  7         radius1 = (sprite1.width * sprite1.scaling) / 2.0;  8     else
 9         radius1 = (sprite1.height * sprite1.scaling) / 2.0; 10 
11     //center point 1
12     double x1 = sprite1.x + radius1; 13     double y1 = sprite1.y + radius1; 14  D3DXVECTOR2 vector1(x1, y1); 15 
16     //calculate radius2
17     if (sprite2.width > sprite2.height) 18         radius2 = (sprite2.width * sprite2.scaling) / 2.0; 19     else
20         radius2 = (sprite2.height * sprite2.scaling) / 2.0; 21 
22     //center point 2
23     double x2 = sprite2.x + radius2; 24     double y2 = sprite2.y + radius2; 25  D3DXVECTOR2 vector2(x2, y2); 26 
27     //calculate distance
28     double deltax = vector1.x - vector2.x; 29     double deltay = vector1.y - vector2.y; 30     double dist = sqrt((deltax * deltax) + (deltay * deltay)); 31 
32     //return distance comparison
33     return (dist < radius1 + radius2); 34 }

 

下面是main.cpp文件,没什么改变,前面已经讲过。

View Code
 1 #include "DirectX.h"
 2 using namespace std;  3 
 4 bool gameover = false;  5 
 6 //windows event handling function
 7 LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  8 {  9     switch (message) 10  { 11     case WM_DESTROY: 12         gameover = true; 13         PostQuitMessage(0); 14         return 0; 15  } 16 
17     return DefWindowProc(hwnd, message, wParam, lParam); 18 } 19 
20 
21 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow) 22 { 23     //set the windows properties
24  WNDCLASSEX wc; 25     wc.cbSize = sizeof(WNDCLASSEX); 26     wc.style = CS_HREDRAW | CS_VREDRAW; 27     wc.lpfnWndProc = (WNDPROC)WinProc; 28     wc.cbClsExtra = 0; 29     wc.cbWndExtra = 0; 30     wc.hInstance = hInstance; 31     wc.hIcon = NULL; 32     wc.hCursor = LoadCursor(NULL, IDC_ARROW); 33     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 34     wc.lpszMenuName = NULL; 35     wc.lpszClassName = APPTITLE.c_str(); 36     wc.hIconSm = NULL; 37     RegisterClassEx(&wc); 38 
39     //determine the resolution of the clients desktop screen
40     int screenWidth = GetSystemMetrics(SM_CXSCREEN); 41     int screenHeight = GetSystemMetrics(SM_CYSCREEN); 42 
43     //place the window in the middle of screen
44     int posX = (GetSystemMetrics(SM_CXSCREEN) - SCREENW) / 2; 45     int posY = (GetSystemMetrics(SM_CYSCREEN) - SCREENH) / 2; 46 
47     //Create a window
48  HWND window; 49     window = CreateWindow(APPTITLE.c_str(), APPTITLE.c_str(), 50         WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, posX, posY, SCREENW, SCREENH, 51  NULL, NULL, hInstance, NULL); 52     if (window == 0) 53         return false; 54 
55     //display the window
56  ShowWindow(window, nCmdShow); 57  UpdateWindow(window); 58 
59     //initialize the game
60     if (!Game_Init(window)) 61         return 0; 62 
63     //main message loop
64  MSG msg; 65     while (!gameover) 66  { 67         //process windows events
68         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 69  { 70             //handle any event messages
71             TranslateMessage(&msg); 72             DispatchMessage(&msg); 73  } 74 
75         //process game loop
76  Game_Run(window); 77  } 78 
79     //free game resources
80  Game_End(); 81 
82     return msg.wParam; 83 }

 

最后是游戏文件game.cpp,imgShip与imgAsteroid分别表示飞船图片与游星图片,ship、asteroid1、asteroid2为精灵结构体用于存储参数信息,在函数Game_Init中会对这些参数初始化,ship飞船的参数很简单,是单个图片;asteroid1与asteroid2这两个精灵都采用imgAsteroid精灵表来生成动画效果,参数稍微多一点。在Game_Run函数中,先设定用于移动飞船的按键,这里是W与S。接着用Sprite_Animat函数传入已经设置好的参数来不断改变asteroid1与asteroid2这两个精灵的参数,再用Sprite_Transform_Draw不断绘制图片来生成动画效果。在绘制图片之前,调用碰撞检测函数Collision与CollisionD,但我得到的效果并不好。

 1 #include "DirectX.h"
 2 using namespace std;  3 
 4 const string APPTITLE = "Bounding Box";  5 const int SCREENW = 1024;  6 const int SCREENH = 576;  7 
 8 SPRITE ship, asteroid1, asteroid2;  9 LPDIRECT3DTEXTURE9 imgShip = NULL;  10 LPDIRECT3DTEXTURE9 imgAsteroid = NULL;  11 
 12 //game initialization
 13 bool Game_Init(HWND window)  14 {  15     //initialize Direct3D
 16     if (!Direct3D_Init(window, SCREENW, SCREENH, false))  17  {  18         MessageBox(0, "Error initialization Direct3D", "Error", 0);  19         return false;  20  }  21 
 22     //initialize DirectInput
 23     if (!DirectInput_Init(window))  24  {  25         MessageBox(0, "Error initialization DirectInput", "Error", 0);  26         return false;  27  }  28 
 29     //load texture
 30     imgShip = LoadTexture("fatship.tga");  31     if (!imgShip)  32         return false;  33     imgAsteroid = LoadTexture("asteroid.tga");  34     if (!imgAsteroid)  35         return false;  36     
 37     //set properties for sprites
 38     ship.x = 450;  39     ship.y = 200;  40     ship.width = ship.height = 128;  41 
 42     asteroid1.x = 50;  43     asteroid1.y = 100;  44     asteroid1.width = asteroid1.height = 60;  45     asteroid1.columns = 8;  46     asteroid1.startframe = 0;  47     asteroid1.endframe = 63;  48     asteroid1.velx = -2.0f;  49 
 50     asteroid2.x = 900;  51     asteroid2.y = 400;  52     asteroid2.width = asteroid2.height = 60;  53     asteroid2.columns = 8;  54     asteroid2.startframe = 0;  55     asteroid2.endframe = 63;  56     asteroid2.velx = 2.0f;  57 
 58     return true;  59 }  60 
 61 //game update
 62 void Game_Run(HWND window)  63 {  64     //make sure the Direct3D device is valid
 65     if (!d3ddev)  66         return;  67 
 68     //update input devices
 69  DirectInput_Update();  70 
 71     //clear the scene
 72     d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);  73 
 74     //move the ship up/down with keys
 75     if (Key_Down(DIK_W))  76  {  77         ship.y -= 1.0f;  78         if (ship.y < 0)  79             ship.y = 0;  80  }  81 
 82     if (Key_Down(DIK_S))  83  {  84         ship.y += 1.0f;  85         if (ship.y > SCREENH - ship.height)  86             ship.y = SCREENH - ship.height;  87  }  88 
 89     //move and animate the asteroids
 90     asteroid1.x  += asteroid1.velx;  91     if (asteroid1.x < 0 || asteroid1.x > SCREENW - asteroid1.width)  92         asteroid1.velx *= -1;  93  Sprite_Animate(asteroid1.frame, asteroid1.startframe, asteroid1.endframe,  94  asteroid1.direction, asteroid1.starttime, asteroid1.delay);  95 
 96     asteroid2.x  += asteroid2.velx;  97     if (asteroid2.x < 0 || asteroid2.x > SCREENW - asteroid2.width)  98         asteroid2.velx *= -1;  99  Sprite_Animate(asteroid2.frame, asteroid2.startframe, asteroid2.endframe, 100  asteroid2.direction, asteroid2.starttime, asteroid2.delay); 101 
102     //test for collisions
103     if (Collision(ship, asteroid1)) 104         asteroid1.velx *= -1; 105     
106     if (CollisionD(ship, asteroid2)) 107         asteroid2.velx *= -1; 108 
109     //start rendering
110     if (d3ddev->BeginScene()) 111  { 112         //start drawing
113         spriteobj->Begin(D3DXSPRITE_ALPHABLEND); 114 
115  Sprite_Transform_Draw(imgShip, ship.x, ship.y, ship.width, 116             ship.height,ship.frame, ship.columns, 0, 1.0f, ship.color); 117  Sprite_Transform_Draw(imgAsteroid, asteroid1.x, asteroid1.y, asteroid1.width, 118             asteroid1.height, asteroid1.frame, asteroid1.columns, 0, 1.0f, asteroid1.color); 119  Sprite_Transform_Draw(imgAsteroid, asteroid2.x, asteroid2.y, asteroid2.width, 120             asteroid2.height, asteroid2.frame, asteroid2.columns, 0, 1.0f, asteroid2.color); 121 
122         //stop drawing
123         spriteobj->End(); 124 
125         //stop rendering
126         d3ddev->EndScene(); 127         d3ddev->Present(NULL, NULL, NULL, NULL); 128  } 129 
130     //escape key exits
131     if (Key_Down(DIK_ESCAPE)) 132         gameover = true; 133 } 134 
135 void Game_End() 136 { 137     //free memory
138     if (imgShip) 139         imgShip->Release(); 140     if (imgAsteroid) 141         imgAsteroid->Release(); 142  DirectInput_Shutdown(); 143  Direct3D_Shutdown(); 144 }

 

最后放出运行截图,源代码,参考自游戏编程入门。

 D3DXSprite简单检测精灵碰撞_第1张图片

你可能感兴趣的:(Sprite)