您的位置:首页 > 其它

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

2013-05-20 17:59 281 查看
  
  
  
  
  
  
  
  
  
游戏效果图:





做这个游戏很轻松,就是想练练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



帝国战机.bmp 



炮弹.bmp



爆炸.bmp



海.bmp



源码:

C++代码

#include <windows.h>
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息