Windows Game Programming Quick Start Method

xiaoxiao2021-03-06  35

Windows Game Programming Quick Start Method

Easideao (Simple Thoughts)

Preamble:

From 2001 to 2005, I have already spent 4 years of occupational game development career in unconsciousness. In these four years, some netizens will have a shortcut to me inquiry. Every time I don't know how to answer, I have always want to express my ideas and ideas, but I have never been able to express my insights in writing. In fact, I think the program is not a difficult thing. The most important thing is whether you are interested in him, it is hard to persist in learning. If you are not interested, even if you have just entered it, if you don't stick to it, it is nothing.

Although perseverance has an unsuspetent position in the process of learning, there is a suitable method and the method suitable for you. If your interest and perseverance have passed, I will write down with a game's code, I insist on writing, you insist on reading, follow the steps I tell. I won't tell all the details here, because it is too large task, my strength can not be realized, the following method is: I said how to do it, how do you do it, first know how to do something, when you Ability to make the correct results I have explained that you have already, if you don't know how to view the relevant information.

Some cumbersome said above, I am not willing to write it, my text is limited, please understand. The most important thing is to follow me. If you have any opinions or questions, you can send me E-mail: chinagdh@163.com.

Chapter 1 Windows program

Open Visual Studio 2003.net, select File -> Blank Solution.

Enter Battlecity in the Name column and press the OK button, press Browse to select Solution to save the location

3. Press the right button in Solution Explorer. Select Add -> New Project in the drop-down menu.

4. Select Visual C Projects -> Win32 -> Win32 Project in the Add New Project dialog box, hit TANK in the Name column and press Enter

5. Select Application Settings and hook in front of the Empty Project to create an empty Win32 project.

6. Press Right click on the TANK item to select Add -> New Folder Add Folder and Name WinApp

7. Press Right click on WinApp folder to select Add -> Add New Item

8. Select Visual C -> C File (.cpp) Enter winApp.cpp in the Name column.

9. Repeated 7.8 steps increase WinApp.h appentry.cpp appentry.h

10. Double-click WinApp.h Open File We add the following code in WinApp.h header files.

11. Treated APPENTRY.H in the same method. This method guarantees that the header is only included once, this is a way I like to use it. #Pragma overce

12. Open AppenTry.h Add to Code #include

13. Open WinApp.h Add to Code #include "AppenTry.h"

14. Open WinApp.cpp to join the code #include "winapp.h"

15. Define the primary program handle and the main window handle

16. Add Global Functions that get the master handle and the main window handle

17. For the convenience, the main program handle and the main window handle are declared in WinApp.h.

Hinstance getApphandle ();

HWnd getMainWnd (); 18. Define the Windows program main function, this is an entry function of a Windows program, we think the program starts from this function.

19. Select the TANK item in Solution Explorer, press Right click to select Build to compile, see if the program can be compiled.

Compile success will appear in the Output window Build: 1 succeeded, 0 failed, 0 Skipped means successful 0 failed 0 skipping

20. Set the path generated by TANK, press Right click on the project TANK to select Properties

21. Select the program generation path (Output file) is ../runtime/tank.exe

22. Select the Working Directory to compile it ../Runtime

23. Increase the initialization of several function programs, the main loop message processing function, the code is as follows

#include "winapp.h"

/ / Define the main program handle

Hinstance g_htheapp = NULL;

/ / Define the main window handle

HWnd g_hmainwnd = null;

//

/ / Get the main program handle

Hinstance getAppHandle ()

{

Return g_htheapp;

}

// Get the main window handle

HWND getMainWnd ()

{

Return g_hmainwnd;

}

//

// Windows program initialization

HWnd Appinit (Hinstance Hinstance, INT NSHOWCMD);

// Windows program ends

void appterm ();

// Windows message loop and main loop

int Appmsgloop ();

// Windows message handler

LResult Callback AppWndProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM);

//

// Windows program main function

Int Winapi WinMain

In hinstance hinstance,

In hinstance hprevinstance,

In lpstr lpcmdline,

INT nshowcmd

)

{

/ / Save the main program handle

g_htheapp = hinstance;

// Initialize the Window window and program

g_hmainwnd = appinit (g_htheapp, nshowcmd);

IF (g_hmainwnd == null)

{

Messagebox (Null, "Can't Create Main Window", "Error", MB_OK;

Return 0;

}

// Enter the main message loop

Return AppmsGloop ();

}

// Windows program initialization

HWnd Appinit (Hinstance Hinstance, INT NSHOWCMD)

{

Return NULL;

}

// Windows program ends

void appterm ()

{

}

// Windows message loop and main loop

int Appmsgloop ()

{

Return 0;

}

// Windows message handler

LResult Callback AppWndProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM)

{

Return DefWindowProc (HWND, MSG, WPARAM, LPARAM);

}

24. Register the program and create the main window in the appinit () function

// Windows program initializes hWnd appinit (Hinstance Hinstance, Int NshowCMD)

{

// Program instance class name

Static char szwindowsclassname [] = "tankbattlecity";

Static int tent = 800; // Window width

Static int opyheight = 600; // Window height

// Register window class

WNDCLASS WC;

Wc.style = CS_HREDRAW | CS_VREDRAW;

/ / Set the main window message processing function

Wc.lpfnwndproc = appwndproc;

wc.cbclsextra = 0;

wc.cbWndextra = 0;

wc.hinstance = hinstance;

wc.hicon = loading; 0, IDi_Application;

wc.hcursor = loadingcursor (0, IDC_ARROW);

Wc.hbrbackground = static_cast (getStockObject (White_brush));

wc.lpszMenuname = 0;

Wc.lpszclassname = szwindowsclassname;

IF (! RegisterClass (& WC))

{

MessageBox (NULL, "RegisterClass - Failed", "Error", MB_OK;

Return False;

}

// Create a main window

HWND HWND = CREATEWINDOW (SzWindowsClassName

, SzwindowsClassName

, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX

CW_USEDEFAULT

CW_USEDEFAULT

, IwindowWidth

, Iwindowheight

0

0

Hinstance

, 0);

IF (null == hwnd)

{

MessageBox (Null, "Create Main Window - Failed", "Error", MB_OK;

Return NULL;

}

// Display the main window

ShowWindow (hwnd, sw_show);

/ / Update the main window display content

UpdateWindow (HWND);

Return hwnd;

}

25. Writing AppMsgloop () program main loop

// Windows message loop and main loop

int Appmsgloop ()

{

MSG msg;

ZeromeMory (& MSG, SIZEOF (MSG));

_Apploop:

// Test if there is a message to be processed

IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_NOREMOVE))

{

// If the message is not received, you want to exit the program.

IF (! GetMessage (& MSG, NULL, 0, 0))

{

// Steering End Procedure

Goto _exitApp;

}

// Perform message processing

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

Else

{

// If there is no message to handle, call the main loop.

Sleep (1);

Goto _Apploop;

_ExitApp:

Apputerm ();

Return (int) msg.wparam;

}

26. Join the launch program message processing in the AppWndProc () function

// Windows message handler

LResult Callback AppWndProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM)

{

Switch (msg)

{

Case WM_DESTROY:

PostquitMessage (0);

Break;

}

Return DefWindowProc (HWND, MSG, WPARAM, LPARAM);

}

To now we can compile and implement a Windows program that does not do anything, I don't want to discuss anyone with any person on the code of code, such as in the appmsgloop () function, using goto and labels. I personally feel that it is not appropriate to discuss this problem. We are important to know how to make the program, about the details of Windows programming, you can check the "Windows programming" book.

Chapter II Simplified Program Interface

In the previous chapter, we introduced how to write a Windows program, have completed a simple Windows program with a main window, and then we wrote our game program. For future writing, the contents of each part of the program are independent, and we now start to define a simple program interface, we don't need to worry too much about Windows programs.

Program interface implementation we use the most common functional function in C to implement interface functions. Here you only need to know a Virtual keyword in front of the function defined in the base class, and you can override the function content in the derived class.

1. Open APPENTRY.H Enter the following program

#ifndef __appenTry_H__

#define __APPENTRY_H__

#include

Class IappenTry

{

PUBLIC:

// Initializer

Virtual Bool Initialize (Hinstance Hinstance, HWND HWND) = 0;

// End the program

Virtual void terminal () = 0;

// Main processing function

Virtual void process () = 0;

// Main rendering function

Virtual void render () = 0;

// Main window message processing function

Virtual Lresult WndProc (Uint Message, WPARAM WPARAM, LPARAM LPARAM) = 0;

// Define the Window program class function

Virtual const char * windowclassname () = 0;

/ / Define the Window Width

Virtual const Int windowWidth () = 0;

/ / Define the Height of the Window window

Virtual const INT windowHeight () = 0;

// Get the main program handle

Virtual Hinstance GetInstance () = 0;

// Get the main window handle

Virtual hwnd getWnd () = 0;

}

#ENDIF / / __APPENTRY_H__

Every function is written here with = 0 indicates that the function is a pure virtual function, and it must be rewritten in the derived class. This method is to define common methods for interfaces.

2. Open WinApp.cpp to join the following code

// Windows message loop and main loop

int Appmsgloop ();

// Windows message handler

LRESULT CALLBACK AppWndProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM); // Get simple program interface instance, we will define in GameApp.cpp

IAPPENTRY * APPENTRYCLASS ();

//

// Windows program main function

Int Winapi WinMain

In hinstance hinstance,

In hinstance hprevinstance,

In lpstr lpcmdline,

INT nshowcmd

)

3. Add the following code in the WinMain function

// Windows program main function

Int Winapi WinMain

In hinstance hinstance,

In hinstance hprevinstance,

In lpstr lpcmdline,

INT nshowcmd

)

{

/ / Save the main program handle

g_htheapp = hinstance;

// Initialize the Window window and program

g_hmainwnd = appinit (g_htheapp, nshowcmd);

IF (g_hmainwnd == null)

{

Messagebox (Null, "Can't Create Main Window", "Error", MB_OK;

Return 0;

}

// Initialization master program

IF (! appentryclass () -> initialize (g_htheapp, g_hmainwnd))

{

MessageBox (NULL, "Initialize AppenTry Failed", "Error", MB_OK;

Return 0;

}

// Enter the main message loop

Return AppmsGloop ();

}

4. Add the following code in the applerm () function

// Windows program ends

void appterm ()

{

// End the program

APPENTRYCLASS () -> Terminal ();

}

5. Add the following code in the AppMsgloop () function

// Windows message loop and main loop

int Appmsgloop ()

{

MSG msg;

ZeromeMory (& MSG, SIZEOF (MSG));

_Apploop:

// Test if there is a message to be processed

IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_NOREMOVE))

{

// If the message is not received, you want to exit the program.

IF (! GetMessage (& MSG, NULL, 0, 0))

{

// Steering End Procedure

Goto _exitApp;

}

// Perform message processing

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

Else

{

// If there is no message to handle, call the main loop.

AppenTryClass () -> Process ();

Sleep (1);

}

Goto _Apploop;

_ExitApp:

Apputerm ();

Return (int) msg.wparam;

}

6. Add the following code in the AppWndProc () function

// Windows message handler

LResult Callback AppWndProc (HWND HWND, UINT MSG, WPARAM WPARAM, LPARAM LPARAM)

{

Switch (msg)

{

Case WM_DESTROY:

PostquitMessage (0);

Break;

}

// Call the message processing function of the simple program interface, if returned, not false, complete the message processing / / otherwise, continues to call the Windows program default message processing function.

LRESULT LR = AppenTryClass () -> WndProc (MSG, WPARAM, LPARAM);

IF (lr! = false)

Return LR;

Return DefWindowProc (HWND, MSG, WPARAM, LPARAM);

}

7. Built a new directory GameApp on the TANK project and create two file appgame.cpp appgame.h

8. Add the following code in appgame.h

#ifndef __Appgame_H__

#define __Appgame_H__

#include "winapp.h"

Class Cappgame: Public IAPPENTRY

{

PUBLIC:

Cappgame ();

Virtual ~ cappgame ();

// Initializer

Virtual Bool Initialize (Hinstance Hinstance, HWND HWND);

// End the program

Virtual void terminal ();

// Main processing function

Virtual void process ();

// Main rendering function

Virtual void render ();

// Main window message processing function

Virtual LRESULT WNDPROC (Uint Message, WPARAM WPARAM, LPARAM LPARAM);

// Define the Window program class function

Virtual const char * windowclassname ();

/ / Define the Window Width

Virtual const Int windowwidth ();

/ / Define the Height of the Window window

Virtual const Int windowheight ();

// Get the main program handle

Virtual hinstance getInstance ();

// Get the main window handle

Virtual hwnd getWnd ();

protected:

/ / Save the main program handle

Hinstance M_HINSTANCE;

/ / Save the main window handle

HWND M_HWND;

}

#ENDIF / / __APPGAME_H__

9. Open AppGame.cpp to join the simple interface program instance, and get functions for program instance

#include "appgame.h"

/ / Define the primary game program instance

Cappgame theappgame;

// Define the simple program interface instance function, this is used in WinApp.cpp, and must be defined

// This is the interface of the Windows program call game program

IAPNTRY * APPENTRYCLASS ()

{

Return & theAppgame;

}

10. Add the following code to write the pure virtual function of the simple program interface

//

CAPPGAME :: Cappgame ()

{

M_HINSTANCE = NULL;

m_hwnd = NULL;

}

CAPPGAME :: ~ CAPPGAME ()

{

}

// Initializer

Bool Cappgame :: Initialize (Hinstance Hinstance, HWND HWND)

{

M_HINSTANCE = Hinstance;

m_hwnd = hwnd;

Return True;

}

// End the program

void cappgame :: terminal ()

{

}

// Main processing function

Void cappgame :: process ()

{

}

// Main rendering function

Void cappgame :: render ()

{

}

// Main window message processing function

LResult Cappgame :: WndProc (uint message, wparam wparam, lparam lparam) {

Return False;

}

// Define the Window program class function

Const char * cappgame :: windowclassname ()

{

Return "Tankbattlecity";

}

/ / Define the Window Width

Const int cappgame :: windowwidth ()

{

Return 800;

}

/ / Define the Height of the Window window

Const Int Cappgame :: WindowHeight ()

{

Return 600;

}

// Get the main program handle

Hinstance Cappgame :: getInstance ()

{

Return M_HINSTANCE;

}

// Get the main window handle

HWnd cappgame :: getWnd ()

{

Return m_hwnd;

}

11. Open WinApp.cpp and do the following modifications in the Appinit () function

// Windows program initialization

HWnd Appinit (Hinstance Hinstance, INT NSHOWCMD)

{

// Program instance class name

Const char * szwindowsclassname = appentryclass () -> windowclassname ();

Static int ● () -> windowwidth (); // Window width

Static int windowheight = appentryclass () -> windowheight (); // window height

// Register window class

WNDCLASS WC;

Wc.style = CS_HREDRAW | CS_VREDRAW;

12. Introduce a little tool. Add a utility directory on the TANK project to add formatstring.h and formatstring.cpp and join the following code

#ifndef __FormatString_H__

#define __fromatstring_h__

#include

// format string pad function template

Template Inline const char * formatstring (const char * szformat, ...)

{

Static char szoutstr [ibuflen];

SzoutStr [0] = 0;

VA_LIST VL;

VA_START (VL, SZFORMAT);

vSprintf (SzoutStr, Szformat, VL);

VA_END (VL);

ASSERT (Strlen (SzoutStr)

Return SzoutStr;

}

/ / I give a commonly used buffer size of 1024 bytes

#define fstr formatstring <1024>

// Usage:

// OutputDebugstring (FSTR ("Format Out% S", "OK");

#ENDIF / / __FORMATSTRING_H__

We can use it when any need to output a string format, which is very convenient. This cannot be used to nested calls, nor can it be used for complex thread calls, static char soutstr [ibuflen]; this is a unique memory address, and other function calls change his content will be wrong. That is to say, the string combined with this tool should be called immediately. Now our project file is as follows:

Chapter III Shows Images and Basic Drawings

This chapter I will show how to display pictures on the program main window with WindowsGDI, with GDI shows just for simple and convenient, to complete our task, and if you want more efficient methods, you can use the DirectX 3D or DirectDRAW interface.

1. First we are ready, I am putting it in Runtime.

Take name imagec.bmp, which is how to display this picture.

2. Add the render directory in the TANK project, and increase the file gdigraphicsdevice.cpp gdigraphicsdevice.h gdisurface.cpp gdisurface.h gditExtrender.cpp gditExtrender.h

3. Open GDIGRAPHICSDEVICE.H to join the following code

#ifndef __gdigraphicsdevice_h__

#define __gdigraphicsDevice_h__

#include

// Drawing equipment, here is the device that can be displayed on the screen, which is virtual,

// We call it graphic device.

Class CGDIGRAPHICSDEVICE

{

PUBLIC:

CGDIGRAPHICSDEVICE ();

Virtual ~ cgdigraphicsdevice ();

// Create a device, let the device operate object point to a window

Bool Create (HWND HWND, IWIDTH, INT IHEIGHT);

// Release device

Void release ();

/ / Update the display, make the main surface content on the screen

Void UpdateFrame (HDC HDC);

// Get the window of the operation pointing

HWND getWnd ();

protected:

// Adjust the window size

Void AdjuestWindowsize (int ingidth, int height);

protected:

// Operate the window handle

HWND M_HWND;

}

#ENDIF / / __GDIGRAPHICSDEVICE_H__

4. Open GDIGRAPHICSDEVICE.CPP to join the following code

#include "gdigraphicsdevice.h"

CGDIGRAPHICSDEVICE :: cgdigraphicsdevice ()

{

m_hwnd = NULL;

}

CGDIGRAPHICSDEVICE :: ~ cgdigraphicsDevice ()

{

}

Bool CgdigraphicsDevice :: Create (HWND HWND, INT IWIDTH, IHEIGHT)

{

Return True;

}

Void cgdigraphicsDevice :: release ()

{

}

Void CGDIGRAPHICSDEVICE :: UpdateFrame (HDC HDC)

{

}

HWnd cgdigraphicsDevice :: getWnd ()

{

Return m_hwnd;

}

//

// Adjust the window size to make the plot area equal to the size of the iWidth Iheight indication

Void CgdigraphicsDevice :: AdjuestWindowsize (int iWidth, Int Iheight)

{

}

5. Implement the adjustment window size function

// Adjust the window size to make the plot area equal to the size of the iWidth Iheight indication

Void CgdigraphicsDevice :: AdjuestWindowsize (int iWidth, Int Iheight)

{

/ / Define the location and window display area where the window is on the screen

RECT RCSCREEN, RCCLIENT;

// Get the location and window display area position on the window on the screen

GetWindowRect (M_HWND, & RCSCREEN);

GetClientRect (M_HWND, & RCCLIENT);

// Calculate the wide and high of the two regions

INT RSCREENWIDTH = rcscreen.right - rcscreen.Left 1;

Int rscreenheight = rcscreen.bottom - rcscreen.top 1;

Int rclientwidth = rcclient.right - rcclient.Left 1;

INT rclientHeight = rcclient.bottom - rcclient.top 1;

/ / Calculate the size of the two regions

INT rw = rscreenwidth - rclientwidth;

INT RH = RSCREENHHET - RCLIENTHEIGHT;

/ / Calculate the new window size

Rcscreen.right = iWidth rw;

RcScreen.bottom = IHEIGHT RH;

// Set the window size

SetwindowPos (M_HWND, NULL, RCSCREEN.LEFT, RCSCREEN.TOP, RCSCREEN.RIGHT, RCSCREEN.BOTTOM, SWP_FRAMECHANGED);

/ / Show Windows

Showwindow (m_hwnd, sw_show);

// Update window

UpdateWindow (M_HWND);

}

6. Implement the creation device function

// Create a device, let the device operate object point to a window

Bool CgdigraphicsDevice :: Create (HWND HWND, INT IWIDTH, IHEIGHT)

{

/ / Save the window handle

m_hwnd = hwnd;

// Adjust the size of the display area

AdjuesTWindowsize (iWidth, Iheight);

Return True;

}

7. Open GDisurface.h Enter the following code

#ifndef __gdisurface_h__

#define __gdisurface_h__

#include

Class CgdigraphicsDevice;

/ / The surface class is used to store a picture and use it to display pictures.

Class CgDisurface

{

PUBLIC:

// bit block transmission method

ENUM SURFACEBLTMODE

{

BLT_BLOCK, // copy mode, completely displayed on the target

BLT_ALPHATEST, / / ​​transparent color detection method, if you encounter the pure blue in the RGB (0, 0, 255) pictures, skipping

BLT_ALPHABLEND, // Not supported

}

CgDisurface ();

Virtual ~ cgdisurface ();

// Create a bitmap

Bool Create (cgdigraphicsdevice * pdevice, int obileidth, int height);

/ / Read a bitmap from the file

Bool loadbmp (cgdigraphicsdevice * pdevice, const char * szfilename); // Release bitmap

Void release ();

// Get wide

INT getWidth ();

// Get high

Int getHeight ();

// Get a bitmap device handle

HDC getDC ();

// Get a transparent channel bitmap device handle

HDC getmaskdc ();

/ / Clear the surface as a color

Void Clear (ColorRef C = RGB (0, 0, 0));

// Picture

Void SetPixel (int X, int y, colorref c);

// Picture

Void Line (int X1, int y1, int x2, int y2, colorref c);

// painted rectangle

Void Rect (int X1, int y1, int x2, int y2, colorref c);

// bitmap transmission

Void Blt (cgdisurface * psurface, int x, int y, int RX, int in, int w, int h, surfacebltmode sbrmode);

protected:

// Surface width

INT m_iwidth;

// surface height

Int m_iheight;

// bit map handle

Hbitmap m_hbitmap;

// bitmap transparent channel graph handle

Hbitmap m_hmaskbitmap;

/ / Save two bitmap sects

Hbitmap m_holdbitmap;

Hbitmap m_holdmaskbitmap;

// Two equipment handles displayed

// bitmap device handle

HDC M_HDC;

/ / Transparent channel bitmap device handle

HDC m_hmaskdc;

}

#ENDIF / / __GDISURFACE_H__

8. Open GDISURFACE.CPP Enter the following code

#include "gdisurface.h"

#include "gdigraphicsdevice.h"

CGDisurface :: cgdisurface ()

{

m_iwidth = 0;

m_iheight = 0;

m_hbitmap = null;

m_hmaskbitmap = null;

m_holdbitmap = null;

m_holdmaskbitmap = null;

M_HDC = NULL;

m_hmaskdc = NULL;

}

CGDisurface :: ~ cgdisurface ()

{

}

// Create a bitmap

Bool CGDisurface :: Create (cgdigraphicsdevice * pdevice, int obileidth, int height)

{

Return True;

}

/ / Read a bitmap from the file

Bool cgdisurface :: loadbmp (cgdigraphicsdevice * pdevice, const char * szfilename)

{

Return True;

}

// Release bitmap

Void cgdisurface :: release ()

{

}

// Get wide

Int cgdisurface :: getWidth ()

{

Return m_iwidth;

}

// Get high

Int cgdisurface :: getHeight ()

{

Return m_iheight;

}

// Get a bitmap device handle

HDC CGDisurface :: getDC ()

{

Return M_HDC;

}

// Get transparent channel bitmap equipment handle HDC CGDisurface :: getmaskdc ()

{

Return m_hmaskdc;

}

/ / Clear the surface as a color

Void CGDisurface :: CLORREF C)

{

}

// Picture

Void CGDisurface :: SetPixel (int X, int y, colorref c)

{

}

// Picture

Void CGDisurface :: Line (int X1, int y1, int x2, int y2, colorref c)

{

}

// painted rectangle

Void CGDisurface :: RECT (INT X1, INT Y1, INT X2, INT Y2, ColorRef C)

{

}

// bitmap transmission

Void CGDisurface :: Blt (CGDisurface * psurface, int x, int y, int RX, int rt, int w, int h, bltmode immande)

{

}

10. Implement a bitmap

// Create a bitmap

Bool CGDisurface :: Create (cgdigraphicsdevice * pdevice, int obileidth, int height)

{

// Get the master window drawing device handle

HWND HWND = PDEvice-> getWnd ();

HDC HDCWindow = :: getdc (hwnd);

// Create a graphic device handle

M_HDC = :: CreateCompatibleDC (HDCWindow);

m_hmaskdc = :: createcompatibledc (hdcwindow);

// Create a bitmap and transparent bitmap

M_Hbitmap = :: CreateCompatibleBitmap (HDCWindow, iWidth, IHEIGHT);

m_hmaskbitmap = :: CreateBitmap (iWidth, Iheight, 1, 1, null);

// Related equipment and bitmap handle

m_holdbitmap = (hbitmap) :: selectObject (m_hdc, m_hbitmap);

M_holdmaskbitmap = (hbitmap) :: selectObject (m_hmaskdc, m_hmaskbitmap);

// Make a transparent channel bitmap

:: setBkcolor (M_HDC, RGB (0,0,255));

:: Bitblt (m_hmaskdc, 0, 0, iWidth, Iheight, M_HDC, 0, 0, SRCCOPY);

:: setBkcolor (M_HDC, RGB (0,0,0));

:: SetTextColor (M_HDC, RGB (255, 255, 255);

:: Bitblt (M_HDC, 0, 0, IWidth, Iheight, M_HmaskDC, 0, 0, Srcand);

/ / Release the main window drawing handle

:: ReleaseDC (HWND, HDCWindow);

/ / Save surface size

m_iwidth = iWidth;

m_iheight = iHEight;

Return True;

}

11. Implementation from the file read bitmap, method, method, and create bitmap, just in place map from the file to be read from the file.

/ / Read a bitmap from the file

Bool cgdisurface :: loadbmp (cgdigraphicsdevice * pdevice, const char * szfilename)

{

// Read bitmap file information, determine the size of the bitmap

FILE * fp = fopen (SZFileName, "RB"); if (null == fp)

{

OutputDebugstring ("Open BMP file [% s] failed (% s:% d)", szfilename, __file__, __line__);

Return False;

}

BitmapfileHeader BMFH;

BitmapInfoheader BMIH;

Fread (& BMFH, SIZEOF (BitmapfileHeader), 1, FP);

Fread (& BMIH, Sizeof (BitmapInfoHeader), 1, FP);

Fclose (fp);

// If it is not a bitmap, return failed

IF (BMFH.BFTYPE! = 0x4d42)

{

OutputDebugstring ("The BMP file [% s] type is failed (% s:% d)", szfilename, __file__, __line__);

Return False;

}

Hbitmap HBMP = (Hbitmap) :: loadImage (null, szfilename, image_bitmap, bmih.biwidth, bmih.biheight, lr_luadfromfile | lr_createdibsection);

m_iwidth = bmih.biwidth;

m_iheight = bmih.biheight;

HWND HWND = PDEvice-> getWnd ();

HDC HDCWindow = :: getdc (hwnd);

M_Hbitmap = :: CreateCompatibleBitmap (HDCWindow, M_iWidth, M_iHeight);

m_hmaskbitmap = :: createBitmap (m_iwidth, m_iheight, 1, 1, null);

HDC HTEMPDC = :: CreateCompatibledc (HDCWINDOW);

M_HDC = :: CreateCompatibleDC (HDCWindow);

m_hmaskdc = :: createcompatibledc (hdcwindow);

Hbitmap Holdbitmap = (Hbitmap) :: SelectObject (HTEMPDC, HBMP);

m_holdbitmap = (hbitmap) :: selectObject (m_hdc, m_hbitmap);

M_holdmaskbitmap = (hbitmap) :: selectObject (m_hmaskdc, m_hmaskbitmap);

:: Bitblt (M_HDC, 0, 0, M_IWidth, M_iHeight, HTEMPDC, 0, 0, Srccopy);

:: setBkcolor (M_HDC, RGB (0,0,255));

:: Bitblt (m_hmaskdc, 0, 0, m_iwidth, m_iheight, m_hdc, 0, 0, srcopy);

:: setBkcolor (M_HDC, RGB (0,0,0));

:: SetTextColor (M_HDC, RGB (255, 255, 255);

:: Bitblt (m_hdc, 0, 0, m_iwidth, m_iheight, m_hmaskdc, 0, 0, srcand);

:: SelectObject (HTEMPDC, Holdbitmap); DeleteDC (HTEMPDC);

DeleteObject (HBMP);

:: ReleaseDC (HWND, HDCWindow);

Return True;

}

12. Realize the release bitmap

// Release bitmap

Void cgdisurface :: release ()

{

:: SelectObject (m_hdc, m_holdbitmap);

:: SelectObject (m_hmaskdc, m_holdmaskbitmap);

:: deletedc (m_hmaskdc);

:: Deletedc (m_hdc);

:: DeleteObject (m_hbitmap);

:: DeleteObject (m_hmaskbitmap;

}

13. Implement 4 basic drawing operations

/ / Clear the surface as a color

Void CGDisurface :: CLORREF C)

{

// Create a padding brush

Hbrush Hbrush = Createsolidbrush (C);

// Fill the entire surface

Rect Rect = {0, 0, M_IWidth, M_iHeight};

FillRect (M_HDC, & Rect, Hbrush);

// Release the brush

DeleteObject (Hbrush);

}

// Picture

Void CGDisurface :: SetPixel (int X, int y, colorref c)

{

:: setPixel (M_HDC, X, Y, C);

}

// Picture

Void CGDisurface :: Line (int X1, int y1, int x2, int y2, colorref c)

{

HPEN HPEN = Createpen (PS_SOLID, 1, C);

HPEN HOLDPEN = SELECTPEN (M_HDC, HPEN);

MoveToex (M_HDC, X1, Y1, (LPPOINT) NULL);

LINETO (M_HDC, X2, Y2);

SELECTPEN (M_HDC, HoldPen);

Deletepen (HPEN);

}

// painted rectangle

Void CGDisurface :: RECT (INT X1, INT Y1, INT X2, INT Y2, ColorRef C)

{

// draw 4 line rectangular border

LINE (X1, Y1, X2, Y1, C);

LINE (x1, y2, x2, y2, c);

LINE (X1, Y1, X1, Y2, C);

LINE (X2, Y1, X2, Y2, C);

}

14. Implement a bitmap transmission function

// bitmap transmission

Void CGDisurface :: Blt (CGDisurface * psurface, int x, int y, int RX, int rt, int w, int h, bltmode immande)

{

HDC HDCDST = Psurface-> getdc ();

Switch (Imode)

{

Case blt_block:

// Basic copy mode transmission bitmap

Bitblt (HDCDST, X, Y, W, H, M_HDC, RX, RY, SRCCOPY);

Break;

Case Blt_alphatest:

// Transparent color method transfer bitmap

Setbkcolor (HDCDST, RGB (255, 255, 255);

SetTextColor (HDCDST, RGB (0,0,0));

Bitblt (HDCDST, X, Y, W, H, M_HmaskDC, RX, RY, SRCAN);

Bitblt (HDCDST, X, Y, W, H, M_HDC, RX, RY, SRCPAINT); BREAK;

Case Blt_alphablend:

Break;

}

}

15. Open GDIGRAPHICSDEVICE.H to join the following code

#ifndef __gdigraphicsdevice_h__

#define __gdigraphicsDevice_h__

#include

Class cgdisurface;

// Drawing equipment, here is the device that can be displayed on the screen, which is virtual,

// We call it graphic device.

Class CGDIGRAPHICSDEVICE

{

PUBLIC:

CGDIGRAPHICSDEVICE ();

Virtual ~ cgdigraphicsdevice ();

// Create a device, let the device operate object point to a window

Bool Create (HWND HWND, IWIDTH, INT IHEIGHT);

// Release device

Void release ();

/ / Update the display, make the main surface content on the screen

Void UpdateFrame (HDC HDC);

// Get the window of the operation pointing

HWND getWnd ();

// Get the main surface

CGDisurface * getMainSurface ();

protected:

// Adjust the window size

Void AdjuestWindowsize (int ingidth, int height);

protected:

// Operate the window handle

HWND M_HWND;

// live down to the surface

CGDisurface * m_pmainsurface;

}

#ENDIF / / __GDIGRAPHICSDEVICE_H__

16. Open GDIGRAPHICSDEVICE.CPP to modify and add the following code

#include "gdigraphicsdevice.h"

#include "gdisurface.h"

CGDIGRAPHICSDEVICE :: cgdigraphicsdevice ()

{

m_hwnd = NULL;

m_pmainsurface = null;

}

CGDIGRAPHICSDEVICE :: ~ cgdigraphicsDevice ()

{

}

// Create a device, let the device operate object point to a window

Bool CgdigraphicsDevice :: Create (HWND HWND, INT IWIDTH, IHEIGHT)

{

/ / Save the window handle

m_hwnd = hwnd;

// Adjust the size of the display area

AdjuesTWindowsize (iWidth, Iheight);

M_PMAINSURFACE = New CGDisurface ();

Return True;

}

// Release device

Void cgdigraphicsDevice :: release ()

{

Delete m_pmainsurface;

m_pmainsurface = null;

}

17. Add to get the main surface function

// Get the main surface

CGDisurface * cgdigraphicsDevice :: getmainsurface ()

{

Return m_pmainsurface;

}

18. Add to create a main surface

// Create a device, let the device operate object point to a window

Bool CgdigraphicsDevice :: Create (HWND HWND, INT IWIDTH, IHEIGHT)

{

/ / Save the window handle

m_hwnd = hwnd;

// Adjust the display area size AdjuestWindowsize (iWidth, Iheight);

M_PMAINSURFACE = New CGDisurface ();

IF (! m_pmainsurface-> create (this, iWidth, Iheight))

{

OutputDebugstring (FSTR ("GraphicsDevice Create Main Surface Failed");

Return False;

}

Return True;

}

// Release device

Void cgdigraphicsDevice :: release ()

{

m_pmainsurface-> release ();

Delete m_pmainsurface;

m_pmainsurface = null;

}

19. Add update display function function

/ / Update the display, make the main surface content on the screen

Void CGDIGRAPHICSDEVICE :: UpdateFrame (HDC HDC)

{

// Returns if the main surface is not created successfully

IF (NULL == m_pmainsurface)

Return;

HDC HDCSRC = m_pmainsurface-> getdc ();

INT iWidth = m_pmainsurface-> getWidth ();

Int Iheight = m_pmainsurface-> getHeight ();

/ / Update the display to the screen will be called by WM_Paint

Bitblt (HDC, 0, 0, IWidth, Iheight, HDCSRC, 0, 0, SRCCopy);

}

20. In order to facilitate our joining a global data definition file on the project TANK, you can define a very public or important global variable here. And join two files sharedata.h sharedata.cpp

21. Open Sharedata.h Add to Code below

#ifndef __sharedata_h__

#define __sharedata_h__

#include "gdigraphicsdevice.h"

#include "gdisurface.h"

#include "gditextrender.h"

Extern CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE;

#ENDIF / / __SHAREDATA_H__

22. Open Sharedata.cpp Add below the code

#include "sharedata.h"

CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE = NULL;

23. Open the following code in the appgame.cpp

#include "appgame.h"

#include "sharedata.h"

CGDisurface.

/ / Define the primary game program instance

Cappgame theappgame;

24. Add the following code, create

// Initializer

Bool Cappgame :: Initialize (Hinstance Hinstance, HWND HWND)

{

M_HINSTANCE = Hinstance;

m_hwnd = hwnd;

// Create a graphics device

THEGRAPHICSDEVICE = New CGDIGRAPHICSDEVICE ();

IF (! THEGRAPHICSDEVICE-> CREATE (M_HWnd, WindowWidth (), WindowHeight ())) {

OutputDebugstring ("CREATE GraphicsDevice Failed);

Return False;

}

// Read bitmap

IF (! THESURFACE.LOADBMP (THEGRAPHICSDEVICE, "ImageC.BMP"))

{

OutputDebugstring ("Load Bitmap Failed");

Return False;

}

Return True;

}

// End the program

void cappgame :: terminal ()

{

// Release bitmap

Thessace.release ();

/ / Release graphics equipment

THEGRAPHICSDEVICE-> Release ();

DELETE THEGRAPHICSDEVICE;

}

25. Modify the following code to display the read picture

// Main processing function

Void cappgame :: process ()

{

Render ();

}

// Main rendering function

Void cappgame :: render ()

{

// Display bitmap

THESURFACE.BLT (THEGRAPHICSDEVICE-> GetMainSurface (), 0, 0, 0, 0, WindowWidth (), WindowHeight (), CGDisurface :: blt_block;

}

26. Add to update display code in the message processing function

// Main window message processing function

LRESULT CAPPGAME :: WndProc (uint message, wparam wparam, lparam lparam)

{

HDC HDC;

Paintstruct PS;

Switch (Message)

{

Case WM_Paint:

{

HDC = beginpaint (m_hwnd, & ps);

IF (THEGRAPHICSDEVICE)

{

// Call graphics device update display

THEGRAPHICSDEVICE-> UPDATEFRAME (HDC);

}

Endpaint (M_HWND, & PS);

}

Return True;

Case WM_ERASEBKGND:

Return True;

}

Return False;

}

27. Join the update display notification in Cappgame :: Render ()

// Main rendering function

Void cappgame :: render ()

{

// Display bitmap

THESURFACE.BLT (THEGRAPHICSDEVICE-> GetMainSurface (), 0, 0, 0, 0, WindowWidth (), WindowHeight (), CGDisurface :: blt_block;

/ / Notify the Window program to update the display window

Rect rcwindow;

GetClientRect (M_HWND, & RCWINDOW);

RedrawWindow (M_HWND, & RCWINDOW, NULL, RDW_INVALIDATE);

}

28. Operating procedures can see the following effects

29. Add the following code in Cappgame :: Render ()

// Main rendering function

Void cappgame :: render ()

{

/ / Clear the main surface

ThegraphicsDevice-> GetMainSurface () -> Clear (RGB (125, 0, 23));

// Display bitmap

THESURFACE.BLT (THEGRAPHICSDEVICE-> GetMainSurface (), 0, 0, 0, 0, WindowWidth (), WindowHeight (), cgdisurface :: blt_block; // Notify the Window program to update the display window

Rect rcwindow;

GetClientRect (M_HWND, & RCWINDOW);

RedrawWindow (M_HWND, & RCWINDOW, NULL, RDW_INVALIDATE);

}

Everyone can see the following effects

30. Modify CAPPGAME :: Render () to

Void cappgame :: render ()

{

/ / Clear the main surface

ThegraphicsDevice-> GetMainSurface () -> Clear (RGB (125, 0, 23));

// Display bitmap

S &urface.blt (THEGRAPHICSDEVICE-> GetMainSurface (), 0, 0, 0, 0, WindowWidth (), WindowHeight (), cgdisurface :: blt_alphates;

/ / Notify the Window program to update the display window

Rect rcwindow;

GetClientRect (M_HWND, & RCWINDOW);

RedrawWindow (M_HWND, & RCWINDOW, NULL, RDW_INVALIDATE);

}

Can see the following effects

There is no blue blue, and the method is changed to transparent way.

31. We change thesurface to theimagec and put it in sharedata.cpp to define it for easy use.

// Initializer

Bool Cappgame :: Initialize (Hinstance Hinstance, HWND HWND)

{

M_HINSTANCE = Hinstance;

m_hwnd = hwnd;

// Create a graphics device

THEGRAPHICSDEVICE = New CGDIGRAPHICSDEVICE ();

IF (! THEGRAPHICSDEVICE-> Create (m_hwnd, windowwidth (), windowheight ())))

{

OutputDebugstring ("CREATE GraphicsDevice Failed);

Return False;

}

// Read bitmap

Theimagec = new cgdisurface ();

IF (! theimagec-> loadingbmp (thegraphicsdevice, "imagec.bmp")))

{

OutputDebugstring ("Load Bitmap Failed");

Return False;

}

Return True;

}

// End the program

void cappgame :: terminal ()

{

// Release bitmap

Theimagec-> Release ();

DELETE theIMAGEC;

Theimagec = NULL;

/ / Release graphics equipment

THEGRAPHICSDEVICE-> Release ();

DELETE THEGRAPHICSDEVICE;

ThegraphicsDevice = NULL;

}

// Main processing function

Void cappgame :: process ()

{

Render ();

}

// Main rendering function

Void cappgame :: render ()

{

/ / Clear the main surface

THEGRAINSDEVICE-> GetMainSurface () -> Clear (RGB (125, 0, 23)); // Display bitmap

THEIMAGEC-> BLT (THEGRAPHICSDEVICE-> GetMainSurface (), 0, 0, 0, 0, Windowwidth (), WindowHeight (), cgdisurface :: blt_alphatest);

/ / Notify the Window program to update the display window

Rect rcwindow;

GetClientRect (M_HWND, & RCWINDOW);

RedrawWindow (M_HWND, & RCWINDOW, NULL, RDW_INVALIDATE);

}

Chapter 4 Text Display Timer Refresh Rate

Some important information when writing programs, help debug programs, where text is very important. Timer We will use the system function TimegetTime (), which is used to get the system from the beginning to the milliseconds experienced, record a start time, and then constantly judgment the current time and start time interval to achieve a certain paragraph The code is performed at a certain frequency. The refresh rate is to indicate how many times the update is displayed within a second, and finally we display it on the screen.

1. Open GDITEXTRENDER.H Enter the following code

#ifndef __gditextRender_H__

#define __gditextRender_H__

#include

Class cgdisurface;

// Text display class

Class CgditeXtrender

{

PUBLIC:

CGDiteXtrender ();

Virtual ~ cgditeXtrender ();

// Create a font

Bool Create (PLogFont Pfont);

// freed

Void release ();

/ / Output text to the surface

Void textout (CGDisurface * psurface, int x, int y, const char * szstring, colorref c, int LEN = 0);

protected:

// font handle

HFONT M_HFONT;

}

#ENDIF / / __GDITEXTRENDER_H__

2. Open GDITEXTRENDER.CPP to enter the following code

#include "gditextrender.h"

CGDiteXtrender :: cgditextRender ()

{

M_HFONT = NULL;

}

CGDITEXTRENDER :: ~ cgditextrender ()

{

}

// Create a font

Bool CGDITEXTRENDER :: Create (Plogfont Pfont)

{

Return True;

}

// freed

Void cgditeXtrender :: release ()

{

}

/ / Output text to the surface

Void CGDiteXtrender :: Textout (CGDisurface * Psurface, Int x, int y, const char * szstring, colorref c, int LEN)

{

}

3. Implement the creation of font functions

// Create a font

Bool CGDITEXTRENDER :: Create (Plogfont Pfont)

{

// Create a font specified by PFont

m_hfont = cretefont

Pfont-> lfheight,

PFONT-> LFWIDTH,

Pfont-> LFESCAPEMENT,

PFONT-> LirtIntation, Pfont-> LFWeight,

Pfont-> lfitalic,

PFONT-> Lfunderline,

PFONT-> LFSTRIKEOUT,

Pfont-> lfcharset,

Pfont-> lfoutPrecision,

PFONT-> LFCLIPPRecision,

PFONT-> LFQuality,

Pfont-> LFPITCHFAMILY,

PFONT-> LFFCENAME);

IF (m_hfont == null)

{

Outputdebugstring (FSTR ("Create Font Failed:% S% D / N", PFONT-> LFFACENAME, PFONT-> LFHEIGHT);

Return False;

}

Return True;

}

4. Realize the release font

// freed

Void cgditeXtrender :: release ()

{

// If the font has been created

IF (m_hfont)

{

// Delete the font handle

DeleteObject (M_HFONT);

M_HFONT = NULL;

}

}

5. Modify the text output function, join the output text function

#include "gditextrender.h"

#include "gdisurface.h"

#include "formatstring.h"

#include

/ / Output text to the surface

Void CGDiteXtrender :: Textout (CGDisurface * Psurface, Int x, int y, const char * szstring, colorref c, int LEN)

{

/ / If the specified string length is 0

IF (len == 0)

{

// Automatically get strings length

Len = (int) Strlen (szstring);

}

// Get a surface device handle

HDC HDC = psurface-> getDC ();

// Select the font

HFONT HOLDFONT = SELECTFONT (HDC, M_HFONT);

// Show text

SetBKMode (HDC, Transparent);

SetBkcolor (HDC, RGB (0, 0));

SetTextColor (HDC, C);

:: Textout (HDC, X, Y, Szstring, Len);

// Restore the font

SELECTFONT (HDC, HoldFont);

}

6. Open Sharedata.h Add to Code

#ifndef __sharedata_h__

#define __sharedata_h__

#include "gdigraphicsdevice.h"

#include "gdisurface.h"

#include "gditextrender.h"

Extern CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE;

EXTERN CGDISURFACE *.

Extern CGDITEXTRENDER * THHETEXTRENDER;

#ENDIF / / __SHAREDATA_H__

7. Open Sharedata.cpp to add the following code

#include "sharedata.h"

CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE = NULL;

CGDisurface * theimagec = null; cgditeXtrender * ThetExTrender = NULL;

8. Open AppGame.cpp to join the initialization text output function and release

// Initializer

Bool Cappgame :: Initialize (Hinstance Hinstance, HWND HWND)

{

M_HINSTANCE = Hinstance;

m_hwnd = hwnd;

// Create a graphics device

THEGRAPHICSDEVICE = New CGDIGRAPHICSDEVICE ();

IF (! THEGRAPHICSDEVICE-> Create (m_hwnd, windowwidth (), windowheight ())))

{

OutputDebugstring ("CREATE GraphicsDevice Failed);

Return False;

}

// Read bitmap

Theimagec = new cgdisurface ();

IF (! theimagec-> loadingbmp (thegraphicsdevice, "imagec.bmp")))

{

OutputDebugstring ("Load Bitmap Failed");

Return False;

}

// Initialize the text output function

Logfont fontinfo = {16, 0, 0, 0,

FW_NORMAL, FALSE, FALSE, FALSE,

Default_charset, OUT_DEFAULT_PRECIS,

CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY,

Variable_pitch,

"体"}

Thetrender = new cgditextrender ();

IF (! Thetrender-> Create (& FONTINFO))

{

OutputDebugstring ("Create Thetrender Failed / N);

Return False;

}

Return True;

}

// End the program

void cappgame :: terminal ()

{

// Release the text output function

Thetextrender-> Release ();

Delete thetextrender;

ThetRender = NULL;

// Release bitmap

Theimagec-> Release ();

DELETE theIMAGEC;

Theimagec = NULL;

/ / Release graphics equipment

THEGRAPHICSDEVICE-> Release ();

DELETE THEGRAPHICSDEVICE;

ThegraphicsDevice = NULL;

}

9. Do the following modifications in the Cappgame :: Render () function to test the text output function

// Main rendering function

Void cappgame :: render ()

{

CGDisurface * pscreen = THEGRAPHICSDEVICE-> getMainSurface ();

/ / Clear the main surface

Pscreen-> Clear (RGB (125, 0, 23));

// Display bitmap

Theimagec-> BLT (Pscreen, 0, 0, 0, 0, WindowWidth (), WindowHeight (), CGDisurface :: blt_alphatest);

// Show text

TEXTRENDER-> Textout (pscreen, 0, 0, "test text ABC", RGB (255, 255, 255)); // Notify the Window program update display window

Rect rcwindow;

GetClientRect (M_HWND, & RCWINDOW);

RedrawWindow (M_HWND, & RCWINDOW, NULL, RDW_INVALIDATE);

}

See the following results

10. Add fps.cpp fps.h in the TANK project uTility catalog.

11. Open FPS.H Enter the following code

#ifndef __fps_h__

#define __fps_h__

#include

// FPS class

Class CFPS

{

PUBLIC:

CFPS ();

Virtual ~ cfps ();

// Statistics, no one counter plus 1 and determine if the calculation FPS

Void count ();

// Get fps

INT getfps ();

protected:

// Record refresh rate

INT m_IFPS;

// Statistics

Int m_icount;

// Time to record the FPS last time

DWORD M_DWPREVRECORDFPSTIME;

/ / Calculate the FPS time interval

DWORD M_DWRECORDFPSINTERVAL;

}

#ENDIF / / __FPS_H__

12. Open fps.cpp Enter the following code

#include "fps.h"

#include

#pragma comment (Lib, "Winmm.Lib")

CFPS :: cfps ()

{

m_icount = 0;

m_ifps = 0;

m_dwprevrecordfpstime = 0;

m_dwrecordfpsinterval = 1000; // 1 second record

}

CFPS :: ~ cfps ()

{

}

Void cfps :: count ()

{

// No call once

m_icount ;

// If time has passed 1000 milliseconds

IF (TimegetTime () - m_dwprevrecordfpstime> = m_dwrecordfpsInterval

{

// Record 1 second call number

m_ifps = m_icount;

// Reset Counter

m_icount = 0;

// Reset start timing time

m_dwprevrecordfpstime = TimegetTime ();

}

}

Int cfps :: getfps ()

{

Return M_IFPS;

}

13. Add the following code in Sharedata.h and Sharedata.cpp, respectively.

Sharedata.h:

#ifndef __sharedata_h__

#define __sharedata_h__

#include "gdigraphicsdevice.h"

#include "gdisurface.h"

#include "gditextrender.h"

#include "fps.h"

Extern CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE;

EXTERN CGDISURFACE *.

Extern CGDITEXTRENDER * THHETEXTRENDER;

EXTERN CFPS * THHENDERFPS;

#ENDIF / / __SHAREDATA_H__

Sharedata.cpp:

#include "sharedata.h" cgdigraphicsdevice * thegraphicsdevice = null;

CGDisurface * theimagec = null;

CGDiteXtrender * thetextrender = NULL;

Cfps * therenderfps = NULL;

14. Add the following code to Cappgame :: Initialize () and Cappgame :: Terminal () in AppGame.cpp

Thetrender = new cgditextrender ();

IF (! Thetrender-> Create (& FONTINFO))

{

OutputDebugstring ("Create Thetrender Failed / N);

Return False;

}

// Create a rendering refresh rate statistical device

Therenderfps = new cfps ();

Return True;

}

// End the program

void cappgame :: terminal ()

{

/ / Release Rendering Refunction Statist

Delete arenderfps;

// Release the text output function

Thetextrender-> Release ();

15. Add refresh rate statistics in the cappgame :: render () function and display it on the screen, and

AppGame.cpp tops Add to #include "formatstring.h"

// Main rendering function

Void cappgame :: render ()

{

CGDisurface * pscreen = THEGRAPHICSDEVICE-> getMainSurface ();

/ / Clear the main surface

Pscreen-> Clear (RGB (127, 127, 127));

// Display bitmap

// Theimagec-> BLT (Pscreen, 0, 0, 0, 0, WindowWidth (), WindowHeight (), CGDisurface :: blt_alphatest);

// Show text

TEXTRENDER-> Textout (Pscreen, 0, 0, FSTR ("FPS =% 2D", therenderfps-> getfps ()), RGB (255, 255, 255);

/ / Notify the Window program to update the display window

Rect rcwindow;

GetClientRect (M_HWND, & RCWINDOW);

RedrawWindow (M_HWND, & RCWINDOW, NULL, RDW_INVALIDATE);

Therenderfps-> count ();

}

The operation program sees the following effects

16. In order to give the CPU more time, we don't need a program to run very fast, how we limit the rendering speed, open AppGame.h to add the following code, then run the FPS is already 30

protected:

/ / Save the main program handle

Hinstance M_HINSTANCE;

/ / Save the main window handle

HWND M_HWND;

// last rendering time

DWORD M_DWRENDERLASTTIME;

}

17. Add to the main rendering function

// Main rendering function

Void cappgame :: render ()

{

IF (timegettime () - m_dwrenderlasttime <33)

{

Return;

}

m_dwrenderlasttime = timegettime ();

Chapter 5 Elf Animation

Small people who ran around in the game, puppy, tank, etc. As shown in Figure 28x28 size, a piece of film is a picture of the elf animation. The next one is the second, we call each picture, we say that the top of Tank is 2 frames. In our project, we define the framework method is to record a graphic location and size.

As shown in Figures x, y, w, h show a frame.

1. Add a directory Animation in the TANK project, and add 6 files frame.h

Frame.cpp Animation.h Animation.cpp SpriteManager.h SpriteManager.cpp

2. Add frame class code in frame.h and frame.cpp

Frame.h:

#ifndef __frame_h__

#define __frame_h__

#include "gdisurface.h"

// Animation frame class

Class cframe

{

PUBLIC:

/ / Location and size on ImageC

INT M_IX;

INT m_iy;

INT m_iw;

INT M_IH;

// Rendering to the surface

Void Render (CGDisurface * psurface, int ix, int y, cgdisurface :: bltmode immande);

}

#ENDIF / / __FRAME_H__

Frame.cpp:

#include "frame.h"

#include "sharedata.h"

// Rendering to the surface

Void Cframe :: Render (cgdisurface * psurface, int ix, int y, cgdisurface :: bltmode ivode)

{

Theimagec-> BLT (Psurface, IX, IY, M_IX, M_IY, M_IW, M_IH, IMODE);

}

3. Open Animation.h Enter the following code

#ifndef __animation_h__

#define __animation_h__

#include "frame.h"

#include

// animation class

Class Canimation

{

PUBLIC:

CANIMATION ();

Virtual ~ canimation ();

// Add frame

Void Push (CFrame & F);

// Get the number of frames

INT getMaxFrame ();

// Get a frame data

Cframe * getframe (int iframe);

protected:

// frame data

Std :: Vector m_vectorframe;

}

#ENDIF / / __ANAMATION_H___

4. Open Animation.cpp Enter the following code

#include "animation.h"

CANIMATION :: canimation ()

{

m_vectorframe.clear ();

}

CANIMATION :: ~ canimation ()

{

m_vectorframe.clear ();

}

// Add frame

Void CANIMATION :: Push (cframe & f)

{

m_vectorframe.push_back (f);

}

// Get the number of frames

INT canIMation :: getmaxframe ()

{

Return (int) m_vectorframe.size ();

}

// Get a frame data

Cframe * canimation :: getFrame (int iframe)

{

IF (iframe <0 &&ness> = (int) m_vectorframe.size ())

Return NULL;

Return & M_VectorFrame [iframe];

}

5. Open SpriteManager.h Enter the following code

#ifndef __spritemanager_h__

#define __SpriteManager_H__

#include "animation.h"

Class CspriteManager

{

PUBLIC:

CSPriteManager ();

Virtual ~ cspritemanager ();

// Create an animation data set

Bool crete ();

// Release the animation data set

Void release ();

// Get animated data

CANIMATION * GetAnimation (int INDEX);

// Total animation

Int getAnimationNumber ();

protected:

// Store animation data

Std :: Vector M_VectoraniMation;

}

#ENDIF / / __SPRITEMANAGER_H__

6. Open SpriteManager.cpp Enter the following code

#include "spritemanager.h"

CSPRITEMANAGER :: CSPriteManager ()

{

}

CSPriteManager :: ~ cspritemanager ()

{

}

// Create an animation data set

Bool cspritemanager :: create ()

{

Return True;

}

// Release the animation data set

Void CspriteManager :: release ()

{

m_vectoranimation.clear ();

}

// Get animated data

Canimation * CSPRITEMANAGER :: GetAnimation (int index)

{

IF (Index <0 || index> = (int) m_vectoranimation.size ())

Return NULL;

// Return to the animation referred to in INDEX

Return & M_VectoraniMation [index];

}

// Total animation

Int cspritemanager :: getAnimationNumber ()

{

Return (int) m_vectoranimation.size ();

}

7. Add the first animation in CSPRITEMANAGER :: Create (), the animation may also have only one frame. Below is the first two frames to 0 animations. The same method can be added to all animations in this function.

// Create an animation data set

Bool cspritemanager :: create ()

{

CANIMATION * PANI;

Cframe F;

// First animation

PANI = New canimation ();

// First frame (0, 0, 28, 28)

f.m_ix = 0;

F.m_iy = 0;

f.m_iw = 28;

F.m_ih = 28;

PANI-> Push (f);

// Second frame (28, 0, 28, 28)

f.m_ix = 28;

F.m_iy = 0;

f.m_iw = 28;

F.m_ih = 28;

PANI-> Push (f);

// ani id = 0 two frame animations joining animation library

m_vectoranimation.push_back (* pani); delete PANI;

Return True;

}

8. Add the following code in Sharedata.h Sharedata.cpp, respectively

Sharedata.h:

#ifndef __sharedata_h__

#define __sharedata_h__

#include "gdigraphicsdevice.h"

#include "gdisurface.h"

#include "gditextrender.h"

#include "fps.h"

#include "spritemanager.h"

Extern CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE;

EXTERN CGDISURFACE *.

Extern CGDITEXTRENDER * THHETEXTRENDER;

EXTERN CFPS * THHENDERFPS;

Extern CSPRITEMANAGER * SHESPRITEMANAGER;

#ENDIF / / __SHAREDATA_H__

Sharedata.cpp:

#include "sharedata.h"

CGDIGRAPHICSDEVICE * THEGRAPHICSDEVICE = NULL;

CGDisurface * theimagec = null;

CGDiteXtrender * thetextrender = NULL;

Cfps * therenderfps = NULL;

CSPRITEMANAGER * SHESPRITEMANAGER = NULL;

9. Add the following initialization and release animator code in AppGame.cpp

Thetrender = new cgditextrender ();

IF (! Thetrender-> Create (& FONTINFO))

{

OutputDebugstring ("Create Thetrender Failed / N);

Return False;

}

// Create a rendering refresh rate statistical device

Therenderfps = new cfps ();

// Create an animation manager

ThessiTemanager = new cspritemanager ();

IF (! thispritemanager-> create ())

{

OutputDebugstring ("Create Sprite Manager Failed / N);

Return False;

}

Return True;

}

// End the program

void cappgame :: terminal ()

{

// Release the animator manager

Thespritemanager-> release ();

DELETE S &PRITEMANAGER;

ThesspriteManager = NULL;

10. In the Cappgame :: Render (), make the following modifications to display a frame of an animation.

/ / Clear the main surface

Pscreen-> Clear (RGB (127, 127, 127));

// Display bitmap

// theimagec-> BLT (Pscreen, 30, 30, 0, 0, WindowWidth (), WindowHeight (), cgdisurface :: blt_alphates;

// Show a frame of an animation

Canimation * Pani = thispriteManager-> GetAnimation (0);

Cframe * pf = pani-> getframe (0); PF-> Render (Pscreen, 100, 100, CGDisurface :: blt_alphates);

// Show text

TEXTRENDER-> Textout (Pscreen, 0, 0, FSTR ("FPS =% 2D", therenderfps-> getfps ()), RGB (255, 255, 255);

Everyone can see that the display is that a TANK is displayed on the screen.

10. The next task is to bring these animations to use it in order. According to the following figure, we can see that this group of pictures is very regular, this is an animation in the four directions of every TANK, I wrote a loop to create an animation in the cspritemanager.cpp create () function in the cspritemanager.cpp code () function Add initialization Code

// Create an animation data set

Bool cspritemanager :: create ()

{

CANIMATION * PANI;

Cframe F;

// All Tank images are 28x28

f.m_iw = 28;

F.m_ih = 28;

// Two groups of animations, the top is player tank, below is local TANK.

For (int K = 0; k <2; k )

{

// There are 8 TANK animations in each large group.

For (int L = 0; l <8; l )

{

// Each Tank has four directions in 4 directions

For (int J = 0; j <4; j )

{

PANI = New canimation ();

/ / 2 frames in each direction

For (int i = 0; i <2; i )

{

f.m_ix = l * 28 * 2 i * 28;

F.m_iy = k * 28 * 4 j * 28;

PANI-> Push (f);

}

m_vectoranimation.push_back (* PANI);

Delete Pani;

}

}

}

// The animation positioning formula is: Animation ID = Tank Model * 4 Direction

Return True;

}

11. Add and modify the code in CappGame :: Render (), run the program to see the Tank walking animation, randomly change a TANK every 2 seconds

// Display bitmap

// theimagec-> BLT (Pscreen, 30, 30, 0, 0, WindowWidth (), WindowHeight (), cgdisurface :: blt_alphates;

// Current frame

Static int icrframe = 0;

// Movie meter start time

Static dword dwanistarttime = timegettime ();

// Current animation ID

Static int icsurani = 0;

// The last time to change the movie

Static DWord dwanichangeLastTime = TimegetTime ();

IF (TimegetTime () - DwanichangeLastTime> 2000)

{

Icurani = rand ()% 64;

DwanichangeLastTime = TimegetTime ();

}

IF (TimegetTime () - DWANISTATTIME> 33)

{

ICURFRAME ;

If (icrframe> = 2)

Icurframe = 0;

DwanistartTime = TimegetTime ();

// Show a frame of an animation

CANIMATION * PANI = TheSpriteManager-> GetAnimation (iCurani);

Cframe * pf = PANI-> getframe (icrframe);

Pf-> Render (Pscreen, 100, 100, CGDisurface :: blt_alphates);

Chapter VI Scenario

转载请注明原文地址:https://www.9cbs.com/read-60715.html

New Post(0)