📄 winmain.cpp
字号:
// create the loader to load object(s) such as midi file
if (FAILED(CoCreateInstance(
CLSID_DirectMusicLoader,
NULL,
CLSCTX_INPROC,
IID_IDirectMusicLoader,
(void**)&dm_loader)))
{
// error
return(0);
} // end if
// reset all the midi segment objects
/*for (index = 0; index < MUSIC_NUM; index++)
{
// reset the object
dm_midi[index].dm_segment = NULL;
dm_midi[index].dm_segstate = NULL;
dm_midi[index].state = MIDI_NULL;
dm_midi[index].id = index;
} // end for index
*/
// reset the active id
//dm_active_id = -1;
// all good baby
return(1);
}
// ---------------------------------------------------------end DMusic_Init-----------------
//------------------------------------------------------------此函数用来加载一个MIDI文件--------
//------------------------------------------------------------具体原理不太明,经过加工----------
int DMusic_Load_MIDI(DMUSIC_MIDI * dm_midi,char *filename)
{
// this function loads a midi segment
DMUS_OBJECTDESC ObjDesc;
HRESULT hr;
IDirectMusicSegment* pSegment = NULL;
//int index; // loop var
// look for open slot for midi segment
//int id = -1;
/*for (index = 0; index < DM_NUM_SEGMENTS; index++)
{
// is this one open
if (dm_midi[index].state == MIDI_NULL)
{
// validate id, but don't validate object until loaded
id = index;
break;
} // end if
} // end for index
// found good id?
if (id==-1)
return(-1);*/
// get current working directory
char szDir[_MAX_PATH];
WCHAR wszDir[_MAX_PATH];
if( _getcwd( szDir, _MAX_PATH ) == NULL)
{
return(1);;
} // end if
MULTI_TO_WIDE(wszDir, szDir);
// tell the loader were to look for files
hr = dm_loader->SetSearchDirectory(GUID_DirectMusicAllTypes,wszDir, FALSE);
if (FAILED(hr))
{
return (2);
} // end if
// convert filename to wide string
WCHAR wfilename[_MAX_PATH];
MULTI_TO_WIDE(wfilename, filename);
// setup object description
INIT_DDSD(ObjDesc);
ObjDesc.guidClass = CLSID_DirectMusicSegment;
wcscpy(ObjDesc.wszFileName, wfilename );
ObjDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;
// load the object and query it for the IDirectMusicSegment interface
// This is done in a single call to IDirectMusicLoader::GetObject
// note that loading the object also initializes the tracks and does
// everything else necessary to get the MIDI data ready for playback.
hr = dm_loader->GetObject(&ObjDesc,IID_IDirectMusicSegment, (void**) &pSegment);
if (FAILED(hr))
return(3);
// ensure that the segment plays as a standard MIDI file
// you now need to set a parameter on the band track
// Use the IDirectMusicSegment::SetParam method and let
// DirectMusic find the trackby passing -1 (or 0xFFFFFFFF) in the dwGroupBits method parameter.
hr = pSegment->SetParam(GUID_StandardMIDIFile,-1, 0, 0, (void*)dm_perf);
if (FAILED(hr))
return(4);
// This step is necessary because DirectMusic handles program changes and
// bank selects differently for standard MIDI files than it does for MIDI
// content authored specifically for DirectMusic.
// The GUID_StandardMIDIFile parameter must be set before the instruments are downloaded.
// The next step is to download the instruments.
// This is necessary even for playing a simple MIDI file
// because the default software synthesizer needs the DLS data
// for the General MIDI instrument set
// If you skip this step, the MIDI file will play silently.
// Again, you call SetParam on the segment, this time specifying the GUID_Download parameter:
hr = pSegment->SetParam(GUID_Download, -1, 0, 0, (void*)dm_perf);
if (FAILED(hr))
return(5);
// at this point we have MIDI loaded and a valid object
(*dm_midi).dm_segment = pSegment;
(*dm_midi).dm_segstate = NULL;
(*dm_midi).state = MIDI_LOADED;
// return id
return(0);
}
//------------------------------------------------------------ end DMusic_Load_MIDI--------------
//---------------------------------------------------用来构造一个柜形---------------------------
void my_rect(int x,int y,int r,int b)
{rect.left=x;
rect.top=y;
rect.bottom=b;
rect.right=r;
}
//-----------------------------------------------------初始化背景星星----------------------------
void initstar()
{int i,r,g,b;
for(i=0;i<star_num;i++)
{star[i].x=rand()%SCREEN_WIDTH;//X轴坐标-----
star[i].y=rand()%SCREEN_HEIGHT;//Y轴坐标----
star[i].v=rand()%5+1;//速度=-------------
//根据star_stat决定是什么顔色-------------
r=rand()%245+10;
g=rand()%245+10;
b=rand()%245+10;
if(star_stat==0)
star[i].c=RGB(r,r,r);//黑白---------
else if(star_stat==1)
star[i].c=RGB(r,0,0);//红色---------
else if(star_stat==2)
star[i].c=RGB(0,g,0);//绿色---------
else if(star_stat==3)
star[i].c=RGB(0,0,b);//蓝色---------
else if(star_stat==4)
star[i].c=RGB(r,g,b);//彩色---------
else
star[i].c=RGB(r,r,r);//黑白---------
}
}
//----------------------------------------------------------------移动星星,并画到缓冲上-------
inline void movestar()
{int i;
for (i=0;i<star_num;i++)
{star[i].y+=star[i].v;//移动----------
if(star[i].y>=SCREEN_HEIGHT)
star[i].y-=SCREEN_HEIGHT;
SetPixel(my_dc,star[i].x,star[i].y,star[i].c);//画点-------------
}
}
//--------------------------------------------------每一盘开始时用来初始化一些变量--------------
void my_game_init()
{//\=================================plane_init============
srand(GetTickCount());
plane.x=rand()%(SCREEN_WIDTH-60)+5;
plane.y=rand()%(100)*(-1)+(SCREEN_HEIGHT-72);
plane.stat=0;
//-------------------------------fire_init-----------------
for(int u=0;u<FIRE_NUM;u++)
fire[u].stat=0;
//----------------------planee_init-------------
for(int u=0;u<PLANEE_NUM;u++)
planee[u].stat=-1;
for(int u=0;u<FIREE_NUM;u++)
firee[u].stat=0;
//p=0;
initstar();
p_e_n=0;//敌机数为0
f_e_n=0;//敌子弹数为0
plane.num=0;//我机子弹数为0
planee_num=4+(grade-1)*2;
firee_num=9+(grade-1)*2;
if(grade==6)
{if(over_sco<100)
over_sco=100;
}
if(fire_stat==0)
fire_num=10;
else
fire_num=27;
plane_v=8;
fire_v=8;
planee_v=2;
firee_v=2+grade;
sco=0;
dm_perf->Stop(NULL,NULL,0,0);//停止MIDI音乐的播放--------------------
dm_perf->PlaySegment(dmusic[grade-1].dm_segment,0,0,&dmusic[grade-1].dm_segstate);//播放MIDI音乐-----------
}
//-------------------------------------------------------------end my_game_init()--------------------------------
//-------------------------------------------------------------WinAPI的回调函数-----------------
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
char buffer[80]; // used to print strings
// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
// return success
return(0);
} break;
case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
// end painting
EndPaint(hwnd,&ps);
// return success
return(0);
} break;
case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
// return success
return(0);
} break;
default:break;
} // end switch
// process any messages that we didn't take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
//------------------------------------------------------------- end WinProc-----------------------
//-------------------------------------------------------------游戏的主体------------------------
int Game_Main(void *parms = NULL, int num_parms = 0)
{
if(KEYDOWN(VK_ESCAPE))//是否按下ESC键-----------------
{ Sleep(300);
end=2;//进入菜单2-------------------------
bb=0;
}
if(KEYDOWN(VK_RETURN))//是否按下回车键------------
{end=1;//-----------------暂停-------------------
bb=0;
gamepause_s.dsbuffer->Play(0,0,0);//播放暂停的声音--------------------
Sleep(500);
return (1);
}
STAR_TIME=GetTickCount();
if(KEYDOWN(VK_LEFT) | KEYDOWN(my_left))//是否按下向左的键--------------------
{plane.x-=plane_v;
plane.stat=1;
}
if(KEYDOWN(VK_RIGHT) | KEYDOWN(my_right))//是否按下向右的键------------------
{plane.x+=plane_v;
plane.stat=2;
}
if(KEYDOWN(VK_UP) | KEYDOWN(my_up))//是否按下向上的键-------------------------
plane.y-=plane_v;
if(KEYDOWN(VK_DOWN) | KEYDOWN(my_down))//是否按下向上的键----------------
plane.y+=plane_v;
//是否越界--------------------------------------------
if(plane.x<2)
plane.x=2;
if(plane.x>MMWIDTH)
plane.x=MMWIDTH;
if(plane.y<2)
plane.y=2;
if(plane.y>MMHEIGHT)
plane.y=MMHEIGHT;
//操作我机子弹------------------
if(plane.num<fire_num)//是否能发子弹-------------------
{ if(p%6==0)
{ if(KEYDOWN(my_fire) | KEYDOWN(VK_SPACE) )
{if(fire_stat==0)//单弹模式---------
{for(u=0;u<fire_num;u++)
{if(fire[u].stat==0)
{fire[u].stat=1;
fire[u].x=plane.x+25;
fire[u].y=plane.y;
plane.num++;
//发出我机子弹的声音-------------
fire_s[u].dsbuffer->Play(0,0,0);
break;
}
} //end for---------
}
else //散弹模式------------------
{if((fire_num-plane.num)>2)
{ n=0;
for(u=0;u<fire_num & n<fire_num;u++)
{
if(fire[n].stat==0)
{n++;
if(fire[n].stat==0)
{n++;
if(fire[n].stat==0)
{ fire[n].stat=1;
fire[n].x=plane.x+25;
fire[n].y=plane.y;
fire[n-1].stat=1;
fire[n-1].x=plane.x+25;
fire[n-1].y=plane.y;
fire[n-2].stat=1;
fire[n-2].x=plane.x+25;
fire[n-2].y=plane.y;
plane.num+=3;
fire_s[n].dsbuffer->Play(0,0,0);
u=100;
}
}
}
n++;
}
}
}//end散弹模式-----------
}
}
}//结束——————是否发弹-----------
//----------------------------------------是否打中敌机,是否越界-------------
if(plane.num>0) //是否有子弹-----------------
{
for(u=0;u<fire_num;u++)//针对每一颗子弹-----------------
{if(fire[u].stat==1)//子弹是否有效--------------------------
{ fire[u].y-=fire_v;//移动子弹-------------------------
if(fire_stat==1)
fire[u].x+=fire[u].xv;
if(fire[u].x<2 | fire[u].y<2 | fire[u].x>fire_x_max| fire[u].y >fire_y_max)//是否出界---
{ fire[u].stat=0;//让子弹失效-----
plane.num--;//我机的子弹个数减少一个---------------
}
for(n=0;n<planee_num;n++)//对每一个敌机-------
{if(planee[n].stat==0)//敌机是否死掉---------0为活着--1为被打中正爆炸-__-1为死掉--
{if(fire[u].x>planee[n].x & fire[u].y>planee[n].y & fire[u].x<(planee[n].x+54) & fire[u].y<(planee[n].y+50))//是否被打中-------
{planee[n].stat=1;//被打中------
fire[u].stat=0;//让子弹失效------
plane.num--;//子弹少一个-----------
sco++;
//发出敌机爆炸的声音-------------
planee_s[n].dsbuffer->SetPan(33*(planee[n].x-plane.x));
planee_s[n].dsbuffer->Play(0,0,0);
if(sco==over_sco)
{end=4;
bb=0;
gamepast_s.dsbuffer->Play(0,0,0);
Sleep(200);
return (1);
}
}
}
}
}//endif(fire[u].stat==1)-------------------
}
}
//结束——————操作我机子弹----
//是否生成敌机-------------------
if(p_e_n<planee_num)
{if(rand()%13==1)
{for(u=0;u<planee_num;u++)
{if(planee[u].stat==-1)
{planee[u].x=rand()%planee_x_max;
planee[u].y=2;
planee[u].stat=0;
p_e_n++;//飞机数加一______----------
if(p_e_n>planee_num)
p_e_n=planee_num;
break;
}
}
}
}
//操作敌机--------------------------------
if(p_e_n>0)//是否有敌机-------------
{ for(u=0;u<planee_num;u++)
{if(planee[u].stat==0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -