📄 g01.htm
字号:
<p> 警告:如果读者是Borland用户,在DirectX软件开发工具包中有一个单独的Borland库文件目录,因此要确保将这些.LIB文件而不目录树中上一级的MS兼容文件添加到工程中。</p> <p> 如果读者仍然对此有疑问的话,请不必着急。在本书中,当讨论Windows编程和首次接触DirectX时还要多次重复这些步骤。</p> <p><b>实例:FreakOut</b></p> <p> 在沉溺于所讨论的有关Windows、DirectX和3D图形之前,应当轶一下,先显示一个完整的游戏——虽然简单了一点,但毫无疑问是一个完整的游戏。读者可以看到一个起初的游戏循环和一些图形的调用以及一些编码工作。怎么样?跟我来吧!<br> 问题是我们现在仅仅在第一章。我并不喜欢使用后面章节中的内容......这听起来欺骗读者,对吧?因此,我决定要做是使用以前常常使用的黑匣子API来进行游戏编程。基于这个要求,我要提一个问题“创建一个类似Freakout的2D游戏,其最低要求是什么?”我们真正所需要的是下面的功能:<br> ·转换为任何图形模式<br> ·在屏幕上画各种颜色的矩形<br> ·采用键盘输入<br> ·使用定时函数同步游戏循环<br> ·在屏幕上画一串带颜色的文本<br> 因此我创建一个名字为BLACKBOX。CPP|H的目录。该程序带有一套DirectX函数集,并且包含实现所需要功能的支持代码。最妙的是,读者根本不需要去查看这些代码,只要在这些函数原型的基础上使用这些函数就可以了,并确保连接上BLACKBOX.CPP|H文件来产生一个.EXE文件。<br> 以BLACKBOX库为基础,我编写了一个名字为FreakOut的游戏,这个游戏演示了本章中所讨论的许多概念。FreakOut游戏含有实际游戏的全部主要组成部分,包括:一个游戏循环、计分、等级,甚至还带有一个球的小型物理模型。我所说的是小型的模型。图1.9是一幅游戏运行中的屏幕画面。当然它远远不及Arkanoid,但4个小时的工作有此成果也不赖!<br> 在编写游戏代码之前,我希望读者能看一下工程和其各种构件是如何协调一致的。参见图1.10</p> <p> 从图中可以看到,游戏主要由下面文件构成:<br> FREAKOUT.CPP——主要的游戏逻辑,使用BLACKBOX.CPP,创建一个最小的Win32应用程序。<br> BLACKBOX.CPP——游戏库(请不要偷看)<br> BLACKBOX.H——游戏库头文件。<br> DDRAW.LIB——用来建立应用程序的DriectDraw输入库。其中并不含有真正的DirectX代码。主要用来作为一个函数调用的中间库,可以轮流调用进行实际工作DDRAW.DLL动态链接库。它可以在DirectX SDK安装程序<LIB>目录下找到。<br> DDRAW.DLL——运行过程中的DirectDraw库,实际上含有通过DDRAW.LIB输入库调用DirectDraw界面函数的COM执行程序。对此读者不必担心:只要确认已经安装了DirectX文件即可。<br> 现在,我们对此已有了了解,让我们看一下BLACKOUT.H头文件,看看它包含了哪些函数。 </p> <p>程序清单1.2 BLOCKOUT.H头文件<br> -------------------------<br> // BLACKBOX.H - Header file for demo game engine library</p> <p>// watch for multiple inclusions<br> #ifndef BLACKBOX<br> #define BLACKBOX</p> <p>// DEFINES ////////////////////////////////////////////////////</p> <p>// default screen size<br> #define SCREEN_WIDTH 640 // size of screen<br> #define SCREEN_HEIGHT 480<br> #define SCREEN_BPP 8 // bits per pixel<br> #define MAX_COLORS 256 // maximum colors</p> <p>// MACROS /////////////////////////////////////////////////////</p> <p>// these read the keyboard asynchronously<br> #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)<br> #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)</p> <p>// initializes a direct draw struct<br> #define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }</p> <p>// TYPES //////////////////////////////////////////////////////</p> <p>// basic unsigned types<br> typedef unsigned short USHORT;<br> typedef unsigned short WORD;<br> typedef unsigned char UCHAR;<br> typedef unsigned char BYTE;</p> <p>// EXTERNALS //////////////////////////////////////////////////</p> <p>extern LPDIRECTDRAW4 lpdd; // dd object<br> extern LPDIRECTDRAWSURFACE4 lpddsprimary; // dd primary surface<br> extern LPDIRECTDRAWSURFACE4 lpddsback; // dd back surface<br> extern LPDIRECTDRAWPALETTE lpddpal; // a pointer to the created dd palette<br> extern LPDIRECTDRAWCLIPPER lpddclipper; // dd clipper<br> extern PALETTEENTRY palette[256]; // color palette<br> extern PALETTEENTRY save_palette[256]; // used to save palettes<br> extern DDSURFACEDESC2 ddsd; // a direct draw surface description struct<br> extern DDBLTFX ddbltfx; // used to fill<br> extern DDSCAPS2 ddscaps; // a direct draw surface capabilities struct<br> extern HRESULT ddrval; // result back from dd calls<br> extern DWORD start_clock_count; // used for timing</p> <p>// these defined the general clipping rectangle<br> extern int min_clip_x, // clipping rectangle <br> max_clip_x, <br> min_clip_y, <br> max_clip_y; </p> <p>// these are overwritten globally by DD_Init()<br> extern int screen_width, // width of screen<br> screen_height, // height of screen<br> screen_bpp; // bits per pixel </p> <p>// PROTOTYPES /////////////////////////////////////////////////</p> <p>// DirectDraw functions<br> int DD_Init(int width, int height, int bpp);<br> int DD_Shutdown(void);<br> LPDIRECTDRAWCLIPPER DD_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds, int num_rects, LPRECT clip_list);<br> int DD_Flip(void);<br> int DD_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);</p> <p>// general utility functions<br> DWORD Start_Clock(void);<br> DWORD Get_Clock(void);<br> DWORD Wait_Clock(DWORD count);</p> <p>// graphics functions<br> int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,LPDIRECTDRAWSURFACE4 lpdds=lpddsback);</p> <p>// gdi functions<br> int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE4 lpdds=lpddsback);<br> int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE4 lpdds=lpddsback);</p> <p>#endif</p> <p> -------------------------<br> 现在,就不要将你的精力都浪费在程序代码和那些神秘的全局变量是什么的问题上,让我们来看一看这些函数。如读者所看到一样,这个简单的图形界面需要一些函数来完成。在这个图形和小型的Win32应用程序(我们要做的Windows编程工作越少越好)的基础上,我创建了游戏FREAKOUT.CPP如实例1.1所示。请认真地看一看,特别是主游戏循环和对游戏处理功能的访问。</p> <p>程序清单1.3 FREAKOUT.CPP源文件<br> ----------------------------<br> // FREAKOUT.CPP - break game demo</p> <p>// INCLUDES ///////////////////////////////////////////////////</p> <p>#define WIN32_LEAN_AND_MEAN // include all macros<br> #define INITGUID // include all GUIDs </p> <p>#include <windows.h> // include important windows stuff<br> #include <windowsx.h> <br> #include <mmsystem.h></p> <p>#include <iostream.h> // include important C/C++ stuff<br> #include <conio.h><br> #include <stdlib.h><br> #include <malloc.h><br> #include <memory.h><br> #include <string.h><br> #include <stdarg.h><br> #include <stdio.h><br> #include <math.h><br> #include <io.h><br> #include <fcntl.h></p> <p>#include <ddraw.h> // directX includes<br> #include "blackbox.h" // game library includes</p> <p>// DEFINES ////////////////////////////////////////////////////</p> <p>// defines for windows <br> #define WINDOW_CLASS_NAME "WIN3DCLASS" // class name</p> <p>#define WINDOW_WIDTH 640 // size of window<br> #define WINDOW_HEIGHT 480</p> <p>// states for game loop<br> #define GAME_STATE_INIT 0<br> #define GAME_STATE_START_LEVEL 1<br> #define GAME_STATE_RUN 2<br> #define GAME_STATE_SHUTDOWN 3<br> #define GAME_STATE_EXIT 4 </p> <p>// block defines<br> #define NUM_BLOCK_ROWS 6<br> #define NUM_BLOCK_COLUMNS 8</p> <p>#define BLOCK_WIDTH 64<br> #define BLOCK_HEIGHT 16<br> #define BLOCK_ORIGIN_X 8<br> #define BLOCK_ORIGIN_Y 8<br> #define BLOCK_X_GAP 80<br> #define BLOCK_Y_GAP 32</p> <p>// paddle defines<br> #define PADDLE_START_X (SCREEN_WIDTH/2 - 16)<br> #define PADDLE_START_Y (SCREEN_HEIGHT - 32);<br> #define PADDLE_WIDTH 32<br> #define PADDLE_HEIGHT 8<br> #define PADDLE_COLOR 191</p> <p>// ball defines<br> #define BALL_START_Y (SCREEN_HEIGHT/2)<br> #define BALL_SIZE 4</p> <p>// PROTOTYPES /////////////////////////////////////////////////</p> <p>// game console<br> int Game_Init(void *parms=NULL);<br> int Game_Shutdown(void *parms=NULL);<br> int Game_Main(void *parms=NULL);</p> <p>// GLOBALS ////////////////////////////////////////////////////</p> <p>HWND main_window_handle = NULL; // save the window handle<br> HINSTANCE main_instance = NULL; // save the instance<br> int game_state = GAME_STATE_INIT; // starting state</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -