Введениев программированиетрехмерных игрВ этой части
Скачать 0.7 Mb.
|
НА ЗАМЕТКУ ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР код DirectX; это промежуточная библиотека, обеспечивающая обращение к динамической библиотеке DDRAW.DLL, которая выполняет реальную работу. Этот файл можно найти в DirectX SDK в каталоге Рис. 1.15. Копия экрана Raiders 3D Raiders3D.cpp T3DLib1.cpp T3DLib2.cpp T3DLib3.cpp (should all be in Файлы C++ T3DLib1.H T3DLib2.H T3DLib3.H (should all be in Заголовочные файлы+ Библиотечные файлы Файлы игры мультимедиа Эти файлы могут быть включены по умолчанию 3D.EXE Компилятор Рис. 1.16. Структура кода Raiders 3D • DINPUT.LIB/DINPUT8.LIB — DirectInput — компонент пользовательского ввода в составе. Для создания приложения требуются библиотеки импорта DIN- PUT.LIB и DINPUT8.LIB; • DSOUND.LIB — DirectSound — компонент цифрового звука в составе DirectX. Для создания приложения требуется библиотека импорта Отметим, что не существует файла DMUSIC.LIB, хотя DirectMusic используется в T3DLIB. Это так, поскольку DirectMusic — это чистый COM объект. Иными словами, нет библиотеки импорта, содержащей интерфейсные функции для обращения к Di rectMusic — вам нужно все делать самому. К счастью, я уже сделал этот для вас! НА ЗАМЕТКУ ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР Следующие файлы ненужны компилятору или компоновщику, но они являются выполняемыми файлами DirectX, которые загружаются при запуске игрового приложения — это динамически компонуемые библиотеки которые содержат COM реализацию функций интерфейса DirectInput, вызываемых через библиотеку импорта DINPUT.LIB. Здесь вам ненужно ни о чем беспокоиться, проследите лишь, чтобы были установлены исполняемые файлы DirectX; • DDRAW.DLL — это динамически компонуемая библиотека DirectDraw, которая содержит реализацию интерфейсных функций DirectDraw, вызываемых через библиотеку импорта DDRAW.LIB; • DSOUND.DLL — это динамически компонуемая библиотека DirectSound, которая содержит реализацию интерфейсных функций DirectSound, вызываемых через библиотеку импорта DSOUND.LIB; • DMUSIC.DLL — это динамически компонуемая библиотека DirectMusic, которая содержит реализацию интерфейсных функций DirectMusic, вызываемых непосредственно через COM обращения. Основываясь на нескольких вызовах библиотеки, я создал игру RAIDERS3D.CPP, показанную в нижеприведенном листинге. Игра запускается в оконном режиме с разрядной графикой, поэтому проследите, чтобы экран находился в 16 битовом цветовом режиме. Хорошо изучите представленный код главный цикл игры, трехмерную математику, а также вызовы других функций Raiders3D - RAIDERS3D.CPP - // ! // , // DDRAW.LIB, DSOUND.LIB, // DINPUT.LIB, WINMM.LIB, // T3DLIB1.CPP,T3DLIB2.CPP T3DLIB3.CPP !!! // T3DLIB1.H,T3DLIB2.H // T3DLIB3.H , // // , // 16- 640x480 // INCLUDES /////////////////////////////////////////////// #define INITGUID // COM- // .LIB- // DXGUID.LIB #define WIN32_LEAN_AND_MEAN #include Windows #include #include #include C/C++ #include #include ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР #include #include #include #include #include #include #include #include DirectX #include #include #include #include #include #include #include "T3DLIB1.h" // T3D #include "T3DLIB2.h" #include "T3DLIB3.h" // DEFINES //////////////////////////////////////////////// // windows #define WINDOW_CLASS_NAME "WIN3DCLASS" // #define WINDOW_TITLE "T3D Graphics Console Ver 2.0" #define WINDOW_WIDTH 640 // #define WINDOW_HEIGHT 480 #define WINDOW_BPP 16 // // (8,16,24 . .) // : // , // , // 8- #define WINDOWED_APP 1 // 0 - , 1 - //////////////////////////////////////////////////////////// #define NUM_STARS 250 // #define NUM_TIES 10 // // 3D- #define NEAR_Z 10 // #define FAR_Z 2000 // #define VIEW_DISTANCE 320 // // // 90 ° // // 640 // #define CROSS_VEL 8 // , // ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР PLAYER_Z_VEL 8 // z- // // #define NUM_TIE_VERTS 10 #define NUM_TIE_EDGES 8 // #define NUM_EXPLOSIONS (NUM_TIES) // // #define GAME_RUNNING 1 #define GAME_OVER 0 // /////////////////////////////////////////////////// // typedef struct POINT3D_TYP { USHORT color; // 16- float x,y,z; // } POINT3D, *POINT3D_PTR; // 3D- , typedef struct LINE3D_TYP { USHORT color; // 16- int v1,v2; // } LINE3D, *LINE3D_PTR; // typedef struct TIE_TYP { int state; // : // 0= , 1= float x, y, z; // float xv,yv,zv; // } TIE, *TIE_PTR; // 3D- , typedef struct VEC3D_TYP { float x,y,z; // } VEC3D, *VEC3D_PTR; // typedef struct EXPL_TYP { int state; // int counter; // USHORT color; // ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР // - / , // POINT3D p1[NUM_TIE_EDGES]; // n POINT3D p2[NUM_TIE_EDGES]; // n VEC3D vel[NUM_TIE_EDGES]; // } EXPL, *EXPL_PTR; // ///////////////////////////////////////////// // int Game_Init(void *parms=NULL); int Game_Shutdown(void *parms=NULL); int Game_Main(void *parms=NULL); // void Init_Tie(int index); // ///////////////////////////////// HWND main_window_handle = NULL; // HINSTANCE main_instance = NULL; // char buffer[256]; // // // - , // , POINT3D tie_vlist[NUM_TIE_VERTS]; // // LINE3D tie_shape[NUM_TIE_EDGES]; // TIE ties[NUM_TIES]; // POINT3D stars[NUM_STARS]; // // , // — 5.5.5 5.6.5, // Game_Init() USHORT rgb_green, rgb_white, rgb_red, rgb_blue; // float cross_x = 0, // cross_y = 0; int cross_x_screen = WINDOW_WIDTH/2, // cross_y_screen = WINDOW_HEIGHT/2, target_x_screen = WINDOW_WIDTH/2, target_y_screen = WINDOW_HEIGHT/2; int player_z_vel = 4; // ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР // / int cannon_state = 0; // int cannon_count = 0; // EXPL explosions[NUM_EXPLOSIONS]; // int misses = 0; // , // int hits = 0; // int score = 0; // // int main_track_id = -1, // laser_id = -1, // explosion_id = -1, // flyby_id = -1; // int game_state = GAME_RUNNING; // // ////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // PAINTSTRUCT ps; // WM_PAINT HDC hdc; // // ? switch(msg) { case WM_CREATE: { // return(0); } break; case WM_PAINT: { // hdc = BeginPaint(hwnd,&ps); // EndPaint(hwnd,&ps); return(0); } break; case WM_DESTROY: { // ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР PostQuitMessage(0); return(0); } break; default:break; } // switch // return (DefWindowProc(hwnd, msg, wparam, lparam)); } // WinProc // WINMAIN //////////////////////////////////////////////// int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { WNDCLASS winclass; // HWND hwnd; // MSG msg; // HDC hdc; // PAINTSTRUCT ps; // // winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = WINDOW_CLASS_NAME; // if (!RegisterClass(&winclass)) return(0); // // if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME,// WINDOW_TITLE, // (WINDOWED_APP ? (WS_OVERLAPPED | WS_SYSMENU) : (WS_POPUP | WS_VISIBLE)), 0,0, // x,y ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР WINDOW_WIDTH, // WINDOW_HEIGHT, // NULL, // NULL, // hinstance, // NULL))) // return(0); // // main_window_handle = hwnd; main_instance = hinstance; // , // width x height if (WINDOWED_APP) { // , // , , // , , // // , // RECT window_rect = {0,0,WINDOW_WIDTH,WINDOW_HEIGHT}; // window_rect AdjustWindowRectEx(&window_rect, GetWindowStyle(main_window_handle), GetMenu(main_window_handle) != NULL, GetWindowExStyle(main_window_handle)); // , // DDraw_Flip() window_client_x0 = -window_rect.left; window_client_y0 = -window_rect.top; // MoveWindow() MoveWindow(main_window_handle, CW_USEDEFAULT, // x CW_USEDEFAULT, // y // window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, FALSE); // ShowWindow(main_window_handle, SW_SHOW); } // if windowed // Game_Init(); // CTRL-ALT-DEL, ALT-TAB. ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР // , SystemParametersInfo(SPI_SCREENSAVERRUNNING,TRUE,NULL,0); // while(1) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { // , if (msg.message == WM_QUIT) break; // TranslateMessage(&msg); // DispatchMessage(&msg); } // if // Game_Main(); } // while // Game_Shutdown(); // CTRL-ALT-DEL, ALT-TAB, // , SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE,NULL,0); // Windows return(msg.wParam); } // WinMain // T3D II //////////////////////////// int Game_Init(void *parms) { // int index; Open_Error_File("error.txt"); // DirectDraw ( ) DDraw_Init(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP); // DirectInput DInput_Init(); ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР // DInput_Init_Keyboard(); // DirectSound DSound_Init(); // explosion_id = DSound_Load_WAV("exp1.wav"); laser_id = DSound_Load_WAV("shocker.wav"); // DirectMusic DMusic_Init(); // main_track_id = DMusic_Load_MIDI("midifile2.mid"); DMusic_Play(main_track_id); // // DirectInput // ShowCursor(FALSE); // srand(Start_Clock()); // rgb_green = RGB16Bit(0,31,0); rgb_white = RGB16Bit(31,31,31); rgb_blue = RGB16Bit(0,0,31); rgb_red = RGB16Bit(31,0,0); // for (index=0; index < NUM_STARS; index++) { // , // (0,0,-d) // (0,0,far_z) stars[index].x = -WINDOW_WIDTH/2 + rand()%WINDOW_WIDTH; stars[index].y = -WINDOW_HEIGHT/2 + rand()%WINDOW_HEIGHT; stars[index].z = NEAR_Z + rand()%(FAR_Z - NEAR_Z); // stars[index].color = rgb_white; } // for index // // POINT3D temp_tie_vlist[NUM_TIE_VERTS] = ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР // , x,y,z { {rgb_white,-40, 40,0}, // p0 {rgb_white,-40, 0,0}, // p1 {rgb_white,-40,-40,0}, // p2 {rgb_white,-10, 0,0}, // p3 {rgb_white, 0, 20,0}, // p4 {rgb_white, 10, 0,0}, // p5 {rgb_white, 0,-20,0}, // p6 {rgb_white, 40, 40,0}, // p7 {rgb_white, 40, 0,0}, // p8 {rgb_white, 40,-40,0}}; // p9 // for (index=0; index // LINE3D temp_tie_shape[NUM_TIE_EDGES] = // , 1, 2 { {rgb_green,0,2 }, // l0 {rgb_green,1,3 }, // l1 {rgb_green,3,4 }, // l2 {rgb_green,4,5 }, // l3 {rgb_green,5,6 }, // l4 {rgb_green,6,3 }, // l5 {rgb_green,5,8 }, // l6 {rgb_green,7,9 } };// l7 // for (index=0; index // // for (index=0; index // Init_Tie(index); } // for index // return(1); } // Game_Init /////////////////////////////////////////////////////////// int Game_Shutdown(void *parms) { // // ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР // // , // DirectSound DSound_Stop_All_Sounds(); DSound_Shutdown(); // DirectMusic DMusic_Delete_All_MIDI(); DMusic_Shutdown(); // DirectInput DInput_Shutdown(); // DirectDraw DDraw_Shutdown(); // return(1); } // Game_Shutdown ////////////////////////////////////////////////////////// void Start_Explosion(int tie) { // , // for (int index=0; index < NUM_EXPLOSIONS; index++) { if (explosions[index].state==0) { // explosions[index].state = 1; // explosions[index].counter = 0;// // explosions[index].color = rgb_green; // for (int edge=0; edge < NUM_TIE_EDGES; edge++) { // explosions[index].p1[edge].x = ties[tie].x + tie_vlist[tie_shape[edge].v1].x; explosions[index].p1[edge].y = ties[tie].y + tie_vlist[tie_shape[edge].v1].y; explosions[index].p1[edge].z = ties[tie].z + tie_vlist[tie_shape[edge].v1].z; ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР // explosions[index].p2[edge].x = ties[tie].x + tie_vlist[tie_shape[edge].v2].x; explosions[index].p2[edge].y = ties[tie].y + tie_vlist[tie_shape[edge].v2].y; explosions[index].p2[edge].z = ties[tie].z + tie_vlist[tie_shape[edge].v2].z; // explosions[index].vel[edge].x = ties[tie].xv- 8+rand()%16; explosions[index].vel[edge].y = ties[tie].yv- 8+rand()%16; explosions[index].vel[edge].z = -3+rand()%4; } // for edge return; } // if } // for index } // Start_Explosion /////////////////////////////////////////////////////////// void Process_Explosions(void) { // // for (int index=0; index // , if (explosions[index].state==0) continue; for (int edge=0; edge // , explosions[index].p1[edge].x+= explosions[index].vel[edge].x; explosions[index].p1[edge].y+= explosions[index].vel[edge].y; explosions[index].p1[edge].z+= explosions[index].vel[edge].z; explosions[index].p2[edge].x+= explosions[index].vel[edge].x; explosions[index].p2[edge].y+= explosions[index].vel[edge].y; explosions[index].p2[edge].z+= explosions[index].vel[edge].z; ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР } // for edge // if (++explosions[index].counter > 100) explosions[index].state = explosions[index].counter = 0; } // for index } // Process_Explosions /////////////////////////////////////////////////////////// void Draw_Explosions(void) { // // for (int index=0; index // , if (explosions[index].state==0) continue; // // for (int edge=0; edge < NUM_TIE_EDGES; edge++) { POINT3D p1_per, p2_per; // if (explosions[index].p1[edge].z < NEAR_Z && explosions[index].p2[edge].z < NEAR_Z) continue; // 1: // p1_per.x = VIEW_DISTANCE* explosions[index].p1[edge].x/ explosions[index].p1[edge].z; p1_per.y = VIEW_DISTANCE* explosions[index].p1[edge].y/ explosions[index].p1[edge].z; p2_per.x = VIEW_DISTANCE* explosions[index].p2[edge].x/ explosions[index].p2[edge].z; p2_per.y = VIEW_DISTANCE* explosions[index].p2[edge].y/ explosions[index].p2[edge].z; // 2: int p1_screen_x = WINDOW_WIDTH/2 + p1_per.x; int p1_screen_y = WINDOW_HEIGHT/2 - p1_per.y; ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР int p2_screen_x = WINDOW_WIDTH/2 + p2_per.x; int p2_screen_y = WINDOW_HEIGHT/2 - p2_per.y; // 3: Draw_Clip_Line16(p1_screen_x, p1_screen_y, p2_screen_x, p2_screen_y, explosions[index].color, back_buffer, back_lpitch); } // for edge } // for index } // Draw_Explosions ////////////////////////////////////////////////////////// void Move_Starfield(void) { // int index; // , // , for (index=0; index // stars[index].z-=player_z_vel; // if (stars[index].z <= NEAR_Z) stars[index].z = FAR_Z; } // for index } // Move_Starfield ///////////////////////////////////////////////////////// void Draw_Starfield(void) { // // int index; for (index=0; index // // 1: float x_per = VIEW_DISTANCE*stars[index].x/ stars[index].z; ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР float y_per = VIEW_DISTANCE*stars[index].y/ stars[index].z; // 2: int x_screen = WINDOW_WIDTH/2 + x_per; int y_screen = WINDOW_HEIGHT/2 - y_per; // if (x_screen>=WINDOW_WIDTH || x_screen < 0 || y_screen >= WINDOW_HEIGHT || y_screen < 0) { // continue; } // if else { // ((USHORT *)back_buffer) [x_screen + y_screen*(back_lpitch >> 1)] = stars[index].color; } // else } // for index } // Draw_Starfield ///////////////////////////////////////////////////////// void Init_Tie(int index) { // // ! // ties[index].x = -WINDOW_WIDTH + rand()%(2*WINDOW_WIDTH); ties[index].y = -WINDOW_HEIGHT+rand()%(2*WINDOW_HEIGHT); ties[index].z = 4*FAR_Z; // ties[index].xv = -4+rand()%8; ties[index].yv = -4+rand()%8; ties[index].zv = -4-rand()%64; // ties[index].state = 1; } // Init_Tie ///////////////////////////////////////////////////////// void Process_Ties(void) { // // ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР int index; // // for (index=0; index // , ? if (ties[index].state==0) continue; // ties[index].z+=ties[index].zv; ties[index].x+=ties[index].xv; ties[index].y+=ties[index].yv; // if (ties[index].z <= NEAR_Z) { // Init_Tie(index); misses++; } } // for index } // Process_Ties ////////////////////////////////////////////////////////// void Draw_Ties(void) { // int index; // // int bmin_x, bmin_y, bmax_x, bmax_y; // for (index=0; index < NUM_TIES; index++) { // // ? if (ties[index].state==0) continue; // // bmin_x = 100000; bmax_x = -100000; ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР bmin_y = 100000; bmax_y = -100000; // z, // , 0 max_z, // ( , ) USHORT rgb_tie_color = RGB16Bit(0,(31-31*(ties[index].z/(4*FAR_Z))),0); // for (int edge=0; edge < NUM_TIE_EDGES; edge++) { POINT3D p1_per, p2_per; // 1: // , // // , , // p1_per.x = VIEW_DISTANCE*(ties[index].x+ tie_vlist[tie_shape[edge].v1].x)/ (tie_vlist[tie_shape[edge].v1].z+ ties[index].z); p1_per.y = VIEW_DISTANCE*(ties[index].y+ tie_vlist[tie_shape[edge].v1].y)/ (tie_vlist[tie_shape[edge].v1].z+ ties[index].z); p2_per.x = VIEW_DISTANCE*(ties[index].x+ tie_vlist[tie_shape[edge].v2].x)/ (tie_vlist[tie_shape[edge].v2].z+ ties[index].z); p2_per.y = VIEW_DISTANCE*(ties[index].y+ tie_vlist[tie_shape[edge].v2].y)/ (tie_vlist[tie_shape[edge].v2].z+ ties[index].z); // 2: int p1_screen_x = WINDOW_WIDTH/2 + p1_per.x; int p1_screen_y = WINDOW_HEIGHT/2 - p1_per.y; int p2_screen_x = WINDOW_WIDTH/2 + p2_per.x; int p2_screen_y = WINDOW_HEIGHT/2 - p2_per.y; // 3: Draw_Clip_Line16(p1_screen_x, p1_screen_y, p2_screen_x, p2_screen_y, rgb_tie_color,back_buffer, back_lpitch); // // ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР int min_x = min(p1_screen_x, p2_screen_x); int max_x = max(p1_screen_x, p2_screen_x); int min_y = min(p1_screen_y, p2_screen_y); int max_y = max(p1_screen_y, p2_screen_y); bmin_x = min(bmin_x, min_x); bmin_y = min(bmin_y, min_y); bmax_x = max(bmax_x, max_x); bmax_y = max(bmax_y, max_y); } // for edge // , if (cannon_state==1) { // // , // if (target_x_screen > bmin_x && target_x_screen < bmax_x && target_y_screen > bmin_y && target_y_screen < bmax_y) { // ! Start_Explosion(index); // DSound_Play(explosion_id ); // score+=ties[index].z; // hits++; // // Init_Tie(index); } // if } // if } // for index } // Draw_Ties ////////////////////////////////////////////////////////// int Game_Main(void *parms) { ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР // , // main() // C int index; // Start_Clock(); // DDraw_Fill_Surface(lpddsback, 0); // DInput_Read_Keyboard(); // if (game_state==GAME_RUNNING) { // if (keyboard_state[DIK_RIGHT]) { // cross_x+=CROSS_VEL; if (cross_x > WINDOW_WIDTH/2) cross_x = -WINDOW_WIDTH/2; } // if if (keyboard_state[DIK_LEFT]) { // cross_x-=CROSS_VEL; if (cross_x < -WINDOW_WIDTH/2) cross_x = WINDOW_WIDTH/2; } // if if (keyboard_state[DIK_DOWN]) { // cross_y-=CROSS_VEL; if (cross_y < -WINDOW_HEIGHT/2) cross_y = WINDOW_HEIGHT/2; } // if if (keyboard_state[DIK_UP]) { // cross_y+=CROSS_VEL; if (cross_y > WINDOW_HEIGHT/2) ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР cross_y = -WINDOW_HEIGHT/2; } // if // if (keyboard_state[DIK_A]) player_z_vel++; else if (keyboard_state[DIK_S]) player_z_vel--; // , if (keyboard_state[DIK_SPACE] && cannon_state==0) { // cannon_state = 1; cannon_count = 0; // target_x_screen = cross_x_screen; target_y_screen = cross_y_screen; // DSound_Play(laser_id); } // if } // - : // - - // if (cannon_state == 1) if (++cannon_count > 15) cannon_state = 2; // if (cannon_state == 2) if (++cannon_count > 20) cannon_state = 0; // Move_Starfield(); // // Process_Ties(); // Process_Explosions(); // DDraw_Lock_Back_Surface(); ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР // Draw_Starfield(); // Draw_Ties(); // Draw_Explosions(); // // // y cross_x_screen = WINDOW_WIDTH/2 + cross_x; cross_y_screen = WINDOW_HEIGHT/2 - cross_y; // Draw_Clip_Line16(cross_x_screen-16,cross_y_screen, cross_x_screen+16,cross_y_screen, rgb_red,back_buffer,back_lpitch); Draw_Clip_Line16(cross_x_screen,cross_y_screen-16, cross_x_screen,cross_y_screen+16, rgb_red,back_buffer,back_lpitch); Draw_Clip_Line16(cross_x_screen-16,cross_y_screen-4, cross_x_screen-16,cross_y_screen+4, rgb_red,back_buffer,back_lpitch); Draw_Clip_Line16(cross_x_screen+16,cross_y_screen-4, cross_x_screen+16,cross_y_screen+4, rgb_red,back_buffer,back_lpitch); // if (cannon_state == 1) { if ((rand()%2 == 1)) { // Draw_Clip_Line16(WINDOW_WIDTH-1,WINDOW_HEIGHT-1, -4+rand()%8+target_x_screen, -4+rand()%8+target_y_screen, RGB16Bit(0,0,rand()), back_buffer,back_lpitch); } // if else { // Draw_Clip_Line16(0, WINDOW_HEIGHT-1, -4+rand()%8+target_x_screen, -4+rand()%8+target_y_screen, RGB16Bit(0,0,rand()), back_buffer,back_lpitch); ЧАСТЬ I. ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ ТРЕХМЕРНЫХ ИГР } // if } // if // , // DDraw_Unlock_Back_Surface(); // sprintf(buffer, "Score %d Kills %d Escaped %d", score, hits, misses); Draw_Text_GDI(buffer, 0,0,RGB(0,255,0), lpddsback); if (game_state==GAME_OVER) Draw_Text_GDI("G A M E O V E R", 320-8*10,240, RGB(255,255,255), lpddsback); // , , // - if (DMusic_Status_MIDI(main_track_id)==MIDI_STOPPED) DMusic_Play(main_track_id); // DDraw_Flip(); // 30 Wait_Clock(30); // if (misses > 100) game_state = GAME_OVER; // , if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // if // return(1); } // Очень немного для трехмерной игры, правда Это реальная трехмерная игра Win32/DirectX. Прежде чем мы займемся анализом кода, я хочу, чтобы вы сами скомпилировали его. Я запрещаю вам двигаться дальше, пока компиляция не завершится успехом Надеюсь, я понятно выразился. Итак, займитесь настройкой компилятора в соответствии сопи санными выше инструкциями для создания Win32 .EXE приложений, указывая пути поиска и создавая списки связывания, настроенные для DirectX. Затем, когда проект будет готов, подключите исходные файлы T3DLIB1.CPP, T3DLIB2.CPP, T3DLIB3.CPP, RAIDERS3D.CPP. ГЛАВА 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ ТРЕХМЕРНЫХ ИГР |