• jQuery火箭图标返回顶部代码


    在进行以下内容前我们需先做好准备,明白都要做什么

    (1)编写碰撞函数(此时的函数不是完整的下面会对其修改):

       我们首先需要创建两个矩形并且调用IntersetRect函数来检查他们是否碰撞的函数。这个函数名为Collision,可重用性很好哦。

     1 int  Collision(SPRITE sprite1, SPRITE sprite2)
     2 {
     3     RECT rect1;
     4     rect1.left = sprite1.x;
     5     rect1.top = sprite1.y;
     6     rect1.right = sprite1.x + sprite1.width;
     7     rect1.bottom = sprite1.y + sprite1.height;
     8 
     9     RECT rect2;
    10     rect2.left = sprite2.x;
    11     rect2.top = sprite2.y;
    12     rect2.right = sprite2.x + sprite2.width;
    13     rect2.bottom = sprite2.y + sprite2.height;
    14 
    15     RECT dest;  //ignored
    16     return IntersectRect(&dest, &rect1, &rect2);
    17 }

    建议:你将注意到在collision函数上有编译器警告信息,因为SPRITE.x和SPRITE.y属性是浮点数,而RECT属性是长整型。要想去除这些警告,可将精灵属性轻质住阿奴按成

    long。

    (2)新的精灵结构:

     1 struct SPRITE {
     2     float x, y;
     3     int frame, columns;
     4     int width, height;
     5     float scaling, rotation;
     6     int startframe, endframe;
     7     int starttime, delay;
     8     int direction;
     9     float velx, vely;
    10     D3DCOLOR color;
    11     SPRITE()
    12     {
    13         frame = 0;
    14         columns = 1;
    15         width = height = 0;
    16         scaling = 1.0f;
    17         rotation = 0.0f;
    18         startframe = endframe = 0;
    19         direction = 1;
    20         starttime = delay = 0;
    21         velx = vely = 0.0f;
    22         color = D3DCOLOR_XRGB(255, 255, 255);
    23     }
    24 };

    (3)为精灵的缩放进行调整:

     1 int  Collision(SPRITE sprite1, SPRITE sprite2)
     2 {
     3     RECT rect1;
     4     rect1.left = (long)sprite1.x;
     5     rect1.top = (long)sprite1.y;
     6     rect1.right = (long)sprite1.x + sprite1.width + sprite1.scaling;
     7     rect1.bottom = (long)sprite1.y + sprite1.height + sprite1.scaling;
     8 
     9     RECT rect2;
    10     rect2.left = (long)sprite2.x;
    11     rect2.top = (long)sprite2.y;
    12     rect2.right = (long)sprite2.x + sprite2.width + sprite2.scaling;
    13     rect2.bottom = (long)sprite2.y + sprite2.height + sprite2.scaling;
    14 
    15     RECT dest;  //ignored
    16     return IntersectRect(&dest, &rect1, &rect2);
    17 }

    OK,到这里准备工作已完成(其实只是对MyDirectX.h和MyDirectX.cpp两个代码块进行了添加操作,其他的无变化哦),示例代码如下:

    MyDirectX.h:

      1 #pragma once
      2 //header files
      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 //libraries
     16 #pragma comment(lib,"winmm.lib")
     17 #pragma comment(lib,"user32.lib")
     18 #pragma comment(lib,"gdi32.lib")
     19 #pragma comment(lib,"dxguid.lib")
     20 #pragma comment(lib,"d3d9.lib")
     21 #pragma comment(lib,"d3dx9.lib")
     22 #pragma comment(lib,"dinput8.lib")
     23 #pragma comment(lib,"xinput.lib")
     24 
     25 //program values
     26 extern const string APPTITLE;
     27 extern const int SCREENW;
     28 extern const int SCREENH;
     29 extern bool gameover;
     30 
     31 //macro to detect key presses
     32 #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
     33 
     34 //Direct3D objects
     35 extern LPDIRECT3D9 d3d;
     36 extern LPDIRECT3DDEVICE9 d3ddev;
     37 extern LPDIRECT3DSURFACE9 backbuffer;
     38 extern LPD3DXSPRITE spriteobj;
     39 
     40 //Direct3D functions
     41 bool Direct3D_Init(HWND hwnd, int width, int height, bool fullscreen);
     42 void Direct3D_Shutdown();
     43 LPDIRECT3DSURFACE9 LoadSurface(string filename);
     44 void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source);
     45 D3DXVECTOR2 GetBitmapSize(string filename);
     46 LPDIRECT3DTEXTURE9 LoadTexture(string filename, D3DCOLOR transcolor = D3DCOLOR_XRGB(0, 0, 0));
     47 void Sprite_Draw_Frame(LPDIRECT3DTEXTURE9 texture, int destx, int desty, int framenum, int framew, int frameh, int columns);
     48 void Sprite_Animate(int &frame, int startframe, int endframe, int direction, int &starttime, int delay);
     49 void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, int frame = 0, int columns = 1,
     50                             float rotation = 0.0f, float scaling = 1.0f, D3DCOLOR color = D3DCOLOR_XRGB(255, 255, 255));
     51 
     52 //DirectInput objects, devices, and states
     53 extern LPDIRECTINPUT8 dinput;
     54 extern LPDIRECTINPUTDEVICE8 dimouse;
     55 extern LPDIRECTINPUTDEVICE8 dikeyboard;
     56 extern DIMOUSESTATE mouse_state;
     57 extern XINPUT_GAMEPAD controllers[4];
     58 
     59 //DirectInput functions
     60 bool DirectInput_Init(HWND);
     61 void DirectInput_Update();
     62 void DirectInput_Shutdown();
     63 bool Key_Down(int);
     64 int Mouse_Button(int);
     65 int Mouse_X();
     66 int Mouse_Y();
     67 void XInput_Vibrate(int contNum = 0, int amount = 65535);
     68 bool XInput_Controller_Found();
     69 
     70 //game functions
     71 bool Game_Init(HWND window);
     72 void Game_Run(HWND window);
     73 void Game_End();
     74 
     75 //sprite structure
     76 struct SPRITE {
     77     float x, y;
     78     int frame, columns;
     79     int width, height;
     80     float scaling, rotation;
     81     int startframe, endframe;
     82     int starttime, delay;
     83     int direction;
     84     float velx, vely;
     85     D3DCOLOR color;
     86     SPRITE()
     87     {
     88         frame = 0;
     89         columns = 1;
     90         width = height = 0;
     91         scaling = 1.0f;
     92         rotation = 0.0f;
     93         startframe = endframe = 0;
     94         direction = 1;
     95         starttime = delay = 0;
     96         velx = vely = 0.0f;
     97         color = D3DCOLOR_XRGB(255, 255, 255);
     98     }
     99 };
    100 //bouding box collision detection
    101 int  Collision(SPRITE sprite1, SPRITE sprite2);

    MyDirectX.cpp:

      1 #include "MyDirectX.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 XINPUT_GAMEPAD controllers[4];
     18 
     19 
     20 bool Direct3D_Init(HWND window, int width, int height, bool fullscreen)
     21 {
     22     //initialize Direct3D
     23     d3d = Direct3DCreate9(D3D_SDK_VERSION);
     24     if (!d3d) return false;
     25 
     26     //set Direct3D presentation parameters
     27     D3DPRESENT_PARAMETERS d3dpp;
     28     ZeroMemory(&d3dpp, sizeof(d3dpp));
     29     d3dpp.hDeviceWindow = window;
     30     d3dpp.Windowed = (!fullscreen);
     31     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
     32     d3dpp.EnableAutoDepthStencil = 1;
     33     d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
     34     d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
     35     d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
     36     d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
     37     d3dpp.BackBufferCount = 1;
     38     d3dpp.BackBufferWidth = width;
     39     d3dpp.BackBufferHeight = height;
     40 
     41     //create Direct3D device
     42     d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
     43         D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
     44     if (!d3ddev) return false;
     45 
     46 
     47     //get a pointer to the back buffer surface
     48     d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
     49 
     50     //create sprite object
     51     D3DXCreateSprite(d3ddev, &spriteobj);
     52 
     53     return 1;
     54 }
     55 
     56 void Direct3D_Shutdown()
     57 {
     58     if (spriteobj) spriteobj->Release();
     59 
     60     if (d3ddev) d3ddev->Release();
     61     if (d3d) d3d->Release();
     62 }
     63 
     64 void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source)
     65 {
     66     //get width/height from source surface
     67     D3DSURFACE_DESC desc;
     68     source->GetDesc(&desc);
     69 
     70     //create rects for drawing
     71     RECT source_rect = { 0, 0, (long)desc.Width, (long)desc.Height };
     72     RECT dest_rect = { (long)x, (long)y, (long)x + desc.Width, (long)y + desc.Height };
     73 
     74     //draw the source surface onto the dest
     75     d3ddev->StretchRect(source, &source_rect, dest, &dest_rect, D3DTEXF_NONE);
     76 
     77 }
     78 
     79 LPDIRECT3DSURFACE9 LoadSurface(string filename)
     80 {
     81     LPDIRECT3DSURFACE9 image = NULL;
     82 
     83     //get width and height from bitmap file
     84     D3DXIMAGE_INFO info;
     85     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);
     86     if (result != D3D_OK)
     87         return NULL;
     88 
     89     //create surface
     90     result = d3ddev->CreateOffscreenPlainSurface(
     91         info.Width,         //width of the surface
     92         info.Height,        //height of the surface
     93         D3DFMT_X8R8G8B8,    //surface format
     94         D3DPOOL_DEFAULT,    //memory pool to use
     95         &image,             //pointer to the surface
     96         NULL);              //reserved (always NULL)
     97 
     98     if (result != D3D_OK) return NULL;
     99 
    100     //load surface from file into newly created surface
    101     result = D3DXLoadSurfaceFromFile(
    102         image,                  //destination surface
    103         NULL,                   //destination palette
    104         NULL,                   //destination rectangle
    105         filename.c_str(),       //source filename
    106         NULL,                   //source rectangle
    107         D3DX_DEFAULT,           //controls how image is filtered
    108         D3DCOLOR_XRGB(0, 0, 0),   //for transparency (0 for none)
    109         NULL);                  //source image info (usually NULL)
    110 
    111                                 //make sure file was loaded okay
    112     if (result != D3D_OK) return NULL;
    113 
    114     return image;
    115 }
    116 
    117 
    118 D3DXVECTOR2 GetBitmapSize(string filename)
    119 {
    120     D3DXIMAGE_INFO info;
    121     D3DXVECTOR2 size = D3DXVECTOR2(0.0f, 0.0f);
    122 
    123     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);
    124 
    125     if (result == D3D_OK)
    126         size = D3DXVECTOR2((float)info.Width, (float)info.Height);
    127     else
    128         size = D3DXVECTOR2((float)info.Width, (float)info.Height);
    129 
    130     return size;
    131 }
    132 
    133 LPDIRECT3DTEXTURE9 LoadTexture(std::string filename, D3DCOLOR transcolor)
    134 {
    135     LPDIRECT3DTEXTURE9 texture = NULL;
    136 
    137     //get width and height from bitmap file
    138     D3DXIMAGE_INFO info;
    139     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);
    140     if (result != D3D_OK) return NULL;
    141 
    142     //create the new texture by loading a bitmap image file
    143     D3DXCreateTextureFromFileEx(
    144         d3ddev,                //Direct3D device object
    145         filename.c_str(),      //bitmap filename
    146         info.Width,            //bitmap image width
    147         info.Height,           //bitmap image height
    148         1,                     //mip-map levels (1 for no chain)
    149         D3DPOOL_DEFAULT,       //the type of surface (standard)
    150         D3DFMT_UNKNOWN,        //surface format (default)
    151         D3DPOOL_DEFAULT,       //memory class for the texture
    152         D3DX_DEFAULT,          //image filter
    153         D3DX_DEFAULT,          //mip filter
    154         transcolor,            //color key for transparency
    155         &info,                 //bitmap file info (from loaded file)
    156         NULL,                  //color palette
    157         &texture);            //destination texture
    158 
    159                               //make sure the bitmap textre was loaded correctly
    160     if (result != D3D_OK) return NULL;
    161 
    162     return texture;
    163 }
    164 
    165 
    166 bool DirectInput_Init(HWND hwnd)
    167 {
    168     //initialize DirectInput object
    169     DirectInput8Create(
    170         GetModuleHandle(NULL),
    171         DIRECTINPUT_VERSION,
    172         IID_IDirectInput8,
    173         (void**)&dinput,
    174         NULL);
    175 
    176     //initialize the keyboard
    177     dinput->CreateDevice(GUID_SysKeyboard, &dikeyboard, NULL);
    178     dikeyboard->SetDataFormat(&c_dfDIKeyboard);
    179     dikeyboard->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
    180     dikeyboard->Acquire();
    181 
    182     //initialize the mouse
    183     dinput->CreateDevice(GUID_SysMouse, &dimouse, NULL);
    184     dimouse->SetDataFormat(&c_dfDIMouse);
    185     dimouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
    186     dimouse->Acquire();
    187     d3ddev->ShowCursor(false);
    188 
    189     return true;
    190 }
    191 
    192 void DirectInput_Update()
    193 {
    194     //update mouse
    195     dimouse->Poll();
    196     if (!SUCCEEDED(dimouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouse_state)))
    197     {
    198         //mouse device lose, try to re-acquire
    199         dimouse->Acquire();
    200     }
    201 
    202     //update keyboard
    203     dikeyboard->Poll();
    204     if (!SUCCEEDED(dikeyboard->GetDeviceState(256, (LPVOID)&keys)))
    205     {
    206         //keyboard device lost, try to re-acquire
    207         dikeyboard->Acquire();
    208     }
    209 
    210     //update controllers
    211     for (int i = 0; i< 4; i++)
    212     {
    213         ZeroMemory(&controllers[i], sizeof(XINPUT_STATE));
    214 
    215         //get the state of the controller
    216         XINPUT_STATE state;
    217         DWORD result = XInputGetState(i, &state);
    218 
    219         //store state in global controllers array
    220         if (result == 0) controllers[i] = state.Gamepad;
    221     }
    222 }
    223 
    224 
    225 int Mouse_X()
    226 {
    227     return mouse_state.lX;
    228 }
    229 
    230 int Mouse_Y()
    231 {
    232     return mouse_state.lY;
    233 }
    234 
    235 int Mouse_Button(int button)
    236 {
    237     return mouse_state.rgbButtons[button] & 0x80;
    238 }
    239 
    240 bool Key_Down(int key)
    241 {
    242     return (bool)(keys[key] & 0x80);
    243 }
    244 
    245 
    246 void DirectInput_Shutdown()
    247 {
    248     if (dikeyboard)
    249     {
    250         dikeyboard->Unacquire();
    251         dikeyboard->Release();
    252         dikeyboard = NULL;
    253     }
    254     if (dimouse)
    255     {
    256         dimouse->Unacquire();
    257         dimouse->Release();
    258         dimouse = NULL;
    259     }
    260 }
    261 
    262 bool XInput_Controller_Found()
    263 {
    264     XINPUT_CAPABILITIES caps;
    265     ZeroMemory(&caps, sizeof(XINPUT_CAPABILITIES));
    266     XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps);
    267     if (caps.Type != 0) return false;
    268 
    269     return true;
    270 }
    271 
    272 void XInput_Vibrate(int contNum, int amount)
    273 {
    274     XINPUT_VIBRATION vibration;
    275     ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
    276     vibration.wLeftMotorSpeed = amount;
    277     vibration.wRightMotorSpeed = amount;
    278     XInputSetState(contNum, &vibration);
    279 }
    280 void Sprite_Draw_Frame(LPDIRECT3DTEXTURE9 texture, int destx, int desty, int framenum, int framew, int frameh, int columns)
    281 {
    282     D3DXVECTOR3 position((float)destx, (float)desty, 0);
    283     D3DCOLOR white = D3DCOLOR_XRGB(255, 255, 255);
    284 
    285     RECT rect;
    286     rect.left = (framenum % columns) * framew;
    287     rect.top = (framenum / columns) * frameh;
    288     rect.right = rect.left + framew;
    289     rect.bottom = rect.top + frameh;
    290 
    291     spriteobj->Draw(texture, &rect, NULL, &position, white);
    292 }
    293 
    294 void Sprite_Animate(int &frame, int startframe, int endframe, int direction, int &starttime, int delay)
    295 {
    296     if ((int)GetTickCount() > starttime + delay)
    297     {
    298         starttime = GetTickCount();
    299 
    300         frame += direction;
    301         if (frame > endframe) frame = startframe;
    302         if (frame < startframe) frame = endframe;
    303     }
    304 }
    305 void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, int frame, int columns, float rotation, float scaling, D3DCOLOR color)
    306 {
    307     //create a scale vector
    308     D3DXVECTOR2 scale(scaling, scaling);
    309     //create a translate vector
    310     D3DXVECTOR2 trans(x, y);
    311     //set center by dividing width and height by two
    312     D3DXVECTOR2 center((float)(width * scaling) / 2, (float)(height * scaling) / 2);
    313     //create 2D transformation matrix
    314     D3DXMATRIX mat;
    315     D3DXMatrixTransformation2D(&mat, NULL, 0, &scale, &center, rotation, &trans);
    316 
    317     //tell sprite object to use the transform
    318     spriteobj->SetTransform(&mat);
    319     //calculate frame location in source image
    320     int fx = (frame % columns) * width;
    321     int fy = (frame / columns) * height;
    322     RECT srcRect = { fx, fy, fx + width, fy + height };
    323     //draw the sprite frame
    324     spriteobj->Draw(image, &srcRect, NULL, NULL, color);
    325 }
    326 
    327 //bouding box collision detection
    328 int  Collision(SPRITE sprite1, SPRITE sprite2)
    329 {
    330     RECT rect1;
    331     rect1.left = (long)sprite1.x;
    332     rect1.top = (long)sprite1.y;
    333     rect1.right = (long)sprite1.x + sprite1.width + sprite1.scaling;
    334     rect1.bottom = (long)sprite1.y + sprite1.height + sprite1.scaling;
    335 
    336     RECT rect2;
    337     rect2.left = (long)sprite2.x;
    338     rect2.top = (long)sprite2.y;
    339     rect2.right = (long)sprite2.x + sprite2.width + sprite2.scaling;
    340     rect2.bottom = (long)sprite2.y + sprite2.height + sprite2.scaling;
    341 
    342     RECT dest;  //ignored
    343     return IntersectRect(&dest, &rect1, &rect2);
    344 }

    MyGame.cpp:

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

    MyWindows.cpp:

     1 #include "MyDirectX.h"
     2 using namespace std;
     3 bool gameover = false;
     4 
     5 
     6 LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
     7 {
     8     switch (msg)
     9     {
    10     case WM_DESTROY:
    11         gameover = true;
    12         PostQuitMessage(0);
    13         return 0;
    14     }
    15     return DefWindowProc(hWnd, msg, wParam, lParam);
    16 }
    17 
    18 
    19 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    20 {
    21     //initialize window settings
    22     WNDCLASSEX wc;
    23     wc.cbSize = sizeof(WNDCLASSEX);
    24     wc.style = CS_HREDRAW | CS_VREDRAW;
    25     wc.lpfnWndProc = (WNDPROC)WinProc;
    26     wc.cbClsExtra = 0;
    27     wc.cbWndExtra = 0;
    28     wc.hInstance = hInstance;
    29     wc.hIcon = NULL;
    30     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    31     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    32     wc.lpszMenuName = NULL;
    33     wc.lpszClassName = APPTITLE.c_str();
    34     wc.hIconSm = NULL;
    35     RegisterClassEx(&wc);
    36 
    37     //create a new window
    38     HWND window = CreateWindow(APPTITLE.c_str(), APPTITLE.c_str(),
    39         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
    40         SCREENW, SCREENH, NULL, NULL, hInstance, NULL);
    41     if (window == 0) return 0;
    42 
    43     //display the window
    44     ShowWindow(window, nCmdShow);
    45     UpdateWindow(window);
    46 
    47     //initialize the game
    48     if (!Game_Init(window)) return 0;
    49 
    50     // main message loop
    51     MSG message;
    52     while (!gameover)
    53     {
    54         if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
    55         {
    56             TranslateMessage(&message);
    57             DispatchMessage(&message);
    58         }
    59 
    60         //process game loop 
    61         Game_Run(window);
    62     }
    63 
    64     //shutdown
    65     Game_End();
    66     return message.wParam;
    67 }

    结果:

           当然了,边界碰撞检测产生相当精确的碰撞结果,而且非常快速。但是有些情况下这种方法不能很好的适应,比如使用带有圆角的美工作品或非常复杂的形状(比如带有突出机翼的飞机)。

    在非常情况下,具有另外一种检测碰撞的方法僵尸有好处的,而在这种情况下我们可以使用级与距离的碰撞算法。

           在使用距离确定两个精灵是否碰撞时,我们必须要做的是计算每个精灵中心点,计算精灵的半径(从中心点到边缘),然后检查两个中心点之间的距离。如果这个距离少于两个半径的

    和,那么就可以确定两个精灵有重叠。为什么呢?每个精灵的半径加起来必须小于两个精灵之间的距离。

    (1)计算距离:

      要计算任意两点之间的距离,我们只需参考经典的数学距离公式即可。通过将两点作为直角三角形两条边的顶点,任意两点都可转换成直角三角形。取得每个点的X和

    Y的delta值(差值),将每个delta值平方然后相加,然后求其平方根,就是两点间的距离。如下图:

    delta_x = x1 - x2

    delta_y = y1 - y2

    distance = square root ((delta_x * delta_x) + (delta_y * delta_y))

    (2)编写距离计算的代码:

      我们可以把这些内容编写到函数中,它使用两个精灵作为参数并从精灵的属性计算出delta值和距离。缩放因子也必须考虑在内,就如在边界框碰撞检测中所作的一样。

    此外,精灵的最大尺寸(不是宽度就是高度)将用于计算半径。我们首先计算第一个精灵的半径。

    1  if (sprite1.width > sprite1.height)
    2     radius1 = (sprite1.width * sprite1.scaling) / 2.0;
    3  else
    4     radius1 = (sprite1.height * sprite1.scaling) / 2.0;

           有了半径之后,在计算第一个精灵的中心点。我将把中心值存储存在的向量中。

    1 double x1 = sprite1.x + radius1;
    2 double y1 = sprite1.y + radius1;
    3 D3DXVECTOR2 vector1(x1, y1);

       这个名为vector1的向量包含了第一个精灵的中心点,无论他是否为与屏幕上。经相同的代码复制给第二个精灵,我们就会得到两个精灵的中心点和半径。一旦有了这

    些值,就可以开始进行距离计算了。首先涉及的是计算X和Y的delta值。

    1  double deltax = vector1.x - vector2.x;
    2  double deltay = vector2.y - vector1.y;

       有了这些delta值之后计算距离那就是非常容易的事情了。

    1 double dist = sqrt((deltax * deltax) + (deltay * deltay));

       我们将此编写到一个可重用的函数中。我将这个命名为CollisionD以便与边界框(Collision)区分开

     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 radius 2
    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 = vector2.y - vector1.y;
    30     double dist = sqrt((deltax * deltax) + (deltay * deltay));
    31 
    32     //return distance comparison
    33     return (dist < radius1 + radius2);
    34 }

       现在正是将这个函数复制到框架中的时候,我们这就来做,将这个函数添加到MyDirectX.cpp中,将原形添加到MyDirectX.h中。

    1 bool CollisionD(SPRITE sprite1, SPRITE sprite2);

    和上面个那个函数效果是一致的

  • 相关阅读:
    leetcode-剑指19-OK
    leetcode-剑指38-?
    leetcode-剑指36-OK
    leetcode-剑指41-OK
    leetcode-剑指20-OK
    leetcode-剑指16-OK
    nginx重写路由隐藏入口文件报错引发的思考
    Go之并发
    Go之接口
    Go实现学生管理系统
  • 原文地址:https://www.cnblogs.com/Trojan00/p/9562375.html
Copyright © 2020-2023  润新知