|
传奇中的人物和建筑的遮挡关系
请问传奇中的人物和建筑的遮挡关系是如何实现的,在代码中没发现有比较建筑物Y和人物Y坐标的代码,貌似都是先把建筑画完,再画人物,这样的话人物就总会遮挡住建筑物的,请高手帮帮忙。。。
关键代码:
procedure TPlayScene.PlayScene(MSurface: TDirectDrawSurface);
function CheckOverlappedObject(myrc, obrc: TRect): Boolean;
begin
if (obrc.Right > myrc.Left) and (obrc.Left < myrc.Right) and
(obrc.Bottom > myrc.Top) and (obrc.Top < myrc.Bottom) then
Result := True
else Result := FALSE;
end;
var
I, j, k, n, m, mmm, ix, iy, line, defx, defy, wunit, fridx, ani, anitick, ax, ay, idx, drawingbottomline: Integer;
dsurface, d: TDirectDrawSurface;
blend, movetick: Boolean;
//myrc, obrc: TRect;
DropItem: pTDropItem;
evn: TEvent;
Actor: TActor;
meff: TMagicEff;
msgstr: string;
ShowItem: pTShowItem;
nFColor, nBColor: Integer;
begin
drawingbottomline := 0;
if (g_MySelf = nil) then begin
msgstr := '正在退出游戏,请稍候...';
with MSurface.Canvas do begin
SetBkMode(Handle, TRANSPARENT);
BoldTextOut(MSurface, (SCREENWIDTH - TextWidth(msgstr)) div 2, (SCREENHEIGHT - 600) + 200,
clWhite, clBlack, msgstr);
Release;
end;
Exit;
end;
g_boDoFastFadeOut := FALSE;
movetick := FALSE;
if GetTickCount - m_dwMoveTime >= 100 then begin
m_dwMoveTime := GetTickCount;
movetick := True;
Inc(m_nMoveStepCount);
if m_nMoveStepCount > 1 then m_nMoveStepCount := 0;
end;
if GetTickCount - m_dwAniTime >= 50 then begin
m_dwAniTime := GetTickCount;
Inc(m_nAniCount);
if m_nAniCount > 100000 then m_nAniCount := 0;
end;
try
I := 0;
while True do begin
if I >= m_ActorList.count then Break;
Actor := m_ActorList;
if movetick then Actor.m_boLockEndFrame := FALSE;
if not Actor.m_boLockEndFrame then begin
Actor.ProcMsg;
if movetick then
if Actor.Move(m_nMoveStepCount) then begin
Inc(I);
Continue;
end;
Actor.Run; //
if Actor <> g_MySelf then Actor.ProcHurryMsg;
end;
if Actor = g_MySelf then Actor.ProcHurryMsg;
//
if Actor.m_nWaitForRecogId <> 0 then begin
if Actor.IsIdle then begin
DelChangeFace(Actor.m_nWaitForRecogId);
NewActor(Actor.m_nWaitForRecogId, Actor.m_nCurrX, Actor.m_nCurrY, Actor.m_btDir, Actor.m_nWaitForFeature, Actor.m_nWaitForStatus);
Actor.m_nWaitForRecogId := 0;
Actor.m_boDelActor := True;
end;
end;
if Actor.m_boDelActor then begin
g_FreeActorList.Add(Actor);
m_ActorList.Delete(I);
if g_TargetCret = Actor then g_TargetCret := nil;
if g_FocusCret = Actor then g_FocusCret := nil;
if g_MagicTarget = Actor then g_MagicTarget := nil;
end else
Inc(I);
end;
except
DebugOutStr('101');
end;
try
I := 0;
while True do begin
if I >= m_GroundEffectList.count then Break;
meff := m_GroundEffectList;
if meff.m_boActive then begin
if not meff.Run then begin
meff.Free;
m_GroundEffectList.Delete(I);
Continue;
end;
end;
Inc(I);
end;
I := 0;
while True do begin
if I >= m_EffectList.count then Break;
meff := m_EffectList;
if meff.m_boActive then begin
if not meff.Run then begin
meff.Free;
m_EffectList.Delete(I);
Continue;
end;
end;
Inc(I);
end;
I := 0;
while True do begin
if I >= m_FlyList.count then Break;
meff := m_FlyList;
if meff.m_boActive then begin
if not meff.Run then begin
meff.Free;
m_FlyList.Delete(I);
Continue;
end;
end;
Inc(I);
end;
EventMan.Execute;
except
DebugOutStr('102');
end;
try
//清除超过显示范围的物品数据
ClearDropItem();
//清除超过显示范围的魔法数据
for k := 0 to EventMan.EventList.count - 1 do begin
evn := TEvent(EventMan.EventList[k]);
if (abs(evn.m_nX - g_MySelf.m_nCurrX) > 30) and (abs(evn.m_nY - g_MySelf.m_nCurrY) > 30) then begin
evn.Free;
EventMan.EventList.Delete(k);
Break;
end;
end;
for k := 0 to EventMan.EventList.count - 1 do begin //播放烟花声音
evn := TEvent(EventMan.EventList[k]);
if (abs(evn.m_nX - g_MySelf.m_nCurrX) <= 30) or (abs(evn.m_nY - g_MySelf.m_nCurrY) <= 30) then begin
if evn.m_nEventType in [ET_FIREFLOWER_1..ET_FIREFLOWER_7] then begin
if TFlowerEvent(evn).m_nExplosionSound > 0 then begin
PlaySound(TFlowerEvent(evn).m_nExplosionSound);
TFlowerEvent(evn).m_nExplosionSound := -2;
end;
end;
end;
end;
except
DebugOutStr('103');
end;
try
with Map.m_ClientRect do begin
{$IF SWH = SWH800}
Left := g_MySelf.m_nRx - 9;
Top := g_MySelf.m_nRy - 9;
Right := g_MySelf.m_nRx + 9;
Bottom := g_MySelf.m_nRy + 8;
{$ELSEIF SWH = SWH1024}
Left := g_MySelf.m_nRx - 12;
Top := g_MySelf.m_nRy - 12;
Right := g_MySelf.m_nRx + 12; //
Bottom := g_MySelf.m_nRy + 15;
{$IFEND}
end;
Map.UpdateMapPos(g_MySelf.m_nRx, g_MySelf.m_nRy);
///////////////////////
//ViewFog := FALSE;
///////////////////////
if g_boNoDarkness or (g_MySelf.m_boDeath) then begin
g_boViewFog := FALSE;
end;
if g_boViewFog then begin
ZeroMemory(m_PFogScreen, MAPSURFACEHEIGHT * MAPSURFACEWIDTH);
ClearLightMap;
end;
// drawingbottomline := 450;
drawingbottomline := SCREENHEIGHT;
m_ObjSurface.Fill(0);
DrawTileMap;
m_ObjSurface.Draw(0, 0,
Rect(UNITX * 3 + g_MySelf.m_nShiftX,
UNITY * 2 + g_MySelf.m_nShiftY,
UNITX * 3 + g_MySelf.m_nShiftX + MAPSURFACEWIDTH,
UNITY * 2 + g_MySelf.m_nShiftY + MAPSURFACEHEIGHT),
m_MapSurface,
FALSE);
except
DebugOutStr('104');
end;
defx := -UNITX * 2 - g_MySelf.m_nShiftX + AAX + 14;
defy := -UNITY * 2 - g_MySelf.m_nShiftY;
m_nDefXX := defx;
m_nDefYY := defy;
try
m := defy - UNITY;
for j := (Map.m_ClientRect.Top - Map.m_nBlockTop) to (Map.m_ClientRect.Bottom - Map.m_nBlockTop + LONGHEIGHT_IMAGE) do begin
if j < 0 then begin
Inc(m, UNITY); Continue; end;
n := defx - UNITX * 2;
//*** 48*32 鸥老屈 坷宏璃飘 弊府扁
for I := (Map.m_ClientRect.Left - Map.m_nBlockLeft - 2) to (Map.m_ClientRect.Right - Map.m_nBlockLeft + 2) do begin
if (I >= 0) and (I < LOGICALMAPUNIT * 3) and (j >= 0) and (j < LOGICALMAPUNIT * 3) then begin
fridx := (Map.m_MArr[I, j].wFrImg) and $7FFF;
if fridx > 0 then begin
ani := Map.m_MArr[I, j].btAniFrame;
wunit := Map.m_MArr[I, j].btArea;
if (ani and $80) > 0 then begin
blend := True;
ani := ani and $7F;
end;
if ani > 0 then begin
anitick := Map.m_MArr[I, j].btAniTick;
fridx := fridx + (m_nAniCount mod (ani + (ani * anitick))) div (1 + anitick);
end;
if (Map.m_MArr[I, j].btDoorOffset and $80) > 0 then begin //凯覆
if (Map.m_MArr[I, j].btDoorIndex and $7F) > 0 then //巩栏肺 钎矫等 巴父
fridx := fridx + (Map.m_MArr[I, j].btDoorOffset and $7F); //凯赴 巩
end;
fridx := fridx - 1;
// 拱眉 弊覆
dsurface := GetObjs(wunit, fridx);
if dsurface <> nil then begin
if (dsurface.Width = 48) and (dsurface.Height = 32) then begin
mmm := m + UNITY - dsurface.Height;
if (n + dsurface.Width > 0) and (n <= SCREENWIDTH) and (mmm + dsurface.Height > 0) and (mmm < drawingbottomline) then begin
m_ObjSurface.Draw(n, mmm, dsurface.ClientRect, dsurface, True)
end else begin
if mmm < drawingbottomline then begin //阂鞘夸窍霸 弊府绰 巴阑 乔窃
m_ObjSurface.Draw(n, mmm, dsurface.ClientRect, dsurface, True)
end;
end;
end;
end;
end;
end;
Inc(n, UNITX);
end;
Inc(m, UNITY);
end;
for k := 0 to m_GroundEffectList.count - 1 do begin
meff := TMagicEff(m_GroundEffectList[k]);
//if j = (meff.Ry - Map.BlockTop) then begin
meff.DrawEff(m_ObjSurface);
if g_boViewFog then begin
AddLight(meff.rx, meff.ry, 0, 0, meff.light, FALSE);
end;
end;
except
DebugOutStr('105');
end;
try
m := defy - UNITY;
for j := (Map.m_ClientRect.Top - Map.m_nBlockTop) to (Map.m_ClientRect.Bottom - Map.m_nBlockTop + LONGHEIGHT_IMAGE) do begin
if j < 0 then begin
Inc(m, UNITY); Continue; end;
n := defx - UNITX * 2;
//*** 硅版坷宏璃飘 弊府扁
for I := (Map.m_ClientRect.Left - Map.m_nBlockLeft - 2) to (Map.m_ClientRect.Right - Map.m_nBlockLeft + 2) do begin
if (I >= 0) and (I < LOGICALMAPUNIT * 3) and (j >= 0) and (j < LOGICALMAPUNIT * 3) then begin
fridx := (Map.m_MArr[I, j].wFrImg) and $7FFF;
if fridx > 0 then begin
blend := FALSE;
wunit := Map.m_MArr[I, j].btArea;
//俊聪皋捞记
ani := Map.m_MArr[I, j].btAniFrame;
if (ani and $80) > 0 then begin
blend := True;
ani := ani and $7F;
end;
if ani > 0 then begin
anitick := Map.m_MArr[I, j].btAniTick;
fridx := fridx + (m_nAniCount mod (ani + (ani * anitick))) div (1 + anitick);
end;
if (Map.m_MArr[I, j].btDoorOffset and $80) > 0 then begin //凯覆
if (Map.m_MArr[I, j].btDoorIndex and $7F) > 0 then //巩栏肺 钎矫等 巴父
fridx := fridx + (Map.m_MArr[I, j].btDoorOffset and $7F); //凯赴 巩
end;
fridx := fridx - 1;
// 拱眉 弊覆
if not blend then begin
dsurface := GetObjs(wunit, fridx);
if dsurface <> nil then begin
if (dsurface.Width <> 48) or (dsurface.Height <> 32) then begin
mmm := m + UNITY - dsurface.Height;
if (n + dsurface.Width > 0) and (n <= SCREENWIDTH) and (mmm + dsurface.Height > 0) and (mmm < drawingbottomline) then begin
m_ObjSurface.Draw(n, mmm, dsurface.ClientRect, dsurface, True)
end else begin
if mmm < drawingbottomline then begin //阂鞘夸窍霸 弊府绰 巴阑 乔窃
m_ObjSurface.Draw(n, mmm, dsurface.ClientRect, dsurface, True)
end;
end;
end;
end;
end else begin
dsurface := GetObjsEx(wunit, fridx, ax, ay);
if dsurface <> nil then begin
mmm := m + ay - 68; //UNITY - DSurface.Height;
if (n > 0) and (mmm + dsurface.Height > 0) and (n + dsurface.Width < SCREENWIDTH) and (mmm < drawingbottomline) then begin
DrawBlend(m_ObjSurface, n + ax - 2, mmm, dsurface, 1);
end else begin
if mmm < drawingbottomline then begin //阂鞘夸窍霸 弊府绰 巴阑 乔窃
DrawBlend(m_ObjSurface, n + ax - 2, mmm, dsurface, 1);
end;
end;
end;
end;
end;
end;
Inc(n, UNITX);
end;
if (j <= (Map.m_ClientRect.Bottom - Map.m_nBlockTop)) and (not g_boServerChanging) then begin
for k := 0 to EventMan.EventList.count - 1 do begin
evn := TEvent(EventMan.EventList[k]);
if j = (evn.m_nY - Map.m_nBlockTop) then begin
evn.DrawEvent(m_ObjSurface,
(evn.m_nX - Map.m_ClientRect.Left) * UNITX + defx,
m);
end;
end;
if g_boDrawDropItem then begin
//显示地面物品外形
for k := 0 to g_DropedItemList.count - 1 do begin
DropItem := pTDropItem(g_DropedItemList[k]);
if DropItem <> nil then begin
if j = (DropItem.Y - Map.m_nBlockTop) then begin
d := g_WDnItemImages.Images[DropItem.looks];
if d <> nil then begin
ix := (DropItem.X - Map.m_ClientRect.Left) * UNITX + defx + SOFFX; // + actor.ShiftX;
iy := m; // + actor.ShiftY;
if DropItem = g_FocusItem then begin
g_ImgMixSurface.Draw(0, 0, d.ClientRect, d, FALSE);
DrawEffect(0, 0, d.Width, d.Height, g_ImgMixSurface, ceBright);
m_ObjSurface.Draw(ix + HALFX - (d.Width div 2),
iy + HALFY - (d.Height div 2),
d.ClientRect,
g_ImgMixSurface, True);
end else begin
m_ObjSurface.Draw(ix + HALFX - (d.Width div 2),
iy + HALFY - (d.Height div 2),
d.ClientRect,
d, True);
end;
end;
end;
end;
end;
end;
for k := 0 to m_ActorList.count - 1 do begin
Actor := m_ActorList[k];
if (j = Actor.m_nRy - Map.m_nBlockTop - Actor.m_nDownDrawLevel) then begin
Actor.m_nSayX := (Actor.m_nRx - Map.m_ClientRect.Left) * UNITX + defx + Actor.m_nShiftX + 24;
if Actor.m_boDeath then
Actor.m_nSayY := m + UNITY + Actor.m_nShiftY + 16 - 60 + (Actor.m_nDownDrawLevel * UNITY)
else Actor.m_nSayY := m + UNITY + Actor.m_nShiftY + 16 - 95 + (Actor.m_nDownDrawLevel * UNITY);
Actor.DrawChr(m_ObjSurface, (Actor.m_nRx - Map.m_ClientRect.Left) * UNITX + defx,
m + (Actor.m_nDownDrawLevel * UNITY),
FALSE, True);
end;
end;
for k := 0 to m_FlyList.count - 1 do begin
meff := TMagicEff(m_FlyList[k]);
if j = (meff.ry - Map.m_nBlockTop) then
meff.DrawEff(m_ObjSurface);
end;
end;
Inc(m, UNITY);
end;
except
DebugOutStr('106');
end;
try
if g_boViewFog then begin
m := defy - UNITY * 4;
for j := (Map.m_ClientRect.Top - Map.m_nBlockTop - 4) to (Map.m_ClientRect.Bottom - Map.m_nBlockTop + LONGHEIGHT_IMAGE) do begin
if j < 0 then begin
Inc(m, UNITY); Continue; end;
n := defx - UNITX * 5;
//硅版 器弊 弊府扁
for I := (Map.m_ClientRect.Left - Map.m_nBlockLeft - 5) to (Map.m_ClientRect.Right - Map.m_nBlockLeft + 5) do begin
if (I >= 0) and (I < LOGICALMAPUNIT * 3) and (j >= 0) and (j < LOGICALMAPUNIT * 3) then begin
idx := Map.m_MArr[I, j].btLight;
if idx > 0 then begin
AddLight(I + Map.m_nBlockLeft, j + Map.m_nBlockTop, 0, 0, idx, FALSE);
end;
end;
Inc(n, UNITX);
end;
Inc(m, UNITY);
end;
//某腐磐 器弊 弊府扁
if m_ActorList.count > 0 then begin
for k := 0 to m_ActorList.count - 1 do begin
Actor := m_ActorList[k];
if (Actor = g_MySelf) or (Actor.light > 0) then
AddLight(Actor.m_nRx, Actor.m_nRy, Actor.m_nShiftX, Actor.m_nShiftY, Actor.light, Actor = g_MySelf);
end;
end else begin
if g_MySelf <> nil then
AddLight(g_MySelf.m_nRx, g_MySelf.m_nRy, g_MySelf.m_nShiftX, g_MySelf.m_nShiftY, g_MySelf.light, True);
end;
end;
except
DebugOutStr('107');
end;
if not g_boServerChanging then begin
try
//**** 林牢傍 某腐磐 弊府扁
if not g_boCheckBadMapMode then
if g_MySelf.m_nState and $00800000 = 0 then //捧疙捞 酒聪搁
g_MySelf.DrawChr(m_ObjSurface, (g_MySelf.m_nRx - Map.m_ClientRect.Left) * UNITX + defx, (g_MySelf.m_nRy - Map.m_ClientRect.Top - 1) * UNITY + defy, True, FALSE);
//****
if (g_FocusCret <> nil) then begin
if IsValidActor(g_FocusCret) and (g_FocusCret <> g_MySelf) then
// if (actor.m_btRace <> 81) or (FocusCret.State and $00800000 = 0) then //Jacky
if (g_FocusCret.m_nState and $00800000 = 0) then //Jacky
g_FocusCret.DrawChr(m_ObjSurface,
(g_FocusCret.m_nRx - Map.m_ClientRect.Left) * UNITX + defx,
(g_FocusCret.m_nRy - Map.m_ClientRect.Top - 1) * UNITY + defy, True, FALSE);
end;
if (g_MagicTarget <> nil) then begin
if IsValidActor(g_MagicTarget) and (g_MagicTarget <> g_MySelf) then
if g_MagicTarget.m_nState and $00800000 = 0 then //捧疙捞 酒聪搁
g_MagicTarget.DrawChr(m_ObjSurface,
(g_MagicTarget.m_nRx - Map.m_ClientRect.Left) * UNITX + defx,
(g_MagicTarget.m_nRy - Map.m_ClientRect.Top - 1) * UNITY + defy, True, FALSE);
end;
except
DebugOutStr('108');
end;
end;
try
for k := 0 to m_ActorList.count - 1 do begin
Actor := m_ActorList[k];
Actor.DrawEff(m_ObjSurface,
(Actor.m_nRx - Map.m_ClientRect.Left) * UNITX + defx,
(Actor.m_nRy - Map.m_ClientRect.Top - 1) * UNITY + defy);
end;
for k := 0 to m_EffectList.count - 1 do begin
meff := TMagicEff(m_EffectList[k]);
//if j = (meff.Ry - Map.BlockTop) then begin
meff.DrawEff(m_ObjSurface);
if g_boViewFog then begin
AddLight(meff.rx, meff.ry, 0, 0, meff.light, FALSE);
end;
end;
if g_boViewFog then begin
for k := 0 to EventMan.EventList.count - 1 do begin
evn := TEvent(EventMan.EventList[k]);
if evn.m_nLight > 0 then
AddLight(evn.m_nX, evn.m_nY, 0, 0, evn.m_nLight, FALSE);
end;
end;
except
DebugOutStr('109');
end;
//地面物品闪亮
try
for k := 0 to g_DropedItemList.count - 1 do begin
DropItem := pTDropItem(g_DropedItemList[k]);
if DropItem <> nil then begin
if GetTickCount - DropItem.FlashTime > g_dwDropItemFlashTime {5 * 1000} then begin
DropItem.FlashTime := GetTickCount;
DropItem.BoFlash := True;
DropItem.FlashStepTime := GetTickCount;
DropItem.FlashStep := 0;
end;
ix := (DropItem.X - Map.m_ClientRect.Left) * UNITX + defx + SOFFX;
iy := (DropItem.Y - Map.m_ClientRect.Top - 1) * UNITY + defy + SOFFY;
if DropItem.BoFlash then begin
if GetTickCount - DropItem.FlashStepTime >= 20 then begin
DropItem.FlashStepTime := GetTickCount;
Inc(DropItem.FlashStep);
end;
if (DropItem.FlashStep >= 0) and (DropItem.FlashStep < 10) then begin
dsurface := g_WMainImages.GetCachedImage(FLASHBASE + DropItem.FlashStep, ax, ay);
DrawBlend(m_ObjSurface, ix + ax, iy + ay, dsurface, 1);
end else DropItem.BoFlash := FALSE;
end;
ShowItem := GetShowItem(DropItem.Name);
if (DropItem <> g_FocusItem) and (((ShowItem <> nil) and (ShowItem.boShowName)) { or g_boShowAllItem}) then begin
//显示地面物品名称
if ShowItem <> nil then begin
nFColor := ShowItem.nFColor;
nBColor := ShowItem.nBColor;
end else begin
nFColor := clWhite;
nBColor := clBlack;
end;
with m_ObjSurface.Canvas do begin
SetBkMode(Handle, TRANSPARENT);
BoldTextOut(m_ObjSurface,
ix + HALFX - TextWidth(DropItem.Name) div 2,
iy + HALFY - TextHeight(DropItem.Name) * 2, // div 2,
nFColor,
nBColor,
DropItem.Name);
Release;
end;
end;
end;
end;
except
DebugOutStr('110');
end;
try
// g_boViewFog:=False; //Jacky 免蜡
if g_boViewFog and not g_boForceNotViewFog then begin
ApplyLightMap;
DrawFog(m_ObjSurface, m_PFogScreen, m_nFogWidth);
MSurface.Draw(SOFFX, SOFFY, m_ObjSurface.ClientRect, m_ObjSurface, FALSE);
end else begin
if g_MySelf.m_boDeath then //人物死亡,显示黑白画面
DrawEffect(0, 0, m_ObjSurface.Width, m_ObjSurface.Height, m_ObjSurface, g_DeathColorEffect {ceGrayScale});
MSurface.Draw(SOFFX, SOFFY, m_ObjSurface.ClientRect, m_ObjSurface, FALSE);
end;
except
DebugOutStr('111');
end;
if g_boViewMiniMap then begin
DrawMiniMap(MSurface);
end;
end;
DrawChr画人物都在GetObj这个函数之后,就是说人物总在建筑物后画。。百思不得其解。。。大虾指教啊。。。
|
|