《宇宙战争》游戏开发总结(雷电游戏)

   
   
   
   
   
   
   
   
   


游戏效果图:

《宇宙战争》游戏开发总结(雷电游戏)_第1张图片

《宇宙战争》游戏开发总结(雷电游戏)_第2张图片

做这个游戏 很轻松,就是想练练windows编程技术。零零散散花点时间,心情不好就放着不管,半个月也做好了。主业其实是继续学习操作系统原理。

3月28号,设计了雷电战斗机的第一幅图。 
                做出了一个实验性的动画。
3月29号,实现了炮弹效果。
4月14号,实现了连续发射炮弹功能。
4月7号,加入敌机AI。
4月9号,为敌机AI加入发射炮弹功能。
4月13号,爆炸效果实现。
4月14号,采用新的游戏动画制作技术(位图背景透明显示技术),以游戏循环代替定时器来控制动画。
              使游戏画面终于流畅了!这是令人激动的进展!
                同时重绘了所有战机,加入游戏背景,一切都开始用位图表示。
4月15号,花了一个小时,最后润色了一下。

做这个游戏也是追求梦想的过程,一直想做一个真正有界面,有漂亮的画面,有战斗场面的游戏。只是一直不知道该怎么实现,现在我终于可以做到了!
 

我的收获:
         1,练习了windows编程技术,由一无所知到有信心开发简单应用程序。
         2,掌握了许多游戏开发和动画制作的技术。
         3,认识到了C语言的局限,与C++的优势。(在写大程序的基础之上)
         4,确定了自己的专攻领域--------游戏开发。

位图资源:

邪恶战机.bmp
《宇宙战争》游戏开发总结(雷电游戏)_第3张图片

帝国战机.bmp 
《宇宙战争》游戏开发总结(雷电游戏)_第4张图片

炮弹.bmp



爆炸.bmp

《宇宙战争》游戏开发总结(雷电游戏)_第5张图片

海.bmp

《宇宙战争》游戏开发总结(雷电游戏)_第6张图片

源码:



C++代码
#include 
#define IDT_TIMER1 1 
int nMode;
HBITMAP Ene,bg,cannonball,Eme,Explode;
HDC mdc;
DWORD tPre,tNow,tCheck;
int num,frame,fps;

int x=400;
int y=600;

HDC hdc;

#define IDT_TIMER3 3//敌机发弹速度

#define IDT_TIMER2 2//定义定时器2每12秒出现一个A类敌机

#define IDT_TIMER4 4    //定义定时器4,我放飞机爆炸效果持续时间

//-----------------------------------------
int Cannonball_x[20];                 //表示炮弹的横坐标
int Cannonball_y[20];                 //表示炮弹的纵坐标

int C_Num[20];                        //用该数组标记一到二十个炸弹                         
int Num=0;                             //Num取值零到十九
int i;
int f;
//----------------------------------------

//++++++++++++++++++++++敌方炮弹++++++++++
int E_A_Cannonball_x[10];              //敌机A炮弹横坐标数组
int E_A_Cannonball_y[10];              //敌机A炮弹纵坐标数组
int E_A_Num=0;                           //标记敌机炮弹
int E_A_NumCount[10];                 //标记敌机炮弹数组
//++++++++++++++++++++++++++++++++++++++++

//===================================初始化A类敌机坐标     该类敌机由屏幕左上向屏幕右下移动并射击====================
int E_A_x=0;
int E_A_y=0;
//==================================================================================================================

//是否我方战机撞到敌方炮弹
int If_Explode=0;
int  Draw_Explode=0;
int If_A_Explode=0;
int  Draw_A_Explode=0;

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);    
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
      HWND hwnd;
	  MSG Msg;
	  WNDCLASS wndclass;
	  char lpszClassName[]="日向";                                     
	  char lpszTitle[]="日向";                                  
	  wndclass.style=0;                                          
	  wndclass.lpfnWndProc=WndProc;                             
	  wndclass.cbClsExtra=0;                                      
	  wndclass.cbWndExtra=0;                                      
	  wndclass.hInstance=hInstance;                                 
	  wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);              
	  wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);                  
	  wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);   
	  wndclass.lpszMenuName=NULL;                                    
	  wndclass.lpszClassName=lpszClassName;                          

if(!RegisterClass(&wndclass))                          
{
	MessageBeep(0);
	return FALSE;
}
    hwnd=CreateWindow(
		               lpszClassName,                   
					  lpszTitle,                        
                      WS_OVERLAPPEDWINDOW,               
                      CW_USEDEFAULT,            
	                  CW_USEDEFAULT,                  
					  CW_USEDEFAULT,
                      CW_USEDEFAULT,                    
					  NULL,                            
					  NULL,                           
					  hInstance,                    
					  NULL                          
					  );
MoveWindow(hwnd,0,0,1400,800,true);
ShowWindow(hwnd,SW_SHOW);                                
UpdateWindow(hwnd);  

//------------------------------------------------
       for(int jj=0;jj<20;jj++)                 //初始化C_Num[20]数组为0
   {
    	C_Num[jj]=0;
   }
//------------------------------------------
	   //+++++++++++++++++++++++++++++++++++++++++++
	 for(i=0;i<9;i++)
	 {
		 E_A_NumCount[i]=0;
	 }
	 //++++++++++++++++++++++++++++++++++++++++++

     
 			 hdc=GetDC(hwnd);
			 mdc=CreateCompatibleDC(hdc);  
             

/*************************************************************这两个语句必须在下面的游戏循环之外**********************/			 
bg=(HBITMAP)LoadImage(NULL,"海.bmp",IMAGE_BITMAP,1500,1000,LR_LOADFROMFILE); 
Ene=(HBITMAP)LoadImage(NULL,"帝国战机.bmp",IMAGE_BITMAP,170,99,LR_LOADFROMFILE);
cannonball=(HBITMAP)LoadImage(NULL,"炮弹.bmp",IMAGE_BITMAP,70,39,LR_LOADFROMFILE);
Eme=(HBITMAP)LoadImage(NULL,"邪恶战机.bmp",IMAGE_BITMAP,170,99,LR_LOADFROMFILE);
Explode=(HBITMAP)LoadImage(NULL,"爆炸.bmp",IMAGE_BITMAP,170,99,LR_LOADFROMFILE);
/**********************************************************************************************************************/

while(Msg.message!=WM_QUIT)
{
	if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	else
	{
		tNow=GetTickCount();
		if(tNow-tPre>=1000){
			绘图                  
             SelectObject(mdc,bg);
             BitBlt(hdc,0,0,1500,1000,mdc,0,0,SRCCOPY);
			 //---------------画我方飞机---------------------------------
        if(If_Explode==0){
			 SelectObject(mdc,Ene);
	       	 BitBlt(hdc,x,y,85,99,mdc,85,0,SRCAND);
             BitBlt(hdc,x,y,85,99,mdc,0,0,SRCPAINT);
			 //----------------------------------------------------------
			          SelectObject(mdc,cannonball);                                       //画炮弹
                      for(i=0;i<20;i++){
			              if(C_Num[i]==1){                                          //如果C_Num[i]=1表示有炮弹,开始画炮弹。可以
						                                                         //标记20个不同时间的
                            BitBlt(hdc,Cannonball_x[i],Cannonball_y[i],70,39,mdc,70,0,SRCAND);
						    BitBlt(hdc,Cannonball_x[i],Cannonball_y[i],70,39,mdc,0,0,SRCPAINT);
							//*********************************在这里判断是否敌机A被炮弹击中******************************
							if((E_A_x-20<=Cannonball_x[i]+10)&&(Cannonball_x[i]+10<=E_A_x+20)&&(E_A_y>=Cannonball_y[i]+20)
						            &&(E_A_y<=Cannonball_y[i]+60)){
								C_Num[i]=0;                  
                                Cannonball_x[i]=0;           //炮弹坐标重置,表示不再画这个炮弹             
                                Cannonball_y[i]=0; 
							    If_A_Explode=1;
                                Draw_A_Explode=1;
							}
							//********************************************************************************************
						  }
					  }
		}//If_Explode结束
			 //--------------------------------------------
	     	 for(i=0;i<20;i++)
			 {
				 if(C_Num[i]==1)                                            //如果C_Num[i],表示炮弹发射,通过不断改变纵坐标实现运动
				 {             
					 Cannonball_y[i]-=1;
				 }
			 }
			 //--------------------------------------------------
			 //===========================================================画敌机
			 if(If_A_Explode==0){
			        SelectObject(mdc,Eme);
                    BitBlt(hdc,E_A_x,E_A_y,85,99,mdc,85,0,SRCAND); 
                    BitBlt(hdc,E_A_x,E_A_y,85,99,mdc,0,0,SRCPAINT);
			 }
			 //===========================================================
             E_A_x+=1;                           //敌机坐标变化
			 E_A_y+=1;
			 //===========================================================
			 //+++++++++++++++++++++++++++++++++++画敌机炮弹+++++++++++++
		if(If_A_Explode==0){
              SelectObject(mdc,cannonball); 
			 for(i=0;i<9;i++){
				 if(E_A_NumCount[i]==1){
                            BitBlt(hdc,E_A_Cannonball_x[i],E_A_Cannonball_y[i],70,39,mdc,70,0,SRCAND);
						    BitBlt(hdc,E_A_Cannonball_x[i],E_A_Cannonball_y[i],70,39,mdc,0,0,SRCPAINT);
				       if((x-20<=E_A_Cannonball_x[i]+10)&&(E_A_Cannonball_x[i]+10<=x+20)&&(y>=E_A_Cannonball_y[i]+20)
						            &&(y<=E_A_Cannonball_y[i]+60)){        //是否我方飞机撞到炮弹
                         E_A_NumCount[i]=0;
                         E_A_Cannonball_x[i]=0;
                         E_A_Cannonball_y[i]=0;
					If_Explode=1;
					Draw_Explode=1;                                    
					   }
				 }
			 }
		}//If_A_Explode结束
			 //---------------------------------------------------如果我方战机撞到地方炮弹
		if( Draw_Explode==1){                                       //画爆炸效果
	                SelectObject(mdc,Explode);
                    BitBlt(hdc,x+20,y,85,99,mdc,85,0,SRCAND); 
                    BitBlt(hdc,x+20,y,85,99,mdc,0,0,SRCPAINT); 
			 }
		     //--------------------------------------------------如果敌机A被毁
		if(Draw_A_Explode==1){                                       //画爆炸效果
			        SelectObject(mdc,Explode);
			        BitBlt(hdc,E_A_x+20,E_A_y,85,99,mdc,85,0,SRCAND); 
                    BitBlt(hdc,E_A_x+20,E_A_y,85,99,mdc,0,0,SRCPAINT); 
		}
			 //--------------------------------------------------------------------------

          //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			 /敌机AI炮弹坐标变化
			 for(i=0;i<10;i++)
			 {
				 if(E_A_NumCount[i]==1)
				 {
					 E_A_Cannonball_y[i]+=4;
				 }
			 }
			 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			 //------------------------------判断是否相撞--------------------
			      if((x-20<=E_A_x+10)&&(E_A_x+10<=x+20)&&(y>=E_A_y+20)
						            &&(y<=E_A_y+60))
				  {
				    	If_Explode=1;                     //若相撞两飞机都爆炸
				    	Draw_Explode=1; 
					    If_A_Explode=1;
                        Draw_A_Explode=1;
				  }
			 //--------------------------------------------------------------
		}
	}
}
  return Msg.wParam;                                          
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch(message)
	{
	      case WM_CREATE:
             	//******************************************定时器的定义*********************************************
	                 //我方飞机的定时器
	         ::SetTimer(hwnd,IDT_TIMER3,600,NULL);
	                 //定义定时器2每12秒出现一个A类敌机
          	 ::SetTimer(hwnd,IDT_TIMER2,6000,NULL);
                   //定义定时器3,每一秒敌机发射一发炮弹
                    ::SetTimer(hwnd,IDT_TIMER4,600,NULL);      //设置爆炸效果持续时间
			   break;
           case WM_TIMER:
               switch(wParam)
			   {
			      case IDT_TIMER2:		
			         E_A_x=0;
			         E_A_y=0;
					 if(If_A_Explode==1){              //如果敌机已被击中,规定时间内重画
                           If_A_Explode=0;
					 }
		             break;
		          case IDT_TIMER3:
		        	 if(E_A_Num==9)
			        	 E_A_Num=0;
		        	 else{
			         	 E_A_NumCount[E_A_Num]=1;
					 }
		        	 E_A_Cannonball_x[E_A_Num]=E_A_x+25;
		             E_A_Cannonball_y[E_A_Num]=E_A_y+50;
		        	 E_A_Num++;
		             break;
		        case IDT_TIMER4:
                    Draw_Explode=0;
                    Draw_A_Explode=0;
		            break;
			   }
            case WM_KEYDOWN:
			{
				switch(wParam)
				{
                  	case VK_UP:                                   //控制我方飞机方向
				    	            y-=22;
				                	break;
			    	case VK_RIGHT:
							    	x+=22;
					                break;
                   case VK_LEFT:
							     	x-=22;
					                break;
                    case VK_DOWN:
								    y+=22;
					                break;
				//----------------------------------------------------------------------------------
		            case VK_SPACE:                 //按shift键发射炮弹
				        if(Num==19)                //若Num增至19,转为零从新开始
						     Num=0;
				    	  else{
						      C_Num[Num]=1;
						  }
                            Cannonball_x[Num]=x;            //获取第Num个炸弹的刚发射时的坐标值,发射后
                            Cannonball_y[Num]=y-20;         //只需不断改变纵坐标自动的实现运d
                            Num++;
				          	break;
							//---------------------------------------------------------------------------
				}
			  
		 }
          break;       
		case WM_DESTROY:
			PostQuitMessage(0);                                
		default:                                          
			return DefWindowProc(hwnd,message,wParam,lParam);
	}
	return 0;
}









你可能感兴趣的:(游戏开发,windows程序设计,游戏开发,C,windows程序设计)