⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raiders3d_2b.cpp

📁 3D游戏编程大师技巧第九章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						  (WINDOWED_APP ? (WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION) : (WS_POPUP | WS_VISIBLE)),
					 	  0,0,	   // x,y
						  WINDOW_WIDTH,  // width
                          WINDOW_HEIGHT, // height
						  NULL,	   // handle to parent 
						  NULL,	   // handle to menu
						  hinstance,// instance
						  NULL)))	// creation parms
return(0);

// save the window handle and instance in a global
main_window_handle = hwnd;
main_instance      = hinstance;

// resize the window so that client is really width x height
if (WINDOWED_APP)
{
// now resize the window, so the client area is the actual size requested
// since there may be borders and controls if this is going to be a windowed app
// if the app is not windowed then it won't matter
RECT window_rect = {0,0,WINDOW_WIDTH-1,WINDOW_HEIGHT-1};

// make the call to adjust window_rect
AdjustWindowRectEx(&window_rect,
     GetWindowStyle(main_window_handle),
     GetMenu(main_window_handle) != NULL,  
     GetWindowExStyle(main_window_handle));

// save the global client offsets, they are needed in DDraw_Flip()
window_client_x0 = -window_rect.left;
window_client_y0 = -window_rect.top;

// now resize the window with a call to MoveWindow()
MoveWindow(main_window_handle,
           0, // x position
           0, // y position
           window_rect.right - window_rect.left, // width
           window_rect.bottom - window_rect.top, // height
           FALSE);

// show the window, so there's no garbage on first render
ShowWindow(main_window_handle, SW_SHOW);
} // end if windowed

// perform all game console specific initialization
Game_Init();

// disable CTRL-ALT_DEL, ALT_TAB, comment this line out 
// if it causes your system to crash
SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, NULL, 0);

// enter main event loop
while(1)
	{
	if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{ 
		// test if this is a quit
        if (msg.message == WM_QUIT)
           break;
	
		// translate any accelerator keys
		TranslateMessage(&msg);

		// send the message to the window proc
		DispatchMessage(&msg);
		} // end if
    
    // main game processing goes here
    Game_Main();

	} // end while

// shutdown game and release all resources
Game_Shutdown();

// enable CTRL-ALT_DEL, ALT_TAB, comment this line out 
// if it causes your system to crash
SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, NULL, 0);

// return to Windows like this
return(msg.wParam);

} // end WinMain

////////////////////////////////////////////////////////////////////

void Render_Energy_Bindings(POINT2D_PTR bindings, // array containing binding positions in the form
                                                  // start point, end point, start point, end point...
                            int num_bindings,     // number of energy bindings to render 1-3
                            int num_segments,     // number of segments to randomize bindings into
                            int amplitude,        // amplitude of energy binding
                            int color,            // color of bindings
                            UCHAR *video_buffer,  // video buffer to render
                            int lpitch)           // memory pitch of buffer
{
// this functions renders the energy bindings across the main exterior energy
// transmission emitters :) Basically, the function takes two points in 2d then
// it anchors a line at the two ends and randomly walks from end point to the
// other by breaking the line into segments and then randomly modulating the y position
// and amount amplitude +-, maximum number of segments 16
POINT2D segments[17]; // to hold constructed segments after construction

// render each binding
for (int index = 0; index < num_bindings; index++)
    {
    // store starting and ending positions
    
    // starting position
    segments[0] = bindings[index*2];
    
    // ending position
    segments[num_segments] = bindings[index*2+1];

    // compute vertical gradient, so if y positions of endpoints are
    // greatly different bindings will be modulated using the straight line
    // as a basis
    float dyds = (segments[num_segments].y - segments[0].y) / (float)num_segments;
    float dxds = (segments[num_segments].x - segments[0].x) / (float)num_segments;

    // now build up segments
    for (int sindex = 1; sindex < num_segments; sindex++)
        {
        segments[sindex].x = segments[sindex-1].x + dxds;
        segments[sindex].y = segments[0].y + sindex*dyds + RAND_RANGE(-amplitude, amplitude);
        } // end for segment            

    // draw binding
    for (sindex = 0; sindex < num_segments; sindex++)
        Draw_Line16(segments[sindex].x, segments[sindex].y, 
                    segments[sindex+1].x, segments[sindex+1].y,
                    color, video_buffer, lpitch); 

    } // end for index

} // end Render_Energy_Binding

////////////////////////////////////////////////////////////////////

void Render_Weapon_Bursts(POINT2D_PTR burstpoints, // array containing energy burst positions in the form
                                                   // start point, end point, start point, end point...
                            int num_bursts,
                            int num_segments,     // number of segments to randomize bindings into
                            int amplitude,        // amplitude of energy binding
                            int color,            // color of bindings
                            UCHAR *video_buffer,  // video buffer to render
                            int lpitch)           // memory pitch of buffer
{
// this functions renders the weapon energy bursts from the weapon emitter or wherever
// function derived from Render_Energy_Binding, but generalized 
// Basically, the function takes two points in 2d then
// it anchors a line at the two ends and randomly walks from end point to the
// other by breaking the line into segments and then randomly modulating the x,y position
// and amount amplitude +-, maximum number of segments 16

POINT2D segments[17]; // to hold constructed segments after construction

// render each energy burst
for (int index = 0; index < num_bursts; index++)
    {
    // store starting and ending positions
    
    // starting position
    segments[0] = burstpoints[index*2];
    
    // ending position
    segments[num_segments] = burstpoints[index*2+1];

    // compute horizontal/vertical gradients, so we can modulate the lines 
    // on the proper trajectory
    float dyds = (segments[num_segments].y - segments[0].y) / (float)num_segments;
    float dxds = (segments[num_segments].x - segments[0].x) / (float)num_segments;

    // now build up segments
    for (int sindex = 1; sindex < num_segments; sindex++)
        {
        segments[sindex].x = segments[0].x + sindex*dxds + RAND_RANGE(-amplitude, amplitude);
        segments[sindex].y = segments[0].y + sindex*dyds + RAND_RANGE(-amplitude, amplitude);
        } // end for segment            

    // draw binding
    for (sindex = 0; sindex < num_segments; sindex++)
        Draw_Line16(segments[sindex].x, segments[sindex].y, 
                    segments[sindex+1].x, segments[sindex+1].y,
                    color, video_buffer, lpitch); 

    } // end for index

} // end Render_Weapons_Bursts

///////////////////////////////////////////////////////////////

int Load_Bitmap_Font(char *fontfile, BOB_PTR font)
{
// this is a semi generic font loader...
// expects the file name of a font in a template that is 
// 4 rows of 16 cells, each character is 16x14, and cell 0 is the space character
// characters from 32 to 95, " " to "-", suffice for 90% of text work

// load the font bitmap template
if (!Load_Bitmap_File(&bitmap16bit, fontfile))
   return(0);

// create the bob that will hold the font, use a bob for speed, we can use the 
// hardware blitter
Create_BOB(font, 0,0,16,14,64, BOB_ATTR_VISIBLE | BOB_ATTR_SINGLE_FRAME, DDSCAPS_SYSTEMMEMORY, 0, 16); 

// load all the frames
for (int index=0; index < 64; index++)
     Load_Frame_BOB16(font, &bitmap16bit,index,index%16,index/16,BITMAP_EXTRACT_MODE_CELL);

// unload the bitmap file
Unload_Bitmap_File(&bitmap16bit);

// return success
return(1);

} // end Load_Bitmap_Font

///////////////////////////////////////////////////////////////

int Draw_Bitmap_Font_String(BOB_PTR font,  // pointer to bob containing font
                            int x, int y,  // screen position to render
                            char *string,  // string to render
                            int hpitch, int vpitch, // horizontal and vertical pitch
                            LPDIRECTDRAWSURFACE7 dest) // destination surface
{
// this function draws a string based on a 64 character font sent in as a bob
// the string will be drawn at the given x,y position with intercharacter spacing
// if hpitch and a interline spacing of vpitch

// are things semi valid?
if (!string || !dest)
   return(0);

// loop and render
for (int index = 0; index < strlen(string); index++)
    {
    // set the position and character
    font->x = x;
    font->y = y;
    font->curr_frame = string[index] - 32;
    // test for overflow set to space
    if (font->curr_frame > 63 || font->curr_frame < 0) font->curr_frame = 0;

    // render character (i hate making a function call!)
    Draw_BOB16(font, dest);

    // move position
    x+=hpitch;

    } // end for index

// return success
return(1);

} // end Draw_Bitmap_Font_String

/////////////////////////////////////////////////////////

int Start_Alien(void)
{
// this function hunts in the alien list, finds an available alien and 
// starts it up

for (int index = 0; index < NUM_ALIENS; index++)
    {
    // is this alien available?
    if (aliens[index].state == ALIEN_STATE_DEAD)
       {
       // clear any residual data
       memset((void *)&aliens[index], 0, sizeof (ALIEN) );

       // start alien up
       aliens[index].state = ALIEN_STATE_ALIVE;
       
       // select random position in bounding volume
       aliens[index].pos.x = RAND_RANGE(-1000,1000);
       aliens[index].pos.y = RAND_RANGE(-1000,1000);
       aliens[index].pos.z = 20000;
       
       // select velocity based on difficulty level
       aliens[index].vel.x = RAND_RANGE(-10,10);
       aliens[index].vel.y = RAND_RANGE(-10,10);
       aliens[index].vel.z = -(10*diff_level+rand()%200);

       // set rotation rate for z axis only
       aliens[index].rot.z = RAND_RANGE(-5,5);
 
       // return the index
       return(index);
       } // end if   

    } // end for index

// failure
return(-1);

} // end Start_Alien


/////////////////////////////////////////////////////////

void Init_Aliens(void)
{
// initializes all the ALIEN fighters to a known state
for (int index = 0; index < NUM_ALIENS; index++)
    {
    // zero ALIEN fighter out
    memset((void *)&aliens[index], 0, sizeof (ALIEN) );

    // set any other specific info now...
    aliens[index].state = ALIEN_STATE_DEAD;

    } // end for

} // end Init_Aliens

/////////////////////////////////////////////////////////

void Draw_Aliens(void)
{
// this function draws all the active ALIEN fighters

MATRIX4X4 mrot; // used to transform objects

for (int index = 0; index < NUM_ALIENS; index++)
    {
    // which state is alien in
    switch(aliens[index].state)
          {
          // is the alien dead? if so move on
          case ALIEN_STATE_DEAD: break;

          // is the alien alive?
          case ALIEN_STATE_ALIVE:
          case ALIEN_STATE_DYING:
          {
          // reset the object (this only matters for backface and object removal)
          Reset_OBJECT4DV2(&obj_alien);

          // generate rotation matrix around y axis
          Build_XYZ_Rotation_MATRIX4X4(aliens[index].ang.x, aliens[index].ang.y, aliens[index].ang.z ,&mrot);
         
          // rotate the local coords of the object
          Transform_OBJECT4DV2(&obj_alien, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

          // set position of constant shaded cube
          obj_alien.world_pos.x = aliens[index].pos.x;
          obj_alien.world_pos.y = aliens[index].pos.y;
          obj_alien.world_pos.z = aliens[index].pos.z;

          // attempt to cull object
          if (!Cull_OBJECT4DV2(&obj_alien, &cam, CULL_OBJECT_XYZ_PLANES))
             {
             // perform world transform
             Model_To_World_OBJECT4DV2(&obj_alien, TRANSFORM_TRANS_ONLY);

             // insert the object into render list
             Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_alien,0);
             } // end if 


          // ok, now test for collision with energy bursts, strategy is as follows
          // we will project the bounding box of the object into screen space to coincide with
          // the energy burst on the screen, if there is an overlap then the target is hit
          // simply need to do a few transforms, this kinda sucks that we are going to do this work
          // 2x, but the problem is that the graphics pipeline knows nothing about collision etc.,
          // so we can't "get to" the information me want since we are ripping the objects apart
          // and passing them down the pipeline for a later world to camera transform, thus you
          // may want to think about this problem when making your own game, how tight to couple
          // collision and the engine, HOWEVER, the only reason we are having a problem at all is that

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -