游戏编程入门之Bomb Catcher游戏

首先是代码:

MyDirectX.h:

 

 1 #pragma once
 2 //header file
 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<time.h>
11 #include<iostream>
12 #include<iomanip>
13 #include<sstream>
14 using namespace std;
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 //program values
25 extern const string APPTITLE;
26 extern const int SCREENW;
27 extern const int SCREENH;
28 extern bool gameover;
29 //Direct3D objects
30 extern LPDIRECT3D9 d3d;
31 extern LPDIRECT3DDEVICE9 d3ddev;
32 extern LPDIRECT3DSURFACE9 backbuffer;
33 //Direct3D functions
34 bool Direct3D_Init(HWND hwnd, int width, int height, bool fullscreen);
35 void Direct3D_Shutdown();
36 LPDIRECT3DSURFACE9 LoadSurface(string filename);
37 void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source);
38 //DirectInput objects,devices,and states
39 extern LPDIRECTINPUT8 dinput;
40 extern LPDIRECTINPUTDEVICE8 dimouse;
41 extern LPDIRECTINPUTDEVICE8 dikeyboard;
42 extern DIMOUSESTATE mouse_state;
43 extern XINPUT_GAMEPAD controllers[4];
44 //DirectInput functions
45 bool DirectInput_Init(HWND);
46 void DirectInput_Update();
47 void DirectInput_Shutdown();
48 int Key_Down(int);
49 int Mouse_Button(int);
50 int Mouse_X();
51 int Mouse_Y();
52 void XInput_Vibrate(int contNum = 0, int amount = 65535);
53 bool XInput_Controller_Found();
54 //game functions
55 bool Game_Init(HWND window);
56 void Game_Run(HWND window);
57 void Game_End();

 

 

MyDirectX.cpp:

 

  1 #include "MyDirectX.h"
  2 #include<iostream>
  3 using namespace std;
  4 //Direct3D variables
  5 LPDIRECT3D9 d3d = NULL;
  6 LPDIRECT3DDEVICE9 d3ddev = NULL;
  7 LPDIRECT3DSURFACE9 backbuffer = NULL;
  8 //DirectInput variables
  9 LPDIRECTINPUT8 dinput = NULL;
 10 LPDIRECTINPUTDEVICE8 dimouse = NULL;
 11 LPDIRECTINPUTDEVICE8 dikeyboard = NULL;
 12 DIMOUSESTATE mouse_state;
 13 char keys[256];
 14 XINPUT_GAMEPAD controllers[4];
 15 //Direct3D initiallization
 16 bool Direct3D_Init(HWND window, int width, int height, bool fullscreen)
 17 {
 18     //initialize Direct3D
 19     d3d = Direct3DCreate9(D3D_SDK_VERSION);
 20     if (!d3d) return false;
 21     //set Direct3D presentation parameters
 22     D3DPRESENT_PARAMETERS d3dpp;
 23     ZeroMemory(&d3dpp, sizeof(d3dpp));
 24     d3dpp.Windowed = (!fullscreen);
 25     d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
 26     d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
 27     d3dpp.BackBufferCount = 1;
 28     d3dpp.BackBufferWidth = width;
 29     d3dpp.BackBufferHeight = height;
 30     d3dpp.hDeviceWindow = window;
 31     //create Direct3D device
 32     d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
 33     if (!d3ddev) return false;
 34     //get a pointer to the back buffer surface
 35     d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
 36     return true;
 37 }
 38 //Direct3D shutdown
 39 void Direct3D_Shutdown()
 40 {
 41     if (d3ddev) d3ddev->Release();
 42     if (d3d) d3d->Release();
 43 }
 44 //Draw a surface to the screen using StretchRect
 45 void DrawSurface(LPDIRECT3DSURFACE9 dest, float x, float y, LPDIRECT3DSURFACE9 source)
 46 {
 47     //get width/height from source surface
 48     D3DSURFACE_DESC desc;
 49     source->GetDesc(&desc);
 50     //create rects for drawing
 51     RECT source_rect = { 0,0,(long)desc.Width,(long)desc.Height };
 52     RECT dest_rect = { (long)x,(long)y,(long)x + desc.Width,(long)y + desc.Height };
 53     //draw the source surface onto the dest
 54     d3ddev->StretchRect(source, &source_rect, dest, &dest_rect, D3DTEXF_NONE);
 55 }
 56 //Loads a bitmap file into a surface
 57 LPDIRECT3DSURFACE9 LoadSurface(string filename)
 58 {
 59     LPDIRECT3DSURFACE9 image = NULL;
 60     //get width and height from bitmap file
 61     D3DXIMAGE_INFO info;
 62     HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);
 63     if (result != D3D_OK) return NULL;
 64     //create surface
 65     result = d3ddev->CreateOffscreenPlainSurface(
 66         info.Width,                 //width of the surface
 67         info.Height,                //height of the surface
 68         D3DFMT_X8R8G8B8,            //surface format
 69         D3DPOOL_DEFAULT,            //memorypool to use
 70         & image,                    //pointer to the surface
 71         NULL);                      //reserved(always NULL)
 72     if (result != D3D_OK) return NULL;
 73     //Load surface from file into newly created surface
 74     result = D3DXLoadSurfaceFromFile(
 75         image,                      //destination surface
 76         NULL,                       //destination palette
 77         NULL,                       //destination rectangle
 78         filename.c_str(),           //source filename
 79         NULL,                       //source rectangle
 80         D3DX_DEFAULT,               //controls how image is filtered
 81         D3DCOLOR_XRGB(0, 0, 0),     //for transparency(0 for none)
 82         NULL);                      //source image info(usually NULL)
 83     //make sure file was loaded okay
 84     if (result != D3D_OK) return NULL;
 85     return image;
 86 }
 87 //DIrectInput initlization
 88 bool DirectInput_Init(HWND hwnd)
 89 {
 90     //initialize DirectInput object
 91     HRESULT result = DirectInput8Create(
 92         GetModuleHandle(NULL),
 93         DIRECTINPUT_VERSION,
 94         IID_IDirectInput8,
 95         (void**)&dinput,
 96         NULL);
 97     //initialize the keyboard
 98     dinput->CreateDevice(GUID_SysKeyboard, &dikeyboard, NULL);
 99     dikeyboard->SetDataFormat(&c_dfDIKeyboard);
100     dikeyboard->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
101     dikeyboard->Acquire();
102     //initialize the mouse
103     dinput->CreateDevice(GUID_SysMouse, &dimouse, NULL);
104     dimouse->SetDataFormat(&c_dfDIMouse);
105     dimouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
106     dimouse->Acquire();
107     d3ddev->ShowCursor(false);
108     return true;
109 }
110 //DirectInput update
111 void DirectInput_Update()
112 {
113     //update mouse
114     dimouse->GetDeviceState(sizeof(mouse_state), (LPVOID)&mouse_state);
115     //update keyboard
116     dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys);
117     //update controllers
118     for (int i = 0; i < 4; i++)
119     {
120         ZeroMemory(&controllers[i], sizeof(XINPUT_STATE));
121         //get the state of the controller
122         XINPUT_STATE state;
123         DWORD result = XInputGetState(i, &state);
124         //store state in global controllers array
125         if (result == 0) controllers[i] = state.Gamepad;
126     }
127 }
128 //Return mouse x movement
129 int Mouse_X()
130 {
131     return mouse_state.lX;
132 }
133 //Return mouse y movement
134 int Mouse_Y()
135 {
136     return mouse_state.lY;
137 }
138 //Return mouse button state
139 int Mouse_Button(int button)
140 {
141     return mouse_state.rgbButtons[button] & 0x80;
142 }
143 //Return key press state
144 int Key_Down(int key)
145 {
146     return (keys[key] & 0x80);
147 }
148 //DirectInput shutdown
149 void DirectInput_Shutdown()
150 {
151     if (dikeyboard)
152     {
153         dikeyboard->Unacquire();
154         dikeyboard->Release();
155         dikeyboard = NULL;
156     }
157     if (dimouse)
158     {
159         dimouse->Unacquire();
160         dimouse->Release();
161         dimouse = NULL;
162     }
163 }
164 //Return true if controller is plugged in
165 bool XInput_Controller_Found()
166 {
167     XINPUT_CAPABILITIES caps;
168     ZeroMemory(&caps, sizeof(XINPUT_CAPABILITIES));
169     XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps);
170     if (caps.Type != 0) return FALSE;
171 
172     return TRUE;
173 }
174 //Vibrates the controller
175 void XInput_Vibrate(int contNum, int amount)
176 {
177     XINPUT_VIBRATION vibration;
178     ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
179     vibration.wLeftMotorSpeed = amount;
180     vibration.wRightMotorSpeed = amount;
181     XInputSetState(contNum, &vibration);
182 }

 

 

MyGame.cpp:

 

  1 #include "MyDirectX.h"
  2 const string APPTITLE = "Bomb Catcher Game";
  3 const int SCREENW = 1024;
  4 const int SCREENH = 768;
  5 LPDIRECT3DSURFACE9 bomb_surf = NULL;
  6 LPDIRECT3DSURFACE9 bucket_surf = NULL;
  7 struct BOMB
  8 {
  9     float x, y;
 10     void reset()
 11     {
 12         x = (float)(rand() % (SCREENW - 128));
 13         y = 0;
 14     }
 15 };
 16 BOMB bomb;
 17 
 18 struct BUCKET
 19 {
 20     float x, y;
 21 };
 22 BUCKET bucket;
 23 int score = 0;
 24 int vibrating = 0;
 25 bool Game_Init(HWND window)
 26 {
 27     Direct3D_Init(window, SCREENW, SCREENH, false);
 28     DirectInput_Init(window);
 29     bomb_surf = LoadSurface("images/bomb.bmp");
 30     if (!bomb_surf) {
 31         MessageBox(window, "Error loadng bomb", "Error", 0);
 32         return false;
 33     }
 34     bucket_surf = LoadSurface("images/bucket.bmp");
 35     if (!bucket_surf) {
 36         MessageBox(window, "Error loadng bucket", "Error", 0);
 37         return false;
 38     }
 39     //get the back buffer surface
 40     d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
 41     //position the bomb
 42     srand((unsigned int)time(NULL));
 43     bomb.reset();
 44     //psition the bucket
 45     bucket.x = 500;
 46     bucket.y = 630;
 47     return true;
 48 }
 49 void Game_Run(HWND window)
 50 {
 51     //make sure the Direct3D device is valid
 52     if (!d3ddev)return;
 53     //update input device
 54     DirectInput_Update();
 55     //move the bomb down the screen
 56     bomb.y += 2.0f;
 57     //see if bomb hit the floor
 58     if (bomb.y > SCREENH)
 59     {
 60         MessageBox(0, "Oh,no, the bomb exploded!!", "YOU STINK", 0);
 61         gameover = true;
 62     }
 63     //move the bucket with the mouse
 64     int mx = Mouse_X();
 65     if (mx < 0)
 66         bucket.x -= 6.0f;
 67     else if (mx > 0)
 68         bucket.x += 6.0f;
 69     //move the bucket with the keyboard
 70     if (Key_Down(DIK_LEFT)) bucket.x -= 6.0f;
 71     else if (Key_Down(DIK_RIGHT)) bucket.x += 6.0f;
 72     //move the bucket with the controller
 73     if (XInput_Controller_Found())
 74     {
 75         //left analog thumb stick
 76         if (controllers[0].sThumbLX < -5000)
 77             bucket.x -= 6.0f;
 78         else if (controllers[0].sThumbLX > 5000)
 79             bucket.x += 6.0f;
 80         //left and right triggers
 81         if (controllers[0].bLeftTrigger > 128)
 82             bucket.x -= 6.0f;
 83         else if (controllers[0].bRightTrigger > 128)
 84             bucket.x += 6.0f;
 85         //left and right D-PAD
 86         if (controllers[0].wButtons&XINPUT_GAMEPAD_LEFT_SHOULDER)
 87             bucket.x -= 6.0f;
 88         else if (controllers[0].wButtons&XINPUT_GAMEPAD_RIGHT_SHOULDER)
 89             bucket.x += 6.0f;
 90         //left and right shoulders
 91         if(controllers[0].wButtons&XINPUT_GAMEPAD_DPAD_LEFT)
 92             bucket.x -= 6.0f;
 93         if (controllers[0].wButtons&XINPUT_GAMEPAD_DPAD_RIGHT)
 94             bucket.x += 6.0f;
 95     }
 96     //update vibration
 97     if (vibrating > 0)
 98     {
 99         vibrating++;
100         if (vibrating > 20)
101         {
102             XInput_Vibrate(0, 0);
103             vibrating = 0;
104         }
105     }
106     //keep bucket inside the screen
107     if (bucket.x < 0) bucket.x = 0;
108     if (bucket.x > SCREENW - 128) bucket.x = SCREENW - 128;
109     //see if bucket caugth the bomb
110     int cx = bomb.x + 64;
111     int cy = bomb.y + 64;
112     if (cx > bucket.x&&cx<bucket.x + 128 && cy>bucket.y&&cy < bucket.y + 128)
113     {
114         //update and display score
115         score++;
116         std::ostringstream os;
117         os << APPTITLE << " [SCORE " << score << "]";
118         string scoreStr = os.str();
119         SetWindowText(window, scoreStr.c_str());
120         //vibrate the controller
121         XInput_Vibrate(0, 65000);
122         vibrating = 1;
123         //restart bomb
124         bomb.reset();
125     }
126     //clear the backbuffer
127     d3ddev->ColorFill(backbuffer, NULL, D3DCOLOR_XRGB(0, 0, 0));
128     //start rendering
129     if (d3ddev->BeginScene())
130     {
131         //draw the bomb
132         DrawSurface(backbuffer, bomb.x, bomb.y, bomb_surf);
133         //draw the bucket
134         DrawSurface(backbuffer, bucket.x, bucket.y, bucket_surf);
135         //stop rendering
136         d3ddev->EndScene();
137         d3ddev->Present(NULL, NULL, NULL, NULL);
138     }
139     //escape key exits
140     if (Key_Down(DIK_SPACE) || Key_Down(DIK_ESCAPE))
141         gameover = true;
142     //controller Back button also exits
143     if (controllers[0].wButtons&XINPUT_GAMEPAD_BACK)
144         gameover = true;
145 }
146 void Game_End()
147 {
148     if (bomb_surf) bomb_surf->Release();
149     if (bucket_surf) bucket_surf->Release();
150     DirectInput_Shutdown();
151     Direct3D_Shutdown();
152 }

 

 

MyWindows.cpp:

 

 1 #include "MyDirectX.h"
 2 using namespace std;
 3 bool gameover = false;
 4 //Windows event handler
 5 LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 6 {
 7     switch (msg)
 8     {
 9     case WM_DESTROY:
10         gameover = true;
11         break;
12     }
13     return DefWindowProc(hWnd, msg, wParam, lParam);
14 }
15 //Windows entry point
16 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
17 {
18     WNDCLASSEX wc;
19     MSG msg;
20     wc.cbSize = sizeof(WNDCLASSEX);
21     wc.lpfnWndProc = (WNDPROC)WinProc;
22     wc.style = 0;
23     wc.cbClsExtra = 0;
24     wc.cbWndExtra = 0;
25     wc.hIcon = NULL;
26     wc.hIconSm = NULL;
27     wc.hInstance = hInstance;
28     wc.lpszMenuName = NULL;
29     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
30     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
31     wc.lpszClassName = "MainWindowClass";
32     if (!RegisterClassEx(&wc))
33         return FALSE;
34     HWND window = CreateWindow("MainWindowClass", APPTITLE.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, SCREENW, SCREENH, (HWND)NULL, (HMENU)NULL,
35         hInstance, (LPVOID)NULL);
36     if (window == 0)
37         return 0;
38     ShowWindow(window, nCmdShow);
39     UpdateWindow(window);
40     if (!Game_Init(window))
41         return 0;
42     while (!gameover)
43     {
44         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
45         {
46             TranslateMessage(&msg);
47             DispatchMessage(&msg);
48         }
49         Game_Run(window);
50     }
51     Game_End();
52     return msg.wParam;
53 }

 

 

结果:

游戏编程入门之Bomb Catcher游戏