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

📄 xinvader.cpp

📁 我用MDEngine写的游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
//			Programed by Johnhans   (C)2002   All Rights Reserved!
//
//
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>
#include <mmsystem.h>
#include "MD_Engine.h"
#include "MD_Surface.h"
#include "MD_Input.h"
#include "MD_Audio.h"
#include "MD_Sound.h"
#include "MD_Timer.h"
#include "MD_File.h"
#include "XInvader.h"
#include "resource.h"
//--------------------------------------------------------------------
// 宏定义
//--------------------------------------------------------------------
#define NAME "XInvader"

#define G_MENU		0
#define G_RUN		1
#define G_CREDITS	2
#define G_HELP		3
#define	G_GAMEOVER	4
#define G_LEVEL		5

#define SAFE_DELETE(A)			if( (A) != NULL ) { delete [] (A); (A) = NULL; }
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
CMD_Engine		Engine;
CMD_Surface		sur_menu;
CMD_Surface		sur_bkgnd;
CMD_Surface		sur_Alphabet;
CMD_Surface		sur_Extras;
CMD_Surface		sur_Ship;
CMD_Surface		sur_Ufo[3];
CMD_Surface		*sur_UfoN;
CMD_Surface		sur_Bullet;
CMD_Input		Input;
CMD_Timer		Timer;
CMD_Timer		TimerTP;
CMD_Audio		Audio;
CMD_Sound		snd_stop;
CMD_Sound		snd_sel;
CMD_Sound		snd_sfire;
CMD_Sound		snd_ufire;
CMD_Sound		snd_explode;
CMD_Sound		snd_extra;
CMD_Sound		snd_gameover;
CMD_Sound		snd_level;

BOOL			bActive;						// 程序是否挂起
bool			RunGame=true;					// 程序运行中
BYTE			m_State=G_MENU;					// 游戏状态

Bullet			m_Bullet[MAX_BULLET];
UFO				m_UFO[MAX_UFO];
Extra			m_Extra[MAX_EXTRA];

unsigned int iScore	= 0;					// 得分
int		iShipPos	= 285;					// 飞船位置X
int		iShipMov	= 0;					// 飞船移动量
int		iShipframe	= 0;					// 当前飞船动画帧
int		iWeapon		= 0;					// 当前武器
int		iMaxWeapon	= 5;					// 可用武器
int		iLaserAmmo	= 100;					// Laser 剩余弹药
int		iPhotonAmmo	= 0;					// Photon 剩余弹药
int		iShield		= 10;					// 剩余防护层
int		iAttack		= 0;					// 额外攻击力

int		iLevel		= 0;					// 当前关数
int		ShootChance	= 0;					// 敌人开火几率
int		inc			= 0;

void DrawFPS();
bool InitEngine(HWND hWnd);						// 初始化引擎设备
void InitLevel();
void UpdateFrame();
void ShowMenu();
void ShowCredits();
void ShowHelp();
void DrawBkgnd();
void DrawStatus();
void DrawShip();
void DrawBullet();
bool DrawUFO();
bool DrawExtra();
void ProcessInput();
void HitTest();
//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: 主窗口消息处理
//-----------------------------------------------------------------------------
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch( message )
    {
    case WM_ACTIVATE:		//应用程序激活消息
		if(LOWORD(wParam)==WA_INACTIVE)
			bActive = false;
		else if(HIWORD(wParam))
		{
			bActive = false;
			return 0;
		}
		else
			bActive = true;
        return 0;

	case WM_SYSKEYDOWN:
		switch(wParam)
		{
			case VK_F4:
				RunGame=false;
				break;
			case VK_RETURN:
				Engine.ChangeDisplayMode(Engine.GetScreenSize()->cx,Engine.GetScreenSize()->cy,!Engine.IsFullScreen());
				break;
			case 18:
				return 0;
		}
		break;

    case WM_SETCURSOR:
		if(Engine.IsFullScreen())
			SetCursor(NULL);
		else
			SetCursor(LoadCursor(NULL, IDC_ARROW));
		return TRUE;

	case WM_SIZE:
	case WM_MOVE:
		Engine.CalcWindowPos();
		break;
    case WM_KEYDOWN:		//击键消息
        switch( wParam )
        {
		case VK_F1:
			Engine.ChangeDisplayMode(Engine.GetScreenSize()->cx,Engine.GetScreenSize()->cy,!Engine.IsFullScreen());
			break;
		case VK_F12:
			{
				static int index=1;
				char str[20];
				sprintf(str,"ScreenShot%d.bmp",index++);
				Engine.SaveScreen(str);
			}
			break;
        }
        break;

    case WM_DESTROY:		//销毁窗口消息
        PostQuitMessage(0);
		RunGame=false;
        break;
    }
	//调用缺省的过程处理过程
    return DefWindowProc(hWnd, message, wParam, lParam);
}

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 初始化, 消息循环
//-----------------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    HWND hWnd;
    WNDCLASSEX wcex={0};

    //建立并注册窗口类
	wcex.cbSize=sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WinProc;
	wcex.hInstance=hInstance;
	wcex.lpszClassName = NAME;
	wcex.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_XINVADER));

	RegisterClassEx(&wcex);
    //创建窗口
    hWnd = CreateWindowEx(WS_EX_APPWINDOW,NAME,NAME,WS_OVERLAPPEDWINDOW | WS_VISIBLE,0,0,GetSystemMetrics(SM_CXSCREEN)/2,GetSystemMetrics(SM_CYSCREEN)/2,NULL,NULL,hInstance,NULL);
    if (!hWnd)
	{
		UnregisterClass(NAME,hInstance);
		MessageBox(hWnd,"程序主框架创建失败!",NAME,MB_OK);
        return FALSE;
	}

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	if(!InitEngine(hWnd))
	{
		MessageBox(hWnd,"游戏引擎初始化失败!",NAME,MB_OK);
		return false;
	}

	// Main message loop:
	while(RunGame)
	{
		//如果有消息则截获它
		if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				RunGame=false;

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else if(bActive)
		{
			UpdateFrame();
		}
	}

	return msg.wParam;
}

bool InitEngine(HWND hWnd)
{
	if(!Engine.Create(hWnd,640,480,16,true))
		return false;

	CMD_File	file;
	int			len=0;
	LPBYTE		buf=NULL;
	if(!file.Open("xipres.pak",true,true))
		return false;
	len=file.GetPackFileInfo("xinvader.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"xinvader.bmp"))
		return false;
	if(!sur_menu.Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("backgnd.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"backgnd.bmp"))
		return false;
	if(!sur_bkgnd.Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("alphabet.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"alphabet.bmp"))
		return false;
	if(!sur_Alphabet.Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("extras.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"extras.bmp"))
		return false;
	if(!sur_Extras.Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("ship.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"ship.bmp"))
		return false;
	if(!sur_Ship.Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("bullet.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"bullet.bmp"))
		return false;
	if(!sur_Bullet.Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("ufo1.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"ufo1.bmp"))
		return false;
	if(!sur_Ufo[0].Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("ufo2.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"ufo2.bmp"))
		return false;
	if(!sur_Ufo[1].Create(buf,0))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("ufo3.bmp")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"ufo3.bmp"))
		return false;
	if(!sur_Ufo[2].Create(buf,0))
		return false;
	SAFE_DELETE(buf);


	if(!Input.Create(hWnd,INPUT_KEYBOARD))
		return false;

	if(!Audio.Create(hWnd))
		return false;

	if(!file.Open("xisres.pak",true,true))
		return false;

	len=file.GetPackFileInfo("sel.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"sel.wav"))
		return false;
	if(!snd_sel.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("stop.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"stop.wav"))
		return false;
	if(!snd_stop.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("sfire.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"sfire.wav"))
		return false;
	if(!snd_sfire.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("ufire.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"ufire.wav"))
		return false;
	if(!snd_ufire.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("explode.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"explode.wav"))
		return false;
	if(!snd_explode.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("extras.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"extras.wav"))
		return false;
	if(!snd_extra.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("gameover.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"gameover.wav"))
		return false;
	if(!snd_gameover.Create(buf,len))
		return false;
	SAFE_DELETE(buf);

	len=file.GetPackFileInfo("level.wav")->length;
	buf=new BYTE[len];
	if(!file.ReadFromPackage(buf,"level.wav"))
		return false;
	if(!snd_level.Create(buf,len))
		return false;
	SAFE_DELETE(buf);


	srand(GetTickCount());
	return true;
}

void InitLevel()
{
	inc=iLevel/6+1;			// UFO移动速度, UFO防御力

	for(int i=0;i<MAX_BULLET;i++)
	{
  		m_Bullet[i].type=0;
		m_Bullet[i].frame=0;
	}
	for(i=0;i<MAX_UFO;i++)
	{
		m_UFO[i].type=_UFO_DIED_;
		m_UFO[i].shield=inc;
		m_UFO[i].inc=inc;
		m_UFO[i].frame=rand()%49;
	}
	for(i=0;i<MAX_EXTRA;i++)
	{
		m_Extra[i].type=0;
		m_Extra[i].frame=rand()%18;
	}

	sur_UfoN=&sur_Ufo[0];
	iShipPos = 285;
	iShipMov = 0;
	if((ShootChance = 180 - (40 * (iLevel / 7)))<50)
		ShootChance = 50;

	switch(iLevel%6)
	{
	case 0:
		for(i=0;i<5;i++)
		{
			m_UFO[i].type=_UFO_1_;
			m_UFO[i].move=0;
			m_UFO[i].x=550-(abs(i-2)*30);
			m_UFO[i].y=(i*65)+10;
		}
		for(i=5;i<10;i++)
		{
			m_UFO[i]=m_UFO[i-5];
			m_UFO[i].x=640-m_UFO[i-5].x-70;
			m_UFO[i].inc=-inc;
		}
		break;
	case 1:
		for(i=0;i<5;i++)
		{
			m_UFO[i].type=_UFO_1_;
			m_UFO[i].x=20+i*30;
			m_UFO[i].y=(i*65)+10;
			m_UFO[i].move=0;
			m_UFO[5+i].type=_UFO_1_;
			m_UFO[5+i].x=550-i*30;
			m_UFO[5+i].y=(i*65)+10;
			m_UFO[5+i].move=0;
			m_UFO[5+i].inc=-inc;
		}
		break;
	case 2:
		for(i=0;i<24;i++)
		{
			m_UFO[i].type=_UFO_1_;
			m_UFO[i].x=5+i%8*80;
			m_UFO[i].y=i/8*80+10;
			m_UFO[i].move=1;
			if((i/8)%2==0)
				m_UFO[i].inc=-inc;
		}
		break;
	case 3:
		sur_UfoN=&sur_Ufo[1];
		for(i=0;i<5;i++)
			m_UFO[i].type=_UFO_2_;
		m_UFO[0].x=200;
		m_UFO[0].y=20;
		m_UFO[0].move=6;
		m_UFO[1].x=180;
		m_UFO[1].y=180;
		m_UFO[1].move=6;
		m_UFO[2].x=530;
		m_UFO[2].y=110;
		m_UFO[2].move=5;
		m_UFO[3].x=100;
		m_UFO[3].y=100;
		m_UFO[3].move=6;
		m_UFO[4].x=450;
		m_UFO[4].y=190;
		m_UFO[4].move=5;
		break;
	case 4:
		sur_UfoN=&sur_Ufo[1];
		for(i=0;i<6;i++)
			m_UFO[i].type=_UFO_2_;
		m_UFO[0].x=20;
		m_UFO[0].y=20;
		m_UFO[0].move=3;
		m_UFO[1].x=110;
		m_UFO[1].y=90;
		m_UFO[1].move=6;
		m_UFO[2].x=20;
		m_UFO[2].y=160;
		m_UFO[2].move=6;
		m_UFO[3].x=540;
		m_UFO[3].y=20;
		m_UFO[3].move=4;
		m_UFO[4].x=470;
		m_UFO[4].y=90;
		m_UFO[4].move=5;
		m_UFO[5].x=540;
		m_UFO[5].y=160;
		m_UFO[5].move=5;

		break;
	case 5:
		sur_UfoN=&sur_Ufo[2];
		for(i=0;i<6;i++)
		{
			m_UFO[i].type=_UFO_3_;
			m_UFO[i].move=7;
		}
		m_UFO[0].x=20;
		m_UFO[0].y=20;
		m_UFO[1].x=90;
		m_UFO[1].y=90;
		m_UFO[2].x=20;
		m_UFO[2].y=160;
		m_UFO[3].x=540;
		m_UFO[3].inc=-m_UFO[3].inc;
		m_UFO[3].y=20;
		m_UFO[4].x=470;
		m_UFO[4].y=90;
		m_UFO[4].inc=-m_UFO[4].inc;
		m_UFO[5].x=540;
		m_UFO[5].y=160;
		m_UFO[5].inc=-m_UFO[5].inc;
		break;
	}
	iLevel++;
	snd_level.Play();
}

void UpdateFrame()
{
	static int nt=0,ot=0;		//////////////////////////
	nt=GetTickCount();			//						//
	if(nt<ot+18)				//		帧速限制50FPS	//
		return;					//						//
	ot=nt;						//////////////////////////

	Engine.FlipScreen();
	switch(m_State)
	{
	case G_MENU:
		ShowMenu();
		break;
	case G_RUN:
		{
			ProcessInput();		// 处理玩家输入
			DrawBkgnd();		// 绘制背景
			bool a=DrawUFO();	// 绘制敌方UFO 
			bool b=DrawExtra();	// 绘制物品
			DrawBullet();		// 绘制子弹
			DrawShip();			// 绘制玩家飞船
			DrawStatus();		// 绘制状态
			HitTest();			// 撞击测试
			if(iShield<=0 && iShipframe>20)
			{
				m_State=G_GAMEOVER;
				Timer.Reset();
				TimerTP.Reset();
				snd_gameover.Play();
			}
			if(a && b)
			{
				InitLevel();
				Timer.Reset();
				TimerTP.Reset();
				m_State=G_LEVEL;
			}
		}
		break;
	case G_CREDITS:
		ShowCredits();
		break;
	case G_HELP:
		ShowHelp();
		break;
	case G_LEVEL:
		{
			char str[10]={'L','E','V','E','L',' '};
			str[6]=iLevel/100+'0';
			str[7]=iLevel%100/10+'0';
			str[8]=iLevel%10+'0';
			str[9]='\0';

⌨️ 快捷键说明

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