namespace MG
{
/// <summary>
/// 地图
/// </summary>
public class Map : IDisposable
{
public Map()
{
for (int i = 0; i < 8; i++)
{
m_bAniTileFrame[i] = new byte[16];
}
}
/// <summary>
/// 读取地图
/// </summary>
/// <param name="filename">地图文件名</param>
/// <returns>MapFile</returns>
public static MapFile ReadMapFile(string filename)
{
MapFile MF;
MapFileHeader mapheader;
MapGround[,] mglist;
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fs))
{
br.BaseStream.Seek(20, SeekOrigin.Begin);
mapheader.shVer = br.ReadUInt16();
mapheader.shWidth = br.ReadUInt16();
mapheader.shHeight = br.ReadUInt16();
mapheader.cEventFileIdx = (char)br.ReadByte();
mapheader.cFogColor = (char)br.ReadByte();
ushort groundwidth = (ushort)(mapheader.shWidth / 2);
ushort groundheight = (ushort)(mapheader.shHeight / 2);
MF.MapHeader = mapheader;
mglist = new MapGround[groundwidth, groundheight];
//读取小地图(背景)所有瓷砖的结构(构造地面最底层的)
MapGround mg;
for (int w = 0; w < groundwidth; w++)
{
for (int h = 0; h < groundheight; h++)
{
mg.cFileIdx = (char)br.ReadByte();
mg.shTileIdx = br.ReadUInt16();
mglist[w, h] = mg;
}
}
MF.MGList = mglist;
//读取大地图(单元格信息,地面物件对象)的结构(构造基于地面的建筑,树木,动画等的)
CellInfor[,] CellInfors = new CellInfor[mapheader.shWidth, mapheader.shHeight];
CellInfor ci;
for (int w = 0; w < mapheader.shWidth; w++)
{
for (int h = 0; h < mapheader.shHeight; h++)
{
ci.bFlag = br.ReadByte();
ci.bObj1Ani = br.ReadByte();
ci.bObj2Ani = br.ReadByte();
ci.bFileIdx = br.ReadInt16();
ci.wObj1 = br.ReadUInt16();
ci.wObj2 = br.ReadUInt16();
ci.bDoorIdx = br.ReadUInt16();
ci.bDoorOffset = br.ReadByte();
ci.wLigntNEvent = br.ReadUInt16();
CellInfors[w, h] = ci;
}
}
MF.CellInfors = CellInfors;
br.Close();
}
}
return MF;
}
int dwLastTime, dwTime, dwDelay = 0; //用于纪录最后时间,时间,延时等数据的全局变量初值为0
/// <summary>
/// 画出地图
/// </summary>
/// <param name="nX">横坐标</param>
/// <param name="nY">从坐标</param>
/// <param name="brush2d">画笔</param>
public void DrawMap(int nX, int nY, Brush brush2d)
{
dwTime = DateTime.Now.Millisecond; //获取系统当前消息循环的滴答数
dwDelay = dwTime - dwLastTime; //当前消息循环滴答数减去上一次的消息循环的滴答数为两次消息处理的延时间隔。
dwLastTime = dwTime; //保存当前滴答数为最近一次消息循环的时间//渲染地图上的物体
//if (dwDelay != 0)
//{
SetAniTileFrame(dwDelay); //设置地图上的动画帧
DrawGround(nX, nY, brush2d);
DrawMapCell(nX, nY, brush2d);
//绘制开门
//DrawOpenDoor(nX, nY);
//}
}
/// <summary>
/// 地表元素
/// </summary>
public class MapElement : FaceImage
{
public MapElement(int x, int y, int width, int height)
: base(Game.Current.dev, width, height, Format.R5G6B5)
{
X = x;
Y = y;
}
/// <summary>
/// 标识地图上的坐标点
/// </summary>
public int X, Y;
}
/// <summary>
/// 地面对象
/// </summary>
public class MapObjects : FaceImage
{
public MapObjects(int x, int y, byte layerIndex, int width, int height)
: base(Game.Current.dev, width, height, Format.A8R8G8B8)
{
X = x;
Y = y;
LayerIndex = layerIndex;
}
public byte LayerIndex;
/// <summary>
/// 标识地图上的坐标点
/// </summary>
public int X, Y;
}
/// <summary>
/// 移动像素数目列表
/// </summary>
Point[] MovePixelArray = new Point[] { new Point(8, 5), new Point(16, 11), new Point(24, 16), new Point(32, 21), new Point(40, 27), new Point(48, 32) };
/// <summary>
/// 视图区的地图(地表)块索引
/// </summary>
List<MapElement> GroundViewBuffer = new List<MapElement>();
/// <summary>
/// 视图区的地图(物体)的索引
/// </summary>
List<MapObjects> ObjectViewBuffer = new List<MapObjects>();
//public ushort[,] ViewBuffer = new ushort[11, 12];
//public ushort[,] ViewMap=new ushort
//public FaceImage MapImage = new FaceImage(Game.Current.dev, 1024, 1024) { Location_Draw = new Point(96, 64) };
//public static implicit operator Texture(Map map)
//{
// return map.MapImage;
//}
//public Rectangle DrawRectangle { get { return new Rectangle(MapImage.Location_Draw, Game.Window.ClientSize); } }
//Originaldata
//
//1008width 21
//736height 23
//BufferData
//1024width
//1024height
/// <summary>
/// 当前的地图文件
/// </summary>
public static MapFile Current { get; set; }
/// <summary>
/// 删除地表图片的临时存储区
/// </summary>
public List<MapElement> TempDeleteGroundViewBuffer = new List<MapElement>();
/// <summary>
/// 删除地面对象的临时缓冲区
/// </summary>
public List<MapObjects> TempDeleteObjectViewBuffer = new List<MapObjects>();
/// <summary>
/// 画出地表元素
/// </summary>
/// <param name="nX">横坐标</param>
/// <param name="nY">纵坐标</param>
/// <param name="brush2d">2D画笔</param>
public void DrawGround(int nX, int nY, Brush brush2d)
{
//是否查过了地图边界
if (nX > Current.MapHeader.shWidth - _showWidthCellCount || nX < 0 || nY > Current.MapHeader.shHeight - _showHeightCellCount || nY < 0)
{
return;
}
//过滤超出缓冲范围的图像数据
foreach (MapElement grd in GroundViewBuffer)
{
if (grd.X < nX / 2 || grd.X > (nX + _bufferWidthCellCount) / 2 || grd.Y < nY / 2f || grd.Y > (nY + _bufferHeightCellCount) / 2)
{
TempDeleteGroundViewBuffer.Add(grd);
}
}
foreach (MapElement grd in TempDeleteGroundViewBuffer)
{
GroundViewBuffer.Remove(grd);
grd.Dispose();
}
if (TempDeleteGroundViewBuffer.Count > 0)
TempDeleteGroundViewBuffer.Clear();
for (int y = 0; y < _showHeightCellCount; y++)
{
for (int x = 0; x < _showWidthCellCount; x++)
{
int _GrdX = (nX + x);
int _GrdY = (nY + y);
if (_GrdX % 2 == 0 && _GrdY % 2 == 0)
{
int GrdX = _GrdX / 2;
int GrdY = _GrdY / 2;
//检查缓冲区该位置图像是否已存在如果存在直接画出来
foreach (MapElement grd in GroundViewBuffer)
{
if (grd.X == GrdX && grd.Y == GrdY)
{
brush2d.Draw(grd, (x - 1) * 48, (y - 1) * 32);
goto goon;
}
}
MapGround mg = Current.MGList[GrdX, GrdY];
if (mg.shTileIdx > m_xImageList[mg.cFileIdx].Positions.Count) continue;
uint imgindex = m_xImageList[mg.cFileIdx].Positions[mg.shTileIdx];
if (imgindex == 0) continue;
using (WilImageDate wid = ResFile.ReadWilFile(m_xImageList[mg.cFileIdx], imgindex, mg.shTileIdx))
{
//图像的宽高合乎规定
if (wid.width == 96 && wid.height >= 64)
{
//底层动画
//if (GroundViewBuffer.Count < 132)//问题
//{
MapElement tempgd = new MapElement(GrdX, GrdY, 96, 64);
tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
GroundViewBuffer.Add(tempgd);
brush2d.Draw(tempgd, (x - 1) * 48, (y - 1) * 32);
//}
//MapImage.DrawWilImage(wid, x-2 * 48, y * 32);
}
}
}
goon: continue;
}
}
}
/// <summary>
/// 会画出图像到Texture上面
/// </summary>
/// <param name="nX">左上角的单元格横坐标</param>
/// <param name="nY">左上角的单元格纵坐标</param>
/// <param name="brush2d">2D画笔</param>
public void DrawMapCell(int nX, int nY, Brush brush2d)
{
//是否查过了地图边界
if (nX > Current.MapHeader.shWidth - _showWidthCellCount || nX < 0 || nY > Current.MapHeader.shHeight - _showHeightCellCount || nY < 0)
{
return;
}
//过滤超出缓冲范围的图像数据
foreach (MapObjects obj in ObjectViewBuffer)
{
if (obj.X < nX || obj.X > (nX + _bufferWidthCellCount) || obj.Y < nY || obj.Y > (nY + _bufferHeightCellCount))
{
TempDeleteObjectViewBuffer.Add(obj);
}
}
foreach (MapObjects obj in TempDeleteObjectViewBuffer)
{
ObjectViewBuffer.Remove(obj);
obj.Dispose();
}
if (TempDeleteObjectViewBuffer.Count > 0)
TempDeleteObjectViewBuffer.Clear();
bool bBlend = false;
//for (int y = 0; y < 23; y++)
//{
// for (int x = 0; x < 21; x++)
// {
// int ObjX = nX + x;
// int ObjY = nY + y;
// CellInfor curcell = Current.CellInfors[ObjX, ObjY];
// // 渲染对象 ,对象索引文件合法。
// if (curcell.bFileIdx != 255)
// {
// //wObj2 wObj2 bObj2Ani
// //wObj1 wObj1 bObjAni1
// //wObj2 wObj2-1 bObj2Ani
// //wObj1 wObj1-1 bObjAni1
// //既是索引又是层数Layers
// //0,1,
// int[] nImgIdxs = new int[] { curcell.wObj1, curcell.wObj2, curcell.wObj1, curcell.wObj2 };
// for (byte ObjLayIdx = 0; ObjLayIdx < 4; ObjLayIdx++)
// {
// int nObjFileIdx = 0;
// int nImgIdx = nImgIdxs[ObjLayIdx];
// if (nImgIdx < 0) nImgIdx = 0;
// byte Anibalue = 0;
// switch (ObjLayIdx)
// {
// case 0:
// nObjFileIdx = (byte)((curcell.bFileIdx & 0XF0) >> 4);
// Anibalue = curcell.bObj1Ani;
// break;
// case 2:
// nObjFileIdx = (byte)(curcell.bFileIdx & 0x0F);
// Anibalue = curcell.bObj2Ani;
// break;
// case 1:
// nObjFileIdx = (byte)((curcell.bFileIdx & 0XF0) >> 4);
// Anibalue = curcell.bObj1Ani;
// break;
// case 3:
// nObjFileIdx = (byte)(curcell.bFileIdx & 0x0F);
// Anibalue = curcell.bObj2Ani;
// break;
// }
// //绘制坐标
// short m_shViewOffsetX = 0, m_shViewOffsetY = 0;
// //wid.width,
// //wid.height,
// //检查缓冲区该位置图像是否已存在如果存在直接画出来
// foreach (MapObjects obj in ObjectViewBuffer)
// {
// if (obj.X == ObjX && obj.Y == ObjY & obj.LayerIndex == ObjLayIdx)
// {
// brush2d.Draw(obj, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX, y * 32 + _VIEW_CELL_Y_START - obj._height + 32 - m_shViewOffsetY, 0), Color.White);
// goto go_draw_Ok;
// }
// }
// if (nImgIdx != 65535)
// {
// //图像库文件索引合法,0~2是背景瓷砖
// if (nObjFileIdx > 2 && nObjFileIdx < 14)
// {
// //图片索引是否小于实际图片索引数量
// if (nImgIdx <= m_xImageList[nObjFileIdx].Indexs.Count && nImgIdx >= 0)
// {
// //有了对象文件库和图像索引就可以定位对象图
// uint index = m_xImageList[nObjFileIdx].Indexs[nImgIdx];
// if (index == 0) continue;
// using (WilImageDate wid = ResFile.ReadWilFile(m_xImageList[nObjFileIdx], index))
// {
// //图像的宽高合乎规定
// if (wid.width >= 48 && wid.height >= 32)
// {
// bBlend = false;
// //nImgIdx += GetDoorImgIdx(curcell);//越过门,门由单独的代码处理
// //底层动画
// if (Anibalue != 255)
// {
// byte bTickType;
// short shAniCnt;
// bTickType = (byte)((Anibalue & 0X70) >> 4);
// shAniCnt = (short)(Anibalue & 0X0F);//低4位是动画帧数
// if (((Anibalue & 0X80) >> 7) == 0)
// bBlend = true;
// nImgIdx += m_bAniTileFrame[bTickType][shAniCnt];//得到动画图像索引并设置为当前图像
// index = m_xImageList[nObjFileIdx].Indexs[nImgIdx];
// }
// if (!bBlend) //非混合绘制
// {
// MapObjects tempgd = new MapObjects(ObjX, ObjY, ObjLayIdx, wid.width, wid.height);
// tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
// ObjectViewBuffer.Add(tempgd);
// brush2d.Draw(tempgd, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX,
// y * 32 + _VIEW_CELL_Y_START - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
// //brush2d.Draw(tempgd, null, new Vector3(x * 48 - m_shViewOffsetX, y * 32 - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
// }
// else //混合绘制
// {
// MapObjects tempgd = new MapObjects(ObjX, ObjY, ObjLayIdx, wid.width, wid.height);
// tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
// ObjectViewBuffer.Add(tempgd);
// brush2d.Draw(tempgd, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX,
// y * 32 + _VIEW_CELL_Y_START - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
// }
// }
// }
// }
// }
// }
// //画完了 继续
// go_draw_Ok: continue;
// }
// }
// }
//}
for (int y = -4; y < _showHeightCellCount + 6; y++)
{
for (int x = -4; x < _showWidthCellCount + 6; x++)
{
int ObjX = nX + x;
int ObjY = nY + y;
if (ObjY >= Current.MapHeader.shHeight || ObjY < 0)
break;
if (ObjX >= Current.MapHeader.shWidth || ObjX < 0 || ObjX < 0)
continue;
CellInfor curcell = Current.CellInfors[ObjX, ObjY];
// 渲染对象 ,对象索引文件合法。
if (curcell.bFileIdx != 255)
{
//wObj2 wObj2 bObj2Ani
//wObj1 wObj1 bObjAni1
//wObj2 wObj2-1 bObj2Ani
//wObj1 wObj1-1 bObjAni1
//既是索引又是层数Layers
//0,1,
ushort[] nImgIdxs = new ushort[] { curcell.wObj1, curcell.wObj2 };//, curcell.wObj1, curcell.wObj2 };
for (byte ObjLayIdx = 0; ObjLayIdx < nImgIdxs.Length; ObjLayIdx++)
{
int nObjFileIdx = 0;
ushort nImgIdx = nImgIdxs[ObjLayIdx];
if (nImgIdx < 0) nImgIdx = 0;
byte Anibalue = 0;
switch (ObjLayIdx)
{
case 0:
nObjFileIdx = (byte)((curcell.bFileIdx & 0x0F) >> 4);
Anibalue = curcell.bObj1Ani;
break;
case 1:
nObjFileIdx = (byte)((curcell.bFileIdx & 0x0F) >> 4);
Anibalue = curcell.bObj2Ani;
break;
}
//绘制坐标
short m_shViewOffsetX = 0, m_shViewOffsetY = 0;
//wid.width,
//wid.height,
//检查缓冲区该位置图像是否已存在如果存在直接画出来
foreach (MapObjects obj in ObjectViewBuffer)
{
if (obj.X == ObjX && obj.Y == ObjY & obj.LayerIndex == ObjLayIdx)
{
brush2d.Draw(obj, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX, y * 32 + _VIEW_CELL_Y_START - obj._height + 32 - m_shViewOffsetY, 0), Color.White);
goto go_draw_Ok;
}
}
if (nImgIdx != 65535)
{
//图像库文件索引合法,0~2是背景瓷砖
if (nObjFileIdx > 2 && nObjFileIdx < 14)
{
//图片索引是否小于实际图片索引数量
if (nImgIdx <= m_xImageList[nObjFileIdx].Positions.Count && nImgIdx >= 0)
{
//有了对象文件库和图像索引就可以定位对象图
uint index = m_xImageList[nObjFileIdx].Positions[(ushort)nImgIdx];
if (index == 0) continue;
using (WilImageDate wid = ResFile.ReadWilFile(m_xImageList[nObjFileIdx], index, nImgIdx))
{
//图像的宽高合乎规定
if (wid.width >= 48 && wid.height >= 32)
{
bBlend = false;
//nImgIdx += GetDoorImgIdx(curcell);//越过门,门由单独的代码处理
//底层动画
if (Anibalue != 255)
{
byte bTickType;
short shAniCnt;
bTickType = (byte)((Anibalue & 0X70) >> 4);
shAniCnt = (short)(Anibalue & 0X0F);//低4位是动画帧数
if (((Anibalue & 0X80) >> 7) == 0)
bBlend = true;
//nImgIdx += m_bAniTileFrame[bTickType][shAniCnt];//得到动画图像索引并设置为当前图像
index = m_xImageList[nObjFileIdx].Positions[(ushort)nImgIdx];
}
if (!bBlend) //非混合绘制
{
MapObjects tempgd = new MapObjects(ObjX, ObjY, ObjLayIdx, wid.width, wid.height);
tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
ObjectViewBuffer.Add(tempgd);
brush2d.Draw(tempgd, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX,
y * 32 + _VIEW_CELL_Y_START - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
//brush2d.Draw(tempgd, null, new Vector3(x * 48 - m_shViewOffsetX, y * 32 - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
}
else //混合绘制
{
MapObjects tempgd = new MapObjects(ObjX, ObjY, ObjLayIdx, wid.width, wid.height);
tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
ObjectViewBuffer.Add(tempgd);
brush2d.Draw(tempgd, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX,
y * 32 + _VIEW_CELL_Y_START - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
}
}
}
}
}
}
//画完了 继续
go_draw_Ok: continue;
}
}
}
}
for (int y = 0; y < _showHeightCellCount; y++)
{
for (int x = 0; x < _showWidthCellCount; x++)
{
int ObjX = nX + x;
int ObjY = nY + y;
if (ObjY >= Current.MapHeader.shHeight || ObjY < 0)
break;
if (ObjX >= Current.MapHeader.shWidth || ObjX < 0 || ObjX < 0)
continue;
CellInfor curcell = Current.CellInfors[ObjX, ObjY];
// 渲染对象 ,对象索引文件合法。
if (curcell.bFileIdx != 255)
{
//wObj2 wObj2 bObj2Ani
//wObj1 wObj1 bObjAni1
//wObj2 wObj2-1 bObj2Ani
//wObj1 wObj1-1 bObjAni1
//既是索引又是层数Layers
//0,1,
ushort[] nImgIdxs = new ushort[] { curcell.wObj1, curcell.wObj2 };
for (byte ObjLayIdx = 2; ObjLayIdx < 4; ObjLayIdx++)
{
int nObjFileIdx = 0;
ushort nImgIdx = nImgIdxs[ObjLayIdx - 2];
if (nImgIdx < 0) nImgIdx = 0;
byte Anibalue = 0;
switch (ObjLayIdx)
{
case 2:
nObjFileIdx = (byte)(curcell.bFileIdx & 0x0F);
Anibalue = curcell.bObj1Ani;
break;
case 3:
nObjFileIdx = (byte)(curcell.bFileIdx & 0x0F);
Anibalue = curcell.bObj2Ani;
break;
}
//绘制坐标
short m_shViewOffsetX = 0, m_shViewOffsetY = 0;
//wid.width,
//wid.height,
//检查缓冲区该位置图像是否已存在如果存在直接画出来
foreach (MapObjects obj in ObjectViewBuffer)
{
if (obj.X == ObjX && obj.Y == ObjY & obj.LayerIndex == ObjLayIdx)
{
brush2d.Draw(obj, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX, y * 32 + _VIEW_CELL_Y_START - obj._height + 32 - m_shViewOffsetY, 0), Color.White);
goto go_draw_Ok;
}
}
if (nImgIdx != 65535)
{
//图像库文件索引合法,0~2是背景瓷砖
if (nObjFileIdx > 2 && nObjFileIdx < 14)
{
//图片索引是否小于实际图片索引数量
if (nImgIdx <= m_xImageList[nObjFileIdx].Positions.Count && nImgIdx >= 0)
{
//有了对象文件库和图像索引就可以定位对象图
uint index=0;
try
{
index = m_xImageList[nObjFileIdx].Positions[nImgIdx];
}
catch { }
if (index == 0) continue;
using (WilImageDate wid = ResFile.ReadWilFile(m_xImageList[nObjFileIdx], index, nImgIdx))
{
//图像的宽高合乎规定
if (wid.width >= 48 && wid.height >= 32)
{
bBlend = false;
//nImgIdx += GetDoorImgIdx(curcell);//越过门,门由单独的代码处理
//底层动画
if (Anibalue != 255)
{
byte bTickType;
short shAniCnt;
bTickType = (byte)((Anibalue & 0X70) >> 4);
shAniCnt = (short)(Anibalue & 0X0F);//低4位是动画帧数
if (((Anibalue & 0X80) >> 7) == 0)
bBlend = true;
//nImgIdx += m_bAniTileFrame[bTickType][shAniCnt];//得到动画图像索引并设置为当前图像
index = m_xImageList[nObjFileIdx].Positions[(ushort)nImgIdx];
}
if (!bBlend) //非混合绘制
{
MapObjects tempgd = new MapObjects(ObjX, ObjY, ObjLayIdx, wid.width, wid.height);
tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
ObjectViewBuffer.Add(tempgd);
brush2d.Draw(tempgd, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX,
y * 32 + _VIEW_CELL_Y_START - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
//brush2d.Draw(tempgd, null, new Vector3(x * 48 - m_shViewOffsetX, y * 32 - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
}
else //混合绘制
{
MapObjects tempgd = new MapObjects(ObjX, ObjY, ObjLayIdx, wid.width, wid.height);
tempgd.DrawWilImage(wid, 0, 0);//把地表图像储存进缓冲
ObjectViewBuffer.Add(tempgd);
brush2d.Draw(tempgd, null, new Vector3(x * 48 + _VIEW_CELL_X_START - m_shViewOffsetX,
y * 32 + _VIEW_CELL_Y_START - wid.height + 32 - m_shViewOffsetY, 0), Color.White);
}
}
}
}
}
}
//画完了 继续
go_draw_Ok: continue;
}
}
}
}
}
int GetDoorImgIdx(CellInfor curcell)
{
int nDoorIdx = 0;
if ((curcell.bDoorOffset & 0X80) > 0)
{
if ((curcell.bDoorIdx & 0X7F) > 0)
nDoorIdx += curcell.bDoorOffset & 0X7F;
}
return nDoorIdx;
}
int[] m_dwAniSaveTime = new int[8];
byte[][] m_bAniTileFrame = new byte[8][];
//fixed byte m_bAniTileFrame[8][16];
public int _VIEW_CELL_X_START = -200,
_VIEW_CELL_Y_START = -157,
_bufferWidthCellCount = 24,
_bufferHeightCellCount = 24,
_showWidthCellCount=21,
_showHeightCellCount=23,
_TILE_ANI_DELAY_1 = 150,
_TILE_ANI_DELAY_2 = 200,
_TILE_ANI_DELAY_3 = 250,
_TILE_ANI_DELAY_4 = 300,
_TILE_ANI_DELAY_5 = 350,
_TILE_ANI_DELAY_6 = 400,
_TILE_ANI_DELAY_7 = 420,
_TILE_ANI_DELAY_8 = 450;
void SetAniTileFrame(int nLoopTime)
{
int nCnt;
for (nCnt = 0; nCnt < 8; nCnt++)
{
m_dwAniSaveTime[nCnt] += nLoopTime;
}
if (m_dwAniSaveTime[0] > _TILE_ANI_DELAY_1)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[0][nCnt]++;
if (m_bAniTileFrame[0][nCnt] >= nCnt)
m_bAniTileFrame[0][nCnt] = 0;
}
m_dwAniSaveTime[0] = 0;
}
if (m_dwAniSaveTime[1] > _TILE_ANI_DELAY_2)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[1][nCnt]++;
if (m_bAniTileFrame[1][nCnt] >= nCnt)
m_bAniTileFrame[1][nCnt] = 0;
}
m_dwAniSaveTime[1] = 0;
}
if (m_dwAniSaveTime[2] > _TILE_ANI_DELAY_3)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[2][nCnt]++;
if (m_bAniTileFrame[2][nCnt] >= nCnt)
m_bAniTileFrame[2][nCnt] = 0;
}
m_dwAniSaveTime[2] = 0;
}
if (m_dwAniSaveTime[3] > _TILE_ANI_DELAY_4)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[3][nCnt]++;
if (m_bAniTileFrame[3][nCnt] >= nCnt)
m_bAniTileFrame[3][nCnt] = 0;
}
m_dwAniSaveTime[3] = 0;
}
if (m_dwAniSaveTime[4] > _TILE_ANI_DELAY_5)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[4][nCnt]++;
if (m_bAniTileFrame[4][nCnt] >= nCnt)
m_bAniTileFrame[4][nCnt] = 0;
}
m_dwAniSaveTime[4] = 0;
}
if (m_dwAniSaveTime[5] > _TILE_ANI_DELAY_6)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[5][nCnt]++;
if (m_bAniTileFrame[5][nCnt] >= nCnt)
m_bAniTileFrame[5][nCnt] = 0;
}
m_dwAniSaveTime[5] = 0;
}
if (m_dwAniSaveTime[6] > _TILE_ANI_DELAY_7)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[6][nCnt]++;
if (m_bAniTileFrame[6][nCnt] >= nCnt)
m_bAniTileFrame[6][nCnt] = 0;
}
m_dwAniSaveTime[6] = 0;
}
if (m_dwAniSaveTime[7] > _TILE_ANI_DELAY_8)
{
for (nCnt = 0; nCnt < 16; nCnt++)
{
m_bAniTileFrame[7][nCnt]++;
if (m_bAniTileFrame[7][nCnt] >= nCnt)
m_bAniTileFrame[7][nCnt] = 0;
}
m_dwAniSaveTime[7] = 0;
}
}
//void DrawOpenDoor(int nX, int nY)
//{
// if ( GetDoorState(nX, nY) )
// {
// BYTE bDoorIndex = m_pbCellIDoorIdx[nX + nY*m_stMapFileHeader.shWidth];
// for ( INT nCnt = 0; nCnt < m_bDoorCount; nCnt++ )
// {
// if ( m_pstDoorInfo[nCnt].bDoorIdx == bDoorIndex )
// {
// for ( INT nLoop = 0; nLoop < m_pstDoorInfo[nCnt].bDoorImgCnt; nLoop++ )
// {
// WORD wPosX = m_pstDoorInfo[nCnt].pstDoorImgInfo[nLoop].wPosX;
// WORD wPosY = m_pstDoorInfo[nCnt].pstDoorImgInfo[nLoop].wPosY;
// if ( nX == wPosX && nY == wPosY )
// {
// WORD wImgIndex = m_pstDoorInfo[nCnt].pstDoorImgInfo[nLoop].wImageNum;
// // 弊覆阑 弊赴促.
// // ".//Data//housesc.wil"
// m_pxTileImg[4].NewSetIndex(wImgIndex);
// g_xMainWnd.DrawWithImageForCompClipRgn(
// (nX-m_shStartViewTileX)*_CELL_WIDTH +_VIEW_CELL_X_START-m_shViewOffsetX,
// (nY-m_shStartViewTileY)*_CELL_HEIGHT+_VIEW_CELL_Y_START-m_pxTileImg[4].m_lpstNewCurrWilImageInfo->shHeight+_CELL_HEIGHT-m_shViewOffsetY,
// m_pxTileImg[4].m_lpstNewCurrWilImageInfo->shWidth,
// m_pxTileImg[4].m_lpstNewCurrWilImageInfo->shHeight,
// (WORD*)m_pxTileImg[4].m_pbCurrImage,
// _CLIP_WIDTH, _CLIP_HEIGHT);
// break;
// }
// }
// }
// }
// }
//}
public WixFile[] m_xImageList = new WixFile[] {
ResFile.ReadWixFile("Tilesc"), ResFile.ReadWixFile("Tiles30c"),ResFile.ReadWixFile("Tiles5c"),
ResFile.ReadWixFile("SmTilesc"), ResFile.ReadWixFile("Housesc"), ResFile.ReadWixFile("Cliffsc"),
ResFile.ReadWixFile("Dungeonsc"),ResFile.ReadWixFile("Innersc"),ResFile.ReadWixFile("Furnituresc"),
ResFile.ReadWixFile("Wallsc"), ResFile.ReadWixFile("SmObjectsc"),ResFile.ReadWixFile("Animationsc"),
ResFile.ReadWixFile("Object1c") ,ResFile.ReadWixFile("Object2c")};
#region IDisposable 成员
public void Dispose()
{
foreach (MapElement grd in TempDeleteGroundViewBuffer)
{
grd.Dispose();
}
foreach (MapElement grd in GroundViewBuffer)
{
grd.Dispose();
}
foreach (MapObjects moj in TempDeleteObjectViewBuffer)
{
moj.Dispose();
}
foreach (MapObjects moj in ObjectViewBuffer)
{
moj.Dispose();
}
}
#endregion
}
/// <summary>
///@brief 地图文件头
///我研究了一下,发现每个文件开头的十几个字节里有地图大小,随后是长*宽/4 个结构,每个结构3个字节,然后又是长*宽 个结构,结构长度为E
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public unsafe struct MapFileHeader
{
/// <summary>
/// 版本
/// </summary>
public ushort shVer;
/// <summary>
/// 地图宽度
/// </summary>
public ushort shWidth;
/// <summary>
/// 地图高度
/// </summary>
public ushort shHeight;
/// <summary>
/// 事件文件索引
/// </summary>
public char cEventFileIdx;
/// <summary>
/// 背景颜色
/// </summary>
public char cFogColor;
}
/// <summary>
/// @brief 瓷砖信息
/// 其实,主要的贴图工作由小图部分完成
/// 小图 文件里的小图结构是指向*.wix,*.wil 的地图图片文件的
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public unsafe struct MapGround
{
/// <summary>
/// 文件索引,是对应的文件名数组
/// </summary>
public char cFileIdx;
/// <summary>
/// 瓷砖索引,是地砖的编号
/// </summary>
public ushort shTileIdx;
}
/// <summary>
/// @brief 地图单元格信息 (客户端的格式)
/// 大图
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public unsafe struct CellInfor
{
/// <summary>
/// 障碍层
/// </summary>
public byte bFlag;
/// <summary>
/// 动画物体1
/// </summary>
public byte bObj1Ani;
/// <summary>
/// 动画物体2
/// </summary>
public byte bObj2Ani;
/// <summary>
/// 文件索引
/// </summary>
public short bFileIdx; // BYTE bFileIdx;
/// <summary>
/// 物体1
/// </summary>
public ushort wObj1;
/// <summary>
/// 物体2
/// </summary>
public ushort wObj2;
/// <summary>
/// 大门索引
/// </summary>
public ushort bDoorIdx;
/// <summary>
/// 大门偏移
/// </summary>
public byte bDoorOffset;
/// <summary>
/// 光线
/// </summary>
public ushort wLigntNEvent;
}
/// <summary>
/// 地图文件
/// </summary>
public struct MapFile
{
/// <summary>
/// 地图文件头
/// </summary>
public MapFileHeader MapHeader;
/// <summary>
/// 地面瓷砖索引
/// </summary>
public MapGround[,] MGList;
/// <summary>
/// 地面大图物件索引
/// </summary>
public CellInfor[,] CellInfors;
}
}
http://blog.csdn.net/shigaofei1/archive/2011/06/27/6569537.aspx