📄 mapunit.pas
字号:
unit MapUnit;
//地图单元
{ MAP文件结构
文件头:52字节
第一行第一列定义
第二行第一列定义
第三行第一列定义
。
第Width行第一列定义
第一行第二列定义
}
interface
uses
Windows, Classes, SysUtils, Grobal2, HUtil32, DXDraws, CliUtil,
MShare, Share;
type
// -------------------------------------------------------------------------------
// Map
// -------------------------------------------------------------------------------
TMapPrjInfo = record
Ident: string[16];
ColCount: integer;
RowCount: integer;
end;
//.MAP文件头 52bytes
TMapHeader = packed record
wWidth :Word; //宽度 2
wHeight :Word; //高度 2
sTitle :String[16]; //标题 16
UpdateDate :TDateTime; //更新日期 8
Reserved :array[0..22] of Char; //保留 20
end;
TMapInfo = packed record
wBkImg :Word;
wMidImg :Word;
wFrImg :Word;
btDoorIndex :Byte; //$80 (巩娄), 巩狼 侥喊 牢郸胶
btDoorOffset :Byte; //摧腮 巩狼 弊覆狼 惑措 困摹, $80 (凯覆/摧塞(扁夯))
btAniFrame :Byte; //$80(Draw Alpha) + 橇贰烙 荐
btAniTick :Byte;
btArea :Byte; //瘤开 沥焊
btLight :Byte; //0..1..4 堡盔 瓤苞
end;
pTMapInfo = ^TMapInfo;
TMapInfoArr = array[0..MaxListSize] of TMapInfo;
pTMapInfoArr = ^TMapInfoArr;
TMap = class
private
function LoadMapInfo(sMapFile:String; var nWidth, nHeight: Integer): Boolean;
procedure UpdateMapSeg (cx, cy: integer); //, maxsegx, maxsegy: integer);
procedure LoadMapArr(nCurrX, nCurrY: integer);
procedure SaveMapArr(nCurrX,nCurrY:Integer);
public
m_sMapBase :string;
m_MArr :array[0..MAXX * 3, 0..MAXY * 3] of TMapInfo;
m_boChange :Boolean;
m_ClientRect :TRect;
m_OldClientRect :TRect;
m_nBlockLeft :Integer;
m_nBlockTop :Integer; //鸥老 谅钎肺 哭率, 怖措扁 谅钎
m_nOldLeft :Integer;
m_nOldTop :Integer;
m_sOldMap :String;
m_nCurUnitX :Integer;
m_nCurUnitY :Integer;
m_sCurrentMap :String;
m_boSegmented :Boolean;
m_nSegXCount :Integer;
m_nSegYCount :Integer;
constructor Create;
destructor Destroy;override;//Jacky
procedure UpdateMapSquare (cx, cy: integer);
procedure UpdateMapPos (mx, my: integer);
procedure ReadyReload;
procedure LoadMap(sMapName:String;nMx,nMy:Integer);
procedure MarkCanWalk (mx, my: integer; bowalk: Boolean);
function CanMove (mx, my: integer): Boolean;
function CanFly (mx, my: integer): Boolean;
function GetDoor (mx, my: integer): Integer;
function IsDoorOpen (mx, my: integer): Boolean;
function OpenDoor (mx, my: integer): Boolean;
function CloseDoor (mx, my: integer): Boolean;
end;
procedure DrawMiniMap;
implementation
uses
ClMain;
constructor TMap.Create;
begin
inherited Create;
//GetMem (MInfoArr, sizeof(TMapInfo) * LOGICALMAPUNIT * 3 * LOGICALMAPUNIT * 3);
m_ClientRect := Rect (0,0,0,0);
m_boChange :=False;
m_sMapBase := '.\Map\'; //地图文件所在目录
m_sCurrentMap := ''; //当前地图文件名(不含.MAP)
m_boSegmented := FALSE;
m_nSegXCount := 0;
m_nSegYCount := 0;
m_nCurUnitX := -1; //当前单元位置X、Y
m_nCurUnitY := -1;
m_nBlockLeft := -1; //当前块X,Y左上角
m_nBlockTop := -1;
m_sOldMap := ''; //前一个地图文件名(在换地图的时候用)
end;
destructor TMap.Destroy;
begin
inherited Destroy;
end;
//读MAP文件的宽度和高度
function TMap.LoadMapInfo (sMapFile:String; var nWidth, nHeight: Integer): Boolean;
var
sFileName :String;
nHandle :Integer;
Header :TMapHeader;
begin
Result := FALSE;
sFileName := m_sMapBase + sMapFile;
if FileExists (sFileName) then begin
nHandle := FileOpen (sFileName, fmOpenRead or fmShareDenyNone);
if nHandle > 0 then begin
FileRead (nHandle, Header, sizeof(TMapHeader));
nWidth := Header.wWidth;
nHeight := Header.wHeight;
end;
FileClose(nHandle);
end;
end;
//segmented map 牢 版快
procedure TMap.UpdateMapSeg (cx, cy: integer); //, maxsegx, maxsegy: integer);
begin
end;
//加载地图段数据
//以当前座标为准
procedure TMap.LoadMapArr(nCurrX,nCurrY: integer);
var
I :Integer;
K :Integer;
nAline :Integer;
nLx :Integer;
nRx :Integer;
nTy :Integer;
nBy :Integer;
sFileName :String;
nHandle :Integer;
Header :TMapHeader;
begin
FillChar(m_MArr, SizeOf(m_MArr), #0);
sFileName:=m_sMapBase + m_sCurrentMap + '.map';
if FileExists(sFileName) then begin
nHandle:=FileOpen(sFileName, fmOpenRead or fmShareDenyNone);
if nHandle > 0 then begin
FileRead (nHandle, Header, SizeOf(TMapHeader));
nLx := (nCurrX - 1) * LOGICALMAPUNIT;
nRx := (nCurrX + 2) * LOGICALMAPUNIT; //rx
nTy := (nCurrY - 1) * LOGICALMAPUNIT;
nBy := (nCurrY + 2) * LOGICALMAPUNIT;
if nLx < 0 then nLx := 0;
if nTy < 0 then nTy := 0;
if nBy >= Header.wHeight then nBy := Header.wHeight;
nAline := SizeOf(TMapInfo) * Header.wHeight; //一个列的大小(字节数)
for I:=nLx to nRx - 1 do begin //i最多有 3*LOGICALMAPUNIT 值,这就是要更新的地图的行数
if (I >= 0) and (I < Header.wWidth) then begin
//当前行列为X,Y,则应从X*每行字节数+Y*每项字节数开始读第一行数据
FileSeek(nHandle, SizeOf(TMapHeader) + (nAline * I) + (SizeOf(TMapInfo) * nTy), 0);
FileRead(nHandle, m_MArr[I - nLx, 0], SizeOf(TMapInfo) * (nBy - nTy));
end;
end;
FileClose(nHandle);
end;
end;
end;
procedure TMap.SaveMapArr(nCurrX,nCurrY:Integer);
var
I :Integer;
K :Integer;
nAline :Integer;
nLx :Integer;
nRx :Integer;
nTy :Integer;
nBy :Integer;
sFileName :String;
nHandle :Integer;
Header :TMapHeader;
begin
FillChar(m_MArr, SizeOf(m_MArr), #0);
sFileName:=m_sMapBase + m_sCurrentMap + '.map';
if FileExists(sFileName) then begin
nHandle:=FileOpen(sFileName, fmOpenRead or fmShareDenyNone);
if nHandle > 0 then begin
FileRead (nHandle, Header, SizeOf(TMapHeader));
nLx := (nCurrX - 1) * LOGICALMAPUNIT;
nRx := (nCurrX + 2) * LOGICALMAPUNIT; //rx
nTy := (nCurrY - 1) * LOGICALMAPUNIT;
nBy := (nCurrY + 2) * LOGICALMAPUNIT;
if nLx < 0 then nLx := 0;
if nTy < 0 then nTy := 0;
if nBy >= Header.wHeight then nBy := Header.wHeight;
nAline := SizeOf(TMapInfo) * Header.wHeight;
for I:=nLx to nRx - 1 do begin
if (I >= 0) and (I < Header.wWidth) then begin
FileSeek(nHandle, SizeOf(TMapHeader) + (nAline * I) + (SizeOf(TMapInfo) * nTy), 0);
FileRead(nHandle, m_MArr[I - nLx, 0], SizeOf(TMapInfo) * (nBy - nTy));
end;
end;
FileClose(nHandle);
end;
end;
end;
procedure TMap.ReadyReload;
begin
m_nCurUnitX := -1;
m_nCurUnitY := -1;
end;
//cx, cy: 位置, 以LOGICALMAPUNIT为单位
procedure TMap.UpdateMapSquare (cx, cy: integer);
begin
if (cx <> m_nCurUnitX) or (cy <> m_nCurUnitY) then begin
if m_boSegmented then
updatemapseg (cx, cy)
else
LoadMapArr(cx, cy);
m_nCurUnitX := cx;
m_nCurUnitY := cy;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -