📄 terrscene.h
字号:
//-----------------------------------------------------------------------------
// 世界场景管理
// 李亦.2006.5.26
//-----------------------------------------------------------------------------
#ifndef _TERRSCENE_H_
#define _TERRSCENE_H_
#ifndef _PLATFORM_H_
#include "platform/platform.h"
#endif
#ifndef _RESMANAGER_H_
#include "core/resManager.h"
#endif
#ifndef _RESMANAGER_H_
#include "core/resManager.h"
#endif
#ifndef _PLATFORMMEMPOOL_H_
#include "platform/platformMemPool.h"
#endif
class TerrainBlock;
struct SceneEntry
{
StringTableEntry pSceneName; //场景名称
S16 nDestX; //目标坐标
S16 nDestY;
//U32 uType; //出入口类型,可选不同风格的出入口,在uFlags标注
};
struct SceneGrid
{
public:
S16 x;
S16 y; //所在世界坐标,原点在左上角
U32 uFlags; //单元标志
U32 uMouse; //光标类型
SceneGrid* pNext; /// Hash表的Next指针
union
{
U32 dwData; //数据
StringTableEntry pScriptFuncName; //将触发的函数名,只传递x,y,玩家ID
SceneEntry sceEntry;
} unData;
//DECLARE_FIXEDSIZE_ALLOCATOR(SceneGrid);
};
//--------------------------------------
/// TGE_TerrainScene
class TerrainScene : public ResourceInstance
{
/// 地形格单元标志组合,采用一对一关联,1个单元格对1个U8,
/// 这样,最大情况下占用内存可能是 256*256*8*8 = 4M
/// 原考虑1个单元对1个Bit(1U8对8个单元),由因障碍检测频繁,
/// 而且4M也不是很夸张;Client只是一个世界图,而Server端可能最多20,即20*4=80M
/// 就算50*4=200也只是200M,1条1G内存就能满足。
/// 现在考虑,通过U8标志组合;检测到Trap、Entry时,再检测Hash表,因为量极少;
/// 而障碍标志直接写在U8,索引存取速度快多了。
public:
enum Constants
{
FILE_VERSION = 1
};
enum GridType
{
BALK_WALK = 0x1, //步行障碍
BALK_JUMP = 0x2, //跳越障碍
BALK_FLY = 0x4, //飞越障碍
BALK_SELF = 0x8, //人物自己障碍
BALK_ALL = BALK_WALK | BALK_JUMP | BALK_FLY | BALK_SELF ,
GT_TRAP = 0x10, //触发器
GT_ENTRY = 0x20, //出入口区域
//GT_OWNER = 0x80, //区域的宿主,须关联相应的数据,如trap数据等;
//非宿主数据,只需要填充与宿主的偏移量即可;
};
TerrainScene();
~TerrainScene();
void initScene(TerrainBlock*);
bool isBlockAt(U32 x, U32 y);
void setWalkBlockAt(U32 x, U32 y,bool bSet=true);
void setSelfBlockAt(U32 x, U32 y,bool bSet=true);
void setBlockAt(U32 x, U32 y,const U32 uFlags);
U32 getBlockAt(U32 x, U32 y);
bool canWalkAt(U32 x, U32 y);
bool save(const char *filename);
bool read(Stream &stream);
void freeData();
U32 hashIndex(S32 x, S32 y);
SceneGrid* getGridAt(S32 x, S32 y);
SceneGrid* setGridAt(S32 x, S32 y,U8 cFlags);
U32 GetWidth();
U32 GetHeight();
protected:
U8* m_pGridFlagBase;
U8** m_pGridFlagRows; /// 地形格行头列表
SceneGrid** m_pGridHashTable; //Grid的Hash表;跨度为squareSize * blockSize
U32 m_nSceneWidth; //场景宽度,格子数
U32 m_nScenePitch; //场景跨度,格子数,4对齐
U32 m_nSceneHeight;
U32 m_uHashMask; //hash掩位值,为数较少,默认为255
};
/////////////////////////////////////////////////////
inline U32 TerrainScene::GetWidth()
{
return m_nSceneWidth;
}
inline U32 TerrainScene::GetHeight()
{
return m_nSceneHeight;
}
inline SceneGrid* TerrainScene::getGridAt(S32 x, S32 y)
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(m_pGridFlagRows[y][x])
{
U32 nIndex = hashIndex(x,y);
for(SceneGrid* it = m_pGridHashTable[nIndex]; it != 0; it = it->pNext)
if(it->x == x && it->y == y)
return it;
}
return 0;
}
inline U32 TerrainScene::hashIndex(S32 x, S32 y)
{
return (y*m_nSceneWidth + x) & m_uHashMask;
}
inline bool TerrainScene::isBlockAt(U32 x, U32 y)
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(x > m_nSceneWidth || y > m_nSceneHeight)
return false;
return m_pGridFlagRows[y][x] & BALK_ALL;
}
inline void TerrainScene::setWalkBlockAt(U32 x, U32 y,bool bSet)
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(x > m_nSceneWidth || y > m_nSceneHeight)
return;
if(bSet)
m_pGridFlagRows[y][x] |= BALK_WALK;
else
m_pGridFlagRows[y][x] &= ~BALK_WALK;
}
inline void TerrainScene::setSelfBlockAt(U32 x, U32 y,bool bSet)
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(x > m_nSceneWidth || y > m_nSceneHeight)
return;
if(bSet)
m_pGridFlagRows[y][x] |= BALK_SELF;
else
m_pGridFlagRows[y][x] &= ~BALK_SELF;
}
inline void TerrainScene::setBlockAt(U32 x, U32 y,const U32 uFlags)
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(x > m_nSceneWidth || y > m_nSceneHeight)
return;
m_pGridFlagRows[y][x] = uFlags;
}
inline U32 TerrainScene::getBlockAt(U32 x, U32 y )
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(x > m_nSceneWidth || y > m_nSceneHeight)
return 0;
return m_pGridFlagRows[y][x];
}
inline bool TerrainScene::canWalkAt(U32 x, U32 y)
{
AssertWarn(m_pGridFlagRows && m_pGridFlagRows[y],"标志列表未分配空间");
if(x > m_nSceneWidth || y > m_nSceneHeight)
return false;
return (m_pGridFlagRows[y][x] & BALK_ALL) == 0;
}
extern ResourceInstance *constructTerrainScene(Stream &stream);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -