DirectX带控制的角色动画(32位显示模式)二

 

  
  
  
  
  1.  
  2.  
  3. ///////////////////////////////////////////////////////////////  
  4.  
  5. ///////////////////////////////////////////////////////////////  
  6.  
  7. LRESULT CALLBACK WindowProc(HWND hwnd,   
  8.         UINT msg,   
  9.         WPARAM wparam,   
  10.         LPARAM lparam)  
  11. {  
  12.         // this is the main message handler of the system  
  13.         PAINTSTRUCT                ps;                // used in WM_PAINT  
  14.         HDC                                hdc;        // handle to a device context  
  15.         char buffer[80];        // used to print strings  
  16.  
  17.         // what is the message   
  18.         switch(msg)  
  19.         {          
  20.         case WM_CREATE:   
  21.                 {  
  22.                         // do initialization stuff here  
  23.                         // return success  
  24.                         return(0);  
  25.                 } break;  
  26.  
  27.         case WM_PAINT:   
  28.                 {  
  29.                         // simply validate the window   
  30.                         hdc = BeginPaint(hwnd,&ps);           
  31.  
  32.                         // end painting  
  33.                         EndPaint(hwnd,&ps);  
  34.  
  35.                         // return success  
  36.                         return(0);  
  37.                 } break;  
  38.  
  39.         case WM_DESTROY:   
  40.                 {  
  41.  
  42.                         // kill the application, this sends a WM_QUIT message   
  43.                         PostQuitMessage(0);  
  44.  
  45.                         // return success  
  46.                         return(0);  
  47.                 } break;  
  48.  
  49.         default:break;  
  50.  
  51.         } // end switch  
  52.  
  53.         // process any messages that we didn't take care of   
  54.         return (DefWindowProc(hwnd, msg, wparam, lparam));  
  55.  
  56. // end WinProc  
  57.  
  58. ///////////////////////////////////////////////////////////  
  59.  
  60. int Game_Main(void *parms = NULL, int num_parms = 0)  
  61. {  
  62.         // 这是游戏的主循环,作你的处理  
  63.  
  64.         //查找正确的行走顺序  
  65.         static int anmation_seq[4]={0,1,0,2};  
  66.         int index;//循环变量   
  67.  
  68.         // 确保这不是再次执行  
  69.         if (window_closed)  
  70.                 return(0);  
  71.  
  72.  
  73.         if (KEYDOWN(VK_ESCAPE))  
  74.         {  
  75.                 PostMessage(main_window_handle,WM_CLOSE,0,0);  
  76.                 window_closed = 1;  
  77.         }   
  78.  
  79.         //复制背景到后备缓冲区  
  80.         DDraw_Draw_Surface(lpddsbackground,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,lpddsback,0);  
  81.  
  82.         //移动物体  
  83.  
  84.         for (index=0;index<2;index++)  
  85.         {  
  86.                 //使对象向右移动  
  87.                 aliens[index].x++;  
  88.                 //测试是否进入屏幕的边缘,设置循环  
  89.                 if(aliens[index].x>SCREEN_WIDTH)  
  90.                         aliens[index].x=-80;  
  91.                 //机器人动画  
  92.                 if (++aliens[index].counter >=(8-aliens[index].velocity))  
  93.                 {  
  94.                         //复位计数器  
  95.                         aliens[index].counter=0;//动画时间为0  
  96.                         //前进到下一帧  
  97.                         if (++aliens[index].current_frame>2)//当前帧大于3  
  98.                         {  
  99.                                 aliens[index].current_frame=0;  
  100.                         }  
  101.                 }  
  102.  
  103.                 //角色控制  
  104.                 if (KEYDOWN(VK_RIGHT))  
  105.                 {  
  106.                         aliens[2].x++;  
  107.                         //测试是否进入屏幕的边缘,设置循环  
  108.                         if(aliens[2].x>SCREEN_WIDTH)  
  109.                                 aliens[2].x=-80;  
  110.                         if (++aliens[2].counter >=(8-aliens[2].velocity))  
  111.                         {  
  112.                                 //复位计数器  
  113.                                 aliens[2].counter=0;//动画时间为0  
  114.                                 //前进到下一帧  
  115.                                 if (++aliens[2].current_frame>2)//当前帧大于3  
  116.                                 {  
  117.                                         aliens[2].current_frame=0;  
  118.                                 }  
  119.                         }  
  120.                 }  
  121.         }//结束index循环  
  122.  
  123.                 //绘制全部机器人  
  124.                 for (index =0;index<3;index++)  
  125.                 {  
  126.                         //绘制对象  
  127.                         DDraw_Draw_Surface(aliens[index].frames[anmation_seq[aliens[index].current_frame]],  
  128.                                                aliens[index].x,aliens[index].y,  
  129.                                                            72,80,  
  130.                                                            lpddsback);  
  131.                 }  
  132.         while(FAILED(lpddsprimary->Flip(NULL,DDFLIP_WAIT)));  
  133.  
  134.         Sleep(30);  
  135.           
  136.         return(1);  
  137.  
  138. // end Game_Main  
  139.  
  140. ////////////////////////////////////////////////////////////  
  141.  
  142. int Game_Init(void *parms = NULL, int num_parms = 0)  
  143. {  
  144.  
  145.         // this is called once after the initial window is created and  
  146.         // before the main event loop is entered, do all your initialization  
  147.         // here  
  148.  
  149.         // create IDirectDraw interface 7.0 object and test for error  
  150.         if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))  
  151.                 return(0);  
  152.         // set cooperation to full screen  
  153.         if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,   
  154.                 DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |   
  155.                 DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))  
  156.                 return(0);  
  157.  
  158.         // set display mode to 640x480x8  
  159.         if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))  
  160.                 return(0);  
  161.  
  162.         // we need a complex surface system with a primary and backbuffer  
  163.  
  164.         // clear ddsd and set size  
  165.         DDRAW_INIT_STRUCT(ddsd);   
  166.  
  167.         // enable valid fields  
  168.         ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;  
  169.  
  170.         // set the backbuffer count field to 1, use 2 for triple buffering  
  171.         ddsd.dwBackBufferCount = 1;  
  172.  
  173.         // request a complex, flippable  
  174.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;  
  175.  
  176.         // create the primary surface  
  177.         if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))  
  178.                 return(0);  
  179.  
  180.         // now query for attached surface from the primary surface  
  181.  
  182.         // this line is needed by the call  
  183.         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;  
  184.  
  185.         // get the attached back buffer surface  
  186.         if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))  
  187.                 return(0);  
  188.  
  189.           
  190.  
  191.         // set clipper up on back buffer since that's where well clip  
  192.         RECT screen_rect= {0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1};  
  193.         lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect);  
  194.  
  195.         // load the 8-bit p_w_picpath  
  196.         if (!Load_Bitmap_File(&bitmap,"1.bmp"))  
  197.                 return(0);  
  198.  
  199.         // clean the surfaces  
  200.         DDraw_Fill_Surface(lpddsprimary,0);  
  201.         DDraw_Fill_Surface(lpddsback,0);  
  202.  
  203.         // create the buffer to hold the background  
  204.         lpddsbackground = DDraw_Create_Surface(640,480,0);  
  205.  
  206.         // copy the background bitmap p_w_picpath to the background surface   
  207.  
  208.         // lock the surface  
  209.         lpddsbackground->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);  
  210.  
  211.         // get video pointer to primary surfce  
  212.         DWORD *p_w_picpath_buffer = (DWORD *)ddsd.lpSurface;         
  213.  
  214.         // process each line and copy it into the primary buffer  
  215.         for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)  
  216.         {  
  217.                 for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)  
  218.                 {  
  219.                         // get BGR values  
  220.                         UCHAR blue  = (bitmap.buffer[index_y*SCREEN_WIDTH*4 + index_x*4 + 0]),  
  221.                                   green = (bitmap.buffer[index_y*SCREEN_WIDTH*4 + index_x*4 + 1]),  
  222.                                   red   = (bitmap.buffer[index_y*SCREEN_WIDTH*4 + index_x*4 + 2]);  
  223.  
  224.                         // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)  
  225.                         DWORD pixel = _RGB32BIT(0,red,green,blue);  
  226.  
  227.                         // write the pixel  
  228.                         p_w_picpath_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;  
  229.  
  230.                 } // end for index_x  
  231.  
  232.         } // end for index_y  
  233.  
  234.         // now unlock the primary surface  
  235.         if (FAILED(lpddsbackground->Unlock(NULL)))  
  236.                 return(0);  
  237.  
  238.         // unload the bitmap file, we no longer need it  
  239.         Unload_Bitmap_File(&bitmap);  
  240.  
  241.         // seed random number generator  
  242.         srand(GetTickCount());  
  243.  
  244.         // initialize all the aliens  
  245.  
  246.         // alien on level 1 of complex  
  247.  
  248.         aliens[0].x              = rand()%SCREEN_WIDTH;  
  249.         aliens[0].y              = 116 - 72;                    
  250.         aliens[0].velocity       = 2+rand()%4;  
  251.         aliens[0].current_frame  = 0;               
  252.         aliens[0].counter        = 0;         
  253.  
  254.         // alien on level 2 of complex  
  255.  
  256.         aliens[1].x              = rand()%SCREEN_WIDTH;  
  257.         aliens[1].y              = 246 - 72;                    
  258.         aliens[1].velocity       = 2+rand()%4;  
  259.         aliens[1].current_frame  = 0;               
  260.         aliens[1].counter        = 0;    
  261.  
  262.         // alien on level 3 of complex  
  263.  
  264.         aliens[2].x              = rand()%SCREEN_WIDTH;  
  265.         aliens[2].y              = 382 - 72;                    
  266.         aliens[2].velocity       = 2+rand()%4;  
  267.         aliens[2].current_frame  = 0;               
  268.         aliens[2].counter        = 0;    
  269.  
  270.         // now load the bitmap containing the alien p_w_picpathry  
  271.         // then scan the p_w_picpaths out into the surfaces of alien[0]  
  272.         // and copy then into the other two, be careful of reference counts!  
  273.  
  274.         // load the 8-bit p_w_picpath  
  275.         if (!Load_Bitmap_File(&bitmap,"3.bmp"))  
  276.                 return(0);  
  277.  
  278.         // create each surface and load bits  
  279.         for (int index = 0; index < 2; index++)  
  280.         {  
  281.                 // create surface to hold p_w_picpath  
  282.                 aliens[0].frames[index] = DDraw_Create_Surface(72,80,0);  
  283.  
  284.                 // now load bits...  
  285.                 Scan_Image_Bitmap(&bitmap,                 // bitmap file to scan p_w_picpath data from  
  286.                         aliens[0].frames[index], // surface to hold data  
  287.                         index, 2);               // cell to scan p_w_picpath from      
  288.  
  289.         } // end for index  
  290.  
  291.         // unload the bitmap file, we no longer need it  
  292.         Unload_Bitmap_File(&bitmap);  
  293.  
  294.         // now for the tricky part. There is no need to create more surfaces with the same  
  295.         // data, so I'm going to copy the surface pointers member for member to each alien  
  296.         // however, be careful, since the reference counts do NOT go up, you still only need  
  297.         // to release() each surface once!  
  298.  
  299.         for (int index = 0; index < 2; index++)  
  300.                 aliens[1].frames[index] = aliens[2].frames[index] = aliens[0].frames[index];  
  301.  
  302.         // return success or failure or your own return code here  
  303.         return(1);  
  304.  
  305. // end Game_Init  
  306.  
  307. /////////////////////////////////////////////////////////////  
  308.  
  309. int Game_Shutdown(void *parms = NULL, int num_parms = 0)  
  310. {  
  311.         // this is called after the game is exited and the main event  
  312.         // loop while is exited, do all you cleanup and shutdown here  
  313.  
  314.  
  315.         // first the palette  
  316.         if (lpddpal)  
  317.         {  
  318.                 lpddpal->Release();  
  319.                 lpddpal = NULL;  
  320.         } // end if  
  321.  
  322.         // now the primary surface  
  323.         if (lpddsprimary)  
  324.         {  
  325.                 lpddsprimary->Release();  
  326.                 lpddsprimary = NULL;  
  327.         } // end if  
  328.  
  329.         // now blow away the IDirectDraw4 interface  
  330.         if (lpdd)  
  331.         {  
  332.                 lpdd->Release();  
  333.                 lpdd = NULL;  
  334.         } // end if  
  335.  
  336.         // unload the bitmap file, we no longer need it  
  337.         Unload_Bitmap_File(&bitmap);  
  338.  
  339.  
  340.         // return success or failure or your own return code here  
  341.         return(1);  
  342.  
  343. // end Game_Shutdown  
  344.  
  345. // WINMAIN ////////////////////////////////////////////////  
  346.  
  347. int WINAPI WinMain(        HINSTANCE hinstance,  
  348.         HINSTANCE hprevinstance,  
  349.         LPSTR lpcmdline,  
  350.         int ncmdshow)  
  351. {  
  352.  
  353.         WNDCLASSEX winclass; // this will hold the class we create  
  354.         HWND           hwnd;         // generic window handle  
  355.         MSG                   msg;                 // generic message  
  356.         HDC        hdc;      // graphics device context  
  357.  
  358.         // first fill in the window class stucture  
  359.         winclass.cbSize         = sizeof(WNDCLASSEX);  
  360.         winclass.style                        = CS_DBLCLKS | CS_OWNDC |   
  361.                 CS_HREDRAW | CS_VREDRAW;  
  362.         winclass.lpfnWndProc        = WindowProc;  
  363.         winclass.cbClsExtra                = 0;  
  364.         winclass.cbWndExtra                = 0;  
  365.         winclass.hInstance                = hinstance;  
  366.         winclass.hIcon                        = LoadIcon(NULL, IDI_APPLICATION);  
  367.         winclass.hCursor                = LoadCursor(NULL, IDC_ARROW);   
  368.         winclass.hbrBackground        = (HBRUSH)GetStockObject(BLACK_BRUSH);  
  369.         winclass.lpszMenuName        = NULL;  
  370.         winclass.lpszClassName        = WINDOW_CLASS_NAME;  
  371.         winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);  
  372.  
  373.         // save hinstance in global  
  374.         hinstance_app = hinstance;  
  375.  
  376.         // register the window class  
  377.         if (!RegisterClassEx(&winclass))  
  378.                 return(0);  
  379.  
  380.         // create the window  
  381.         if (!(hwnd = CreateWindowEx(NULL,                  // extended style  
  382.                 WINDOW_CLASS_NAME,     // class  
  383.                 TEXT("DirectDraw 8-Bit Bitmap Loading"), // title  
  384.                 WS_POPUP | WS_VISIBLE,  
  385.                 0,0,          // initial x,y  
  386.                 SCREEN_WIDTH,SCREEN_HEIGHT,  // initial width, height  
  387.                 NULL,          // handle to parent   
  388.                 NULL,          // handle to menu  
  389.                 hinstance,// instance of this application  
  390.                 NULL)))        // extra creation parms  
  391.                 return(0);  
  392.  
  393.         // save main window handle  
  394.         main_window_handle = hwnd;  
  395.  
  396.         // initialize game here  
  397.         Game_Init();  
  398.  
  399.         // enter main event loop  
  400.         while(TRUE)  
  401.         {  
  402.                 // test if there is a message in queue, if so get it  
  403.                 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))  
  404.                 {   
  405.                         // test if this is a quit  
  406.                         if (msg.message == WM_QUIT)  
  407.                                 break;  
  408.  
  409.                         // translate any accelerator keys  
  410.                         TranslateMessage(&msg);  
  411.  
  412.                         // send the message to the window proc  
  413.                         DispatchMessage(&msg);  
  414.                 } // end if  
  415.  
  416.                 // main game processing goes here  
  417.                 Game_Main();  
  418.                   
  419.  
  420.         } // end while  
  421.  
  422.         // closedown game here  
  423.         Game_Shutdown();  
  424.  
  425.         // return to Windows like this  
  426.         return(msg.wParam);  
  427.  
  428. // end WinMain  
  429.  
  430. ///////////////////////////////////////////////////////////