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

📄 gscene.cpp

📁 RPG游戏源代码,里面有RPG游戏的制作流程,供大家学习如何制作RPG游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
// GScene.cpp: implementation of the CGScene class.
// RPGDemo框架程序	场景类
// written by 萧萧落木(Roc.j.Wood)
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GScene.h"

#include <fstream.h>

#include <algorithm>
#include <string>
#include <functional>
using namespace std;

struct COMPARE_ROLEPOS_LESS : public binary_function<LPCGRole, LPCGRole, bool> {
	bool operator()(LPCGRole r1, LPCGRole r2)
	{ 
		if(r1==NULL) return false;
		if(r2==NULL) return true;
		
		static int x1,x2,y1,y2,lv1,lv2;

		lv1=r1->GetLevel();
		lv2=r2->GetLevel();
		
		if(lv1==lv2)
		{
			r1->GetMapPos(x1,y1);
			r2->GetMapPos(x2,y2);
			return y1<y2;
		}
		return lv1<lv2;
	}
};

HRESULT CGSceneLayer::RenderLayer(CGAFDDrawSurface &gDDSurface, LONG XOff, LONG YOff)
{
	assert(RectCount==0||(RectCount>0&&pRectArray));
	for(int i=0;i<RectCount;i++)
	{
		LONG lX=pRectArray[i].left+XOff;
		LONG lY=pRectArray[i].top+YOff;
		HRESULT hr=gDDSurface.BltFastTo(GAFDDraw.GetBack(),lX,lY,FALSE,pRectArray+i,TRUE);
		TESTHR_RET(hr);
	}
	return S_OK;
}

#pragma pack(push,1)
struct WORDRECT
{
	WORD    Left;
	WORD    Top;
	WORD    Width;
	WORD    Height;
};
#pragma pack(pop)

HRESULT CGSceneLayer::LoadLayer(::fstream &fs)
{
	ClearLayer();
	try
	{
		fs.read((CHAR*)(&RectCount),sizeof(DWORD));
		if(RectCount>0)
		{
			pRectArray = new RECT[RectCount];
			if(pRectArray==NULL) throw;		
		}
		for(int i=0;i<RectCount;i++)
		{
			WORDRECT rt;
			fs.read((CHAR*)(&rt),sizeof(WORDRECT));
			pRectArray[i].left=rt.Left;
			pRectArray[i].top=rt.Top;
			pRectArray[i].right=rt.Left+rt.Width;
			pRectArray[i].bottom=rt.Top+rt.Height;
		}
	}
	catch(...)
	{
		ClearLayer();
		return E_FAIL;
	}
	return S_OK;
}

CGScene::CGScene(CRPGGame *pGameApp)
{
	assert(pGameApp);
	m_pGameApp = pGameApp;

	ScreenWidth		= GAFDDraw.GetBack()->GetWidth();
	ScreenHeight	= GAFDDraw.GetBack()->GetHeight();

	HCells	=
	VCells	=
	Width	=	
	Height	=
	XPosition	=
	YPosition	=
	ObjCount	=
	ExitCount	=
	RoleCount	=	0;

	memset(m_szName,0,16);
	memset(m_RoleArray,0,sizeof(LPCGRole)*CG_NUM_MAXROLEINSCENE);
	memset(m_ExitArray,0,sizeof(CGSceneExit)*CG_NUM_MAXEXITINSCENE);

	m_pMapInfo	=	NULL;
}

CGScene::~CGScene()
{
	FinalClearup();
}

HRESULT CGScene::LoadMAP(LPCTSTR szFileName)
{
	assert(szFileName);
	
	string fName;
	fName="SCENE\\";
	fName.append(szFileName);
	
	
	::fstream fs;
	fs.open(fName.c_str(),ios::in|ios::binary);
	if(fs.is_open()==FALSE)	return E_FAIL;

	try
	{
		DWORD MAPFLAG;
		DWORD MAPVER;
		fs.read((CHAR *)&MAPFLAG,4);
		fs.read((CHAR *)&MAPVER,4);
		if(MAPFLAG!=MAKEFOURCC('G','M','A','P')	|| MAPVER!=0x0101)	return -1;

		CHAR   GraphFName[32];
		fs.read(GraphFName,32);
		fName="SCENE\\";
		fName.append(GraphFName);
		HRESULT hr = m_gGraph.CreateByJPEG(&GAFDDraw,fName.c_str());
		TESTHR_RET(hr);

		LONG tmpWidth = m_gGraph.GetWidth();
		LONG tmpHeight= m_gGraph.GetHeight();
		fs.read((CHAR *)&Width,4);
		fs.read((CHAR *)&Height,4);
		if(tmpWidth!=Width || tmpHeight!=Height) return -2;

		MapToCell(tmpWidth,tmpHeight);
		SAFE_DELETE_ARRAY(m_pMapInfo);
		m_pMapInfo = new WORD[tmpWidth*tmpHeight];
		if(m_pMapInfo==NULL) return E_OUTOFMEMORY;
		fs.read((CHAR *)m_pMapInfo,tmpHeight*tmpWidth*sizeof(WORD));

		for(int Lv=0;Lv<256;Lv++)
		{
			hr = m_gSceneLayers[Lv].LoadLayer(fs);
			TESTHR_TRW(hr);
		}
	}
	catch(...)
	{
		fs.close();
		return E_FAIL;
	}

	fs.close();
	return S_OK;
}

#pragma pack(push,1)

struct SCNOBJECT
{
	WORD  X,Y;		//格子坐标(0..HCells-1,0..VCells-1)
	WORD  Idx;		//道具编号
	WORD  Enable;	//是否空箱子? 1表示有东西,0表示空了
};

struct SCNEXIT
{
	WORD X1,Y1,X2,Y2;	//出口出发区域(格子坐标)
	CHAR SCNName[32];	//对应的场景文件
	WORD TX,TY;			//切换场景以后在目标场景出现的格子坐标
};

struct SCNROLE
{
	WORD X,Y;			//站立的格子坐标
	WORD Dir;			//方向
	CHAR ROLName[32];  	//对应角色文件(*.ROL)
};

struct SCSNEFILEHEADRER
{
	DWORD	SCNFLAG;
	DWORD	Version;
	CHAR	szName[16];		//场景名称
	CHAR	szMapName[32];	//场景对应MAP文件名
	DWORD   Width;			//由对应的MAP文件设定
	DWORD   Height;			//由对应的MAP文件设定
	DWORD   HCells;			//Width/16,水平格子数(方格大小16*16)
	DWORD   VCells;			//Height/16,垂直格子数
};

#pragma pack(pop)

inline void LOADINGMSG(const string &Msg, DWORD DelayMS=50)
{
	GAFDDraw.GetBack()->Fill(0);
	GAFDDraw.GetBack()->TextXY(10,450,0xFFFFFF,(LPCTSTR)Msg.c_str());
	GAFDDraw.Present(TRUE,FALSE);
	Sleep(DelayMS);	
}

HRESULT CGScene::LoadScene(LPCTSTR szFileName)
{
	assert(szFileName);
	
	LOADINGMSG("清除残余角色列表...");
	ClearupROLEArray(FALSE);

	string fName;
	fName="SCENE\\";
	fName.append(szFileName);

	LOADINGMSG(string("打开场景文件")+fName+"...");

	::fstream fs;
	fs.open(fName.c_str(),ios::in|ios::binary);
	if(fs.is_open()==FALSE)	return E_FAIL;
	
	//装载场景文件
	try
	{
		SCSNEFILEHEADRER ScnFile;
		fs.read((CHAR*)&ScnFile,sizeof(ScnFile));

		if(ScnFile.SCNFLAG!=MAKEFOURCC('G','S','C','N')	|| ScnFile.Version!=0x0106)	return -1;
		
		memcpy(m_szName,ScnFile.szName,16);
		Width  = ScnFile.Width;
		Height = ScnFile.Height;
		HCells = ScnFile.HCells;
		VCells = ScnFile.VCells;
		
		LOADINGMSG(string("装入场景地图文件")+ScnFile.szMapName+"...",0);

		HRESULT hr;
		hr = LoadMAP(ScnFile.szMapName);
		TESTHR_RET(hr);
	

		int i;

		//装入道具列表
		LOADINGMSG("装入道具列表设定...");
		fs.read((CHAR*)&ObjCount,4);
		assert(ObjCount==0);

		//装入出口列表
		LOADINGMSG("装入场景出口列表设定...");
		fs.read((CHAR*)&ExitCount,4);
		for(i=0;i<ExitCount;i++)
		{
			SCNEXIT exit;
			fs.read((CHAR*)&exit,sizeof(SCNEXIT));
			m_ExitArray[i].Enable=TRUE;
			m_ExitArray[i].TX=exit.TX;
			m_ExitArray[i].TY=exit.TY;
			memcpy(m_ExitArray[i].TargetScene,exit.SCNName,32);
			SetRect(&(m_ExitArray[i].rt),exit.X1*16,exit.Y1*16,exit.X2*16,exit.Y2*16);
		}

		//装入角色列表
		LOADINGMSG("装入角色列表设定...");
		LONG Count;
		fs.read((CHAR*)(&Count),4);
		for(i=0;i<Count;i++)
		{
			SCNROLE rol;
			fs.read((CHAR*)(&rol),sizeof(SCNROLE));
			hr = AddNewRole(rol.ROLName,rol.X,rol.Y,rol.Dir);
			TESTHR_MSGTRW(hr,"CGScene场景装入角色出错!");
		}
	}
	catch(...)
	{
		fs.close();
		return E_FAIL;
	}

	fs.close();

	LOADINGMSG("场景装入成功,进入场景模式...",200);

	return S_OK;
}

void CGScene::FinalClearup()
{
	m_pGameApp = NULL;
	memset(m_szName,0,16);
	ClearupROLEArray(TRUE);
	SAFE_DELETE_ARRAY(m_pMapInfo);
}


void CGScene::SortRoleList()
{
	BOOL Flag=TRUE;
	while(Flag)
	{
		static COMPARE_ROLEPOS_LESS _CompareFunc;
		Flag=FALSE;
		for(int i=CG_NUM_MAXROLEINSCENE-1;i>0;i--)
		{
			if(_CompareFunc(m_RoleArray[i],m_RoleArray[i-1]))
			{
				swap(m_RoleArray[i],m_RoleArray[i-1]);
				Flag=TRUE;
			}
		}
	}
}

HRESULT CGScene::RenderScene()
{
	LONG XOff=-XPosition;
	LONG YOff=-YPosition;
	
	GAFDDraw.GetBack()->Fill(0);
	
	//给所有角色按照层次信息和y坐标递增排序
	SortRoleList();
	
	int roleidx=0;
	for(SHORT Level=0;Level<256;Level+=2)	//一次渲染成组的2个层
	{
		//渲染第Level层道具箱
		//未完成
		
		//渲染第Level层景物
		m_gSceneLayers[Level].RenderLayer(m_gGraph,XOff,YOff);	
			
		//渲染第Level层角色
		for(;roleidx<RoleCount;roleidx++)
			if(m_RoleArray[roleidx])

⌨️ 快捷键说明

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