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

📄 game.cpp

📁 过程的c++编译器 里面有超级玛丽的源代码 还有一个 管理系统的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*********************************************
程序设计:罗穆峰  2008-11-20
http://lmf.biaotian.com
E-mail: lmf@biaotian.com
QQ: 16324942 [模范英雄]
*********************************************/

#include "Game.h"
#include "SoundMan.h"
#include "地图数据.h"
#include "Brick.h"
#include "Ground.h"
#include "Stone.h"
#include "PipeBody.h"
#include "PipeTop.h"
#include "Question.h"
#include "FungusDemon.h"
#include "TortoiseDemon.h"
#include "FlyTortoiseDemon.h"
#include "ClipDemon.h"
#include "BeetleDemon.h"
#include "Coin.h"
#include <queue>

int g_FlushAction=0;//问号和金币当前的闪烁状态。所有问号的金币的闪烁状态是一致的。取值为0~2。
static int s_FlushTimeCount=0;//并非每个时钟周期闪烁一次,而是要等到该变量记录到一定值后再改变一次闪烁状态。
static int s_FlushDir;//当前的闪烁方向。1:由亮变暗 2:由暗变亮

CGame::CGame()
{
	m_Mario=NULL;
}

const std::set<CObject*> * CGame::GetAllObject()
{
/*
	返回所有角色和物体的列表。返回NULL表示游戏尚未开始。
*/
	if(!m_Mario)return NULL;//游戏尚未开始
	return &m_Object;
}

void CGame::Start()
{
/*
	开始游戏。
*/
	if(m_Mario)return;//游戏已经开始,则不再响应该事件

	//清除所有角色和物体
	std::set<CObject*>::iterator it;
	for(it=m_Object.begin();it!=m_Object.end();++it)
	{
		delete *it;
	}
	m_Object.clear();

	//创建主角玛莉
	m_Mario=new CMario(this,0,0,1);
	m_Object.insert(m_Mario);

	//从第0关开始
	m_CurLevel=0;
	m_MapData=MapData+1;
	LoadMapData();
}

void CGame::InsertObject(int X,int Y,int Type)
{
/*
	插入一个新角色或物体。
	参数:
		[i]X,Y		要插入到哪个位置。
		[i]Type		要插入的物体类型。取值为:
			1		砖块。
			2		石头。
			3		水管体。
			4		水管顶。
			5		问号(内藏一枚金币)。
			6		问号(内藏蘑菇)。
			7		问号(内藏十枚金币)。
			8		砖块(内藏蘑菇)。
			9		砖块(内藏五星)。
			10		砖块(内藏十枚金币)。
			11		蘑菇妖怪。
			12		乌龟妖怪。
			13		飞乌龟妖怪。
			14		夹子妖怪。
			15		地板。
			16		金币。
			17		甲虫妖怪。
*/
	switch(Type)
	{
	case 1:
		m_Object.insert(new CBrick(this,X,Y,0));
		break;
	case 2:
		m_Object.insert(new CStone(this,X,Y));
		break;
	case 3:
		m_Object.insert(new CPipeBody(this,X,Y));
		break;
	case 4:
		m_Object.insert(new CPipeTop(this,X,Y));
		break;
	case 5:
		m_Object.insert(new CQuestion(this,X,Y,3));
		break;
	case 6:
		m_Object.insert(new CQuestion(this,X,Y,1));
		break;
	case 7:
		m_Object.insert(new CQuestion(this,X,Y,2));
		break;
	case 8:
		m_Object.insert(new CBrick(this,X,Y,1));
		break;
	case 9:
		m_Object.insert(new CBrick(this,X,Y,3));
		break;
	case 10:
		m_Object.insert(new CBrick(this,X,Y,2));
		break;
	case 11:
		m_Object.insert(new CFungusDemon(this,X,Y));
		break;
	case 12:
		m_Object.insert(new CTortoiseDemon(this,X,Y));
		break;
	case 13:
		m_Object.insert(new CFlyTortoiseDemon(this,X,Y));
		break;
	case 14:
		m_Object.insert(new CClipDemon(this,X,Y));
		break;
	case 15:
		m_Object.insert(new CGround(this,X,Y));
		break;
	case 16:
		m_Object.insert(new CCoin(this,X,Y));
		break;
	case 17:
		m_Object.insert(new CBeetleDemon(this,X,Y));
		break;
	}
}

void CGame::Clock(void)
{
/*
	执行一次时序信号动作。
*/
	//改变问号和金币当前的闪烁状态
	s_FlushTimeCount++;
	switch(g_FlushAction)
	{
	case 0:
		if(s_FlushTimeCount>=10)
		{//最亮的状态显示10个时钟周期
			g_FlushAction=1;
			s_FlushDir=1;
			s_FlushTimeCount=0;
		}
		break;
	case 1:
		if(s_FlushTimeCount>=2)
		{//稍暗的状态显示2个时钟周期
			g_FlushAction+=s_FlushDir;
			s_FlushTimeCount=0;
		}
		break;
	default://case 2:
		if(s_FlushTimeCount>=3)
		{//最暗的状态显示3个时钟周期
			g_FlushAction=1;
			s_FlushDir=-1;
			s_FlushTimeCount=0;
		}
	}

	std::set<CObject*>::iterator it,it2;
	//使所有的角色和物体动作一次
	for(it=m_Object.begin();it!=m_Object.end();)
	{
		if(3==(*it)->LiveState||(*it)->XPos>288+32||(*it)->XPos+(*it)->Width<-32||(*it)->YPos>256)
		{//对象已死亡,则删除
			//左边线超出右边界32像素以上,左边线超出左边界32像素以上,上边线超出下边界,则认为对象超出地图范围之外,要删除该对象
			if(*it==m_Mario)
			{//删除的是玛莉
				if(1==m_Mario->LiveState)
				{//删除的是活玛莉,则要停止背景音乐,播放玛莉死亡时的音乐
					m_SoundMan->PlayBackMusic(0);
					m_SoundMan->PlaySound(CSoundMan::DEATH);
				}
				m_Mario=NULL;
			}
			it2=it;
			++it;
			delete *it2;
			m_Object.erase(it2);
		}
		else
		{
			(*it)->Clock();
			++it;
		}
	}
	if(!m_Mario)return;//玛莉已被删除
	int Offset=m_Mario->XPos-((288-m_Mario->Width)>>1);
	if(Offset>0)
	{//玛莉超过了地图中线,则要将地图移动,使玛莉到达地图中央
		MoveMap(Offset);
	}
	if(m_Mario->XPos==288-m_Mario->Width)
	{//玛莉到达了地图右边线,则进入下一关
		//清除除玛莉外的所有角色和物体
		for(it=m_Object.begin();it!=m_Object.end();)
		{
			it2=it;
			it++;
			if(*it2==m_Mario)continue;//玛莉不能删除
			delete *it2;
			m_Object.erase(it2);
		}

		m_CurLevel++;
		if(MapData[0]==m_CurLevel)
		{//已经玩过了最后一关,则游戏结束
			m_SoundMan->PlayBackMusic(0);
			//删除玛莉
			m_Object.clear();
			delete m_Mario;
			m_Mario=NULL;
		}
		else
		{
			m_MapData+=3+m_MapData[2]*16;
			LoadMapData();
		}
	}
}

void CGame::Move(int Dir, bool Acc)
{
/*
	使主角开始或停止移动。
	参数:
		[i]Dir	移动方向。取值为:
				1	向上
				2	向下
				3	向左
				4	向右
				0	停止
		[i]Acc	是否加速移动。
*/
	if(!m_Mario)return;//游戏尚未开始
	m_Mario->Move(Dir,Acc);
}

void CGame::Jump(void)
{
/*
	使主角跳跃一次。
*/
	if(!m_Mario)return;//游戏尚未开始
	m_Mario->Jump();
}

void CGame::Fire(void)
{
/*
	使主角发射一次子弹。
*/
	if(!m_Mario)return;//游戏尚未开始
	m_Mario->Fire();
}

struct BLOCKINFO
{//移动路径内的阻挡物信息
	CObject * Blocker;//阻挡本对象运动的物体
	int x,y;//受该物体阻挡后能运动到的位置
	int BlockMode;//阻挡方式,取值与本函数的返回值一致。当MayBe为true时,忽略该成员
	int BumpMode;//与该物体的碰撞方式,取值取CObject::Bump函数的中Mode参数一致。当MayBe为true时,忽略该成员
	bool MayBe;//如果阻挡物刚好在运动区域的边界上,则可能阻挡,也可能不阻挡
};

struct BLOCKINFOCompare
{//BLOCKINFO的比较器,若b距离被阻挡物较近,则返回true。
	//以X坐标较近为准,若X值相同则以Y较近为准,若Y值也相同,则以一定阻挡的物体为准
	//不可能出现X较近而Y值较远的情况
	bool operator() (const BLOCKINFO & a,const BLOCKINFO & b)
	{
		if(XLarge)
		{
			if(b.x>a.x)return true;
			if(b.x<a.x)return false;
		}
		else
		{
			if(b.x<a.x)return true;
			if(b.x>a.x)return false;
		}
		if(YLarge)
		{
			if(b.y>a.y)return true;
			if(b.y<a.y)return false;
		}
		else
		{
			if(b.y<a.y)return true;
			if(b.y>a.y)return false;
		}
		if(!b.MayBe&&a.MayBe)return true;
		return false;
	}
	bool XLarge;//若为true,则X值越大则越近,否则X值小越近
	bool YLarge;//若为true,则Y值越大则越近,否则Y值小越近
};

int CGame::Move(CObject * Obj,int Horz,int Vert)
{
/*
	移动某个角色或物体。
	参数:
		[i]Obje		要移动的对象。
		[i]Horz		要移动的水平距离(像素),向右为正,向左为负。
		[i]Vert		要移动的竖直距离(像素),向下为正,向上为负。
	返回值:
		返回一个位段值。以下各值可用位或合并。
		0	成功。
		1	水平方向遇到阻挡。
		2	竖直方向遇到阻挡。
*/
	int retval=0;

	//如果没有阻挡,应该移动到的位置
	int OrDestX=Obj->XPos+Horz;
	int OrDestY=Obj->YPos+Vert;

	BLOCKINFOCompare Compare;
	BLOCKINFO bi;
	if(Vert>0)
	{//向下移动,则Y值越小越近
		Compare.YLarge=false;
	}
	else
	{//向上移动,则Y值越大越近
		Compare.YLarge=true;
	}
	if(Horz>0)
	{//向右移动,则X值越小越近
		Compare.XLarge=false;

⌨️ 快捷键说明

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