feat/TD-019-add-all-enemies-and-levels
This commit is contained in:
parent
a41c6c5bfa
commit
ad13499d2d
13
src/Makefile
13
src/Makefile
@ -1,14 +1,15 @@
|
||||
FPC = fpc
|
||||
|
||||
CONVBANNERS_SRC = convbanners.pas
|
||||
|
||||
BANNERS_SRC = completed.txt exit.txt keys.txt paused.txt menu.txt \
|
||||
level.txt gameover.txt
|
||||
level.txt gameover.txt
|
||||
|
||||
GAME_SRC = _banners_m.pas arena_graphics_m.pas arena_m.pas \
|
||||
GAME_SRC = _autobanners_m.pas arena_graphics_m.pas arena_m.pas \
|
||||
ascii_arts_m.pas cell_m.pas creature_m.pas enemy_packs_m.pas \
|
||||
game_m.pas ghost_m.pas gohamster.pas graphics_m.pas hamster_m.pas \
|
||||
keys_m.pas level_m.pas math_m.pas sun_m.pas sun_fields_m.pas \
|
||||
trace_m.pas snake_m.pas snake_fields_m.pas drop_m.pas drop_fields_m.pas
|
||||
keys_m.pas level_m.pas math_m.pas sun_m.pas trace_m.pas snake_m.pas \
|
||||
drop_m.pas
|
||||
|
||||
all: gohamster
|
||||
|
||||
@ -18,11 +19,11 @@ play: gohamster
|
||||
gohamster: $(GAME_SRC)
|
||||
$(FPC) $@.pas
|
||||
|
||||
_banners_m.pas: convbanners $(BANNERS_SRC)
|
||||
_autobanners_m.pas: convbanners $(BANNERS_SRC)
|
||||
./convbanners
|
||||
|
||||
convbanners: $(CONVBANNERS_SRC)
|
||||
$(FPC) $@.pas
|
||||
|
||||
clean:
|
||||
rm *.o *.ppu convbanners _banners_m.pas gohamster
|
||||
rm *.o *.ppu convbanners _autobanners_m.pas gohamster
|
||||
|
||||
@ -2,7 +2,7 @@ unit arena_graphics_m;
|
||||
|
||||
interface
|
||||
|
||||
uses arena_m, creature_m, trace_m, level_m, _banners_m;
|
||||
uses arena_m, creature_m, trace_m, level_m, _autobanners_m;
|
||||
|
||||
const
|
||||
ArenaSymbol = ' ';
|
||||
@ -28,6 +28,7 @@ procedure DrawScore(s: integer);
|
||||
procedure EraseStepTrace(var hamster: creature; a: tracePtr);
|
||||
procedure EraseLifesNumber(n: integer);
|
||||
procedure EraseTrace(tp: tracePtr; var a: arena);
|
||||
procedure RedrawInterfaceArea(x: integer; t: creatureType);
|
||||
|
||||
implementation
|
||||
|
||||
@ -58,9 +59,9 @@ const
|
||||
HamsterLifeY = 5;
|
||||
DecimalBase = 10;
|
||||
PauseXPadding = 3 * WidthCoefficient;
|
||||
PauseX = (ScreenW * WidthCoefficient - PauseWidth) div 2;
|
||||
PauseX = (ScreenW * WidthCoefficient - PauseBannerW) div 2;
|
||||
PauseYPadding = 1;
|
||||
PauseY = (ScreenH - PauseHeight) div 2;
|
||||
PauseY = (ScreenH - PauseBannerH) div 2;
|
||||
InterfaceArenaCellX1 = 15;
|
||||
InterfaceArenaCellX2 = 29;
|
||||
|
||||
@ -80,13 +81,16 @@ const
|
||||
lY: 0; rX: 0; rY: GhostHeight div CellSize
|
||||
),
|
||||
(
|
||||
lX: 0; lY: 0; rX: 0; rY: 0
|
||||
lX: -SunWidth div CellSize div WidthCoefficient;
|
||||
lY: -SunHeight div CellSize; rX: 0; rY: 0
|
||||
),
|
||||
(
|
||||
lX: 0; lY: 0; rX: 0; rY: 0
|
||||
lX: -SnakeWidth div CellSize div WidthCoefficient;
|
||||
lY: -SnakeHeight div CellSize; rX: 0; rY: 1
|
||||
),
|
||||
(
|
||||
lX: 0; lY: 0; rX: 0; rY: 0
|
||||
lX: -DropWidth div CellSize div WidthCoefficient;
|
||||
lY: -DropHeight div CellSize; rX: 0; rY: 1
|
||||
)
|
||||
);
|
||||
|
||||
@ -184,24 +188,63 @@ begin
|
||||
DrawFieldCell(x - 1, -1, ' ')
|
||||
end;
|
||||
|
||||
procedure RedrawInterfaceArea(x: integer);
|
||||
procedure EraseSunInterface(x: integer);
|
||||
begin
|
||||
EraseHamsterInterface(x);
|
||||
if (x = 1) or (x = 2) then
|
||||
DrawLineY(1, InterfaceBarH - HamsterHeight,
|
||||
HamsterHeight, BorderSymbol)
|
||||
else
|
||||
if x = InterfaceArenaCellX1 then
|
||||
DrawLineY(InterfaceCellW * WidthCoefficient,
|
||||
InterfaceBarH - HamsterHeight, HamsterHeight, BorderSymbol)
|
||||
else
|
||||
if x = InterfaceArenaCellX2 then
|
||||
DrawLineY(InterfaceCellW * 2 * WidthCoefficient + 1,
|
||||
InterfaceBarH - HamsterHeight, HamsterHeight, BorderSymbol)
|
||||
else
|
||||
if x = ArenaW then
|
||||
DrawLineY(ArenaW * CellSize * WidthCoefficient,
|
||||
InterfaceBarH - HamsterHeight, HamsterHeight, BorderSymbol)
|
||||
if x <= 0 then
|
||||
exit;
|
||||
DrawFieldCell(x, 0, ' ');
|
||||
DrawFieldCell(x - 1, 0, ' ')
|
||||
end;
|
||||
|
||||
procedure RedrawEnemyInterfaceArea(x: integer);
|
||||
var
|
||||
h: integer = SunHeight div 2;
|
||||
begin
|
||||
EraseSunInterface(x);
|
||||
if (x = 1) or (x = 2) then
|
||||
DrawLineY(1, InterfaceBarH - h, h, BorderSymbol)
|
||||
else
|
||||
if (x = InterfaceArenaCellX1) or (x = InterfaceArenaCellX1 + -1) then
|
||||
DrawLineY(InterfaceCellW * WidthCoefficient,
|
||||
InterfaceBarH - h, h, BorderSymbol)
|
||||
else
|
||||
if (x = InterfaceArenaCellX2) or (x = InterfaceArenaCellX2 - 1) then
|
||||
DrawLineY(InterfaceCellW * 2 * WidthCoefficient + 1,
|
||||
InterfaceBarH - h, h, BorderSymbol)
|
||||
else
|
||||
if x = ArenaW then
|
||||
DrawLineY(ArenaW * CellSize * WidthCoefficient,
|
||||
InterfaceBarH - h, h, BorderSymbol)
|
||||
end;
|
||||
|
||||
procedure RedrawHamsterInterfaceArea(x: integer);
|
||||
begin
|
||||
EraseHamsterInterface(x);
|
||||
if (x = 1) or (x = 2) then
|
||||
DrawLineY(1, InterfaceBarH - HamsterHeight,
|
||||
HamsterHeight, BorderSymbol)
|
||||
else
|
||||
if x = InterfaceArenaCellX1 then
|
||||
DrawLineY(InterfaceCellW * WidthCoefficient,
|
||||
InterfaceBarH - HamsterHeight, HamsterHeight, BorderSymbol)
|
||||
else
|
||||
if x = InterfaceArenaCellX2 then
|
||||
DrawLineY(InterfaceCellW * 2 * WidthCoefficient + 1,
|
||||
InterfaceBarH - HamsterHeight, HamsterHeight, BorderSymbol)
|
||||
else
|
||||
if x = ArenaW then
|
||||
DrawLineY(ArenaW * CellSize * WidthCoefficient,
|
||||
InterfaceBarH - HamsterHeight, HamsterHeight, BorderSymbol)
|
||||
end;
|
||||
|
||||
procedure RedrawInterfaceArea(x: integer; t: creatureType);
|
||||
begin
|
||||
case t of
|
||||
creatureHamster:
|
||||
RedrawHamsterInterfaceArea(x);
|
||||
creatureSun, creatureSnake, creatureDrop:
|
||||
RedrawEnemyInterfaceArea(x)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure RedrawArea(var a: arena; arenaX, arenaY: integer; t: creatureType);
|
||||
@ -217,8 +260,6 @@ begin
|
||||
if (arenaX + j > 0) and (arenaX + j < ArenaW + 1) and
|
||||
(arenaY + i > 0) and (arenaY + i < ArenaH + 1) then
|
||||
begin
|
||||
if (t = creatureHamster) and (arenaY + i = 1) then
|
||||
RedrawInterfaceArea(arenaX + j);
|
||||
DrawArenaCell(arenaX + j, arenaY + i, a)
|
||||
end
|
||||
end
|
||||
@ -232,6 +273,8 @@ begin
|
||||
{Later move to erase hamster}
|
||||
arenaX := h.curX - h.dX;
|
||||
arenaY := h.curY - h.dY;
|
||||
if arenaY = 1 then
|
||||
RedrawInterfaceArea(arenaX, h.t);
|
||||
RedrawArea(a, arenaX, arenaY, h.t);
|
||||
if t <> nil then
|
||||
DrawTrace(t);
|
||||
@ -262,14 +305,15 @@ procedure DrawPause;
|
||||
begin
|
||||
EraseRectangle(PauseX - PauseXPadding,
|
||||
PauseY - PauseYPadding,
|
||||
PauseWidth + PauseXPadding * 2,
|
||||
PauseHeight + PauseYPadding * 2 + 1);
|
||||
PauseBannerW + PauseXPadding * 2,
|
||||
PauseBannerH + PauseYPadding * 2 + 1);
|
||||
DrawRectangle(PauseX - PauseXPadding,
|
||||
PauseY - PauseYPadding,
|
||||
PauseHeight + PauseYPadding * 2 + 1,
|
||||
PauseWidth + PauseXPadding * 2,
|
||||
PauseBannerH + PauseYPadding * 2 + 1,
|
||||
PauseBannerW + PauseXPadding * 2,
|
||||
BorderSymbol);
|
||||
DrawBannerImage(PauseX, PauseY, PauseHeight, PauseAscii)
|
||||
DrawBannerImage(PauseX, PauseY, PauseBannerH, PauseBanner);
|
||||
GotoXY(1, 1)
|
||||
end;
|
||||
|
||||
procedure DrawTrace(a: tracePtr);
|
||||
@ -358,8 +402,8 @@ procedure ErasePause;
|
||||
begin
|
||||
EraseRectangle(PauseX - PauseXPadding,
|
||||
PauseY - PauseYPadding,
|
||||
PauseWidth + PauseXPadding * 2,
|
||||
PauseHeight + PauseYPadding * 2 + 1)
|
||||
PauseBannerW + PauseXPadding * 2,
|
||||
PauseBannerH + PauseYPadding * 2 + 1)
|
||||
end;
|
||||
|
||||
procedure DrawLevelUnpause(var level: levelState);
|
||||
@ -388,8 +432,7 @@ begin
|
||||
write(symbol)
|
||||
end
|
||||
end
|
||||
end;
|
||||
GotoXY(1, 1)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure DrawArenaEdges;
|
||||
@ -515,7 +558,7 @@ end;
|
||||
procedure DrawHamsterRunX(var h: creature);
|
||||
var
|
||||
xIdx: integer;
|
||||
img: ^CreatureImage;
|
||||
img: ^creatureImage;
|
||||
begin
|
||||
if h.dX = 0 then
|
||||
exit;
|
||||
@ -532,7 +575,7 @@ end;
|
||||
procedure DrawHamsterRunY(var h: creature);
|
||||
var
|
||||
yIdx: integer;
|
||||
img: ^CreatureImage;
|
||||
img: ^creatureImage;
|
||||
begin
|
||||
if h.dY = 0 then
|
||||
exit;
|
||||
@ -558,7 +601,8 @@ begin
|
||||
DrawHamsterRunX(h)
|
||||
else
|
||||
if h.dY <> 0 then
|
||||
DrawHamsterRunY(h)
|
||||
DrawHamsterRunY(h);
|
||||
GotoXY(1, 1)
|
||||
end;
|
||||
|
||||
procedure DrawGhost(var g: creature);
|
||||
@ -574,23 +618,41 @@ end;
|
||||
|
||||
procedure DrawSun(var g: creature);
|
||||
var
|
||||
asciiIdx: integer;
|
||||
asciiIdx, h: integer;
|
||||
img: ^creatureImage;
|
||||
begin
|
||||
asciiIdx := g.curX div g.moveSpeed mod SunRunN + 1;
|
||||
if g.rageMode then
|
||||
begin
|
||||
img := @(GoidaSunAscii);
|
||||
h := GoidaSunHeight
|
||||
end
|
||||
else
|
||||
begin
|
||||
asciiIdx := g.curX div g.moveSpeed mod SunRunN + 1;
|
||||
img := @(SunAscii[asciiIdx]);
|
||||
h := SunHeight
|
||||
end;
|
||||
DrawFieldAscii(g.curX - SunWidth div WidthCoefficient div 2,
|
||||
g.curY - SunHeight div 2 + 1,
|
||||
SunHeight, SunWidth, SunAscii[asciiIdx])
|
||||
|
||||
g.curY - h div 2 + 1, h, SunWidth, img^)
|
||||
end;
|
||||
|
||||
{
|
||||
procedure DrawEnemy(var e: creature);
|
||||
procedure DrawSnake(var g: creature);
|
||||
var
|
||||
asciiIdx: integer;
|
||||
begin
|
||||
asciiIdx := e.curX div e.moveSpeed mod;
|
||||
asciiIdx := g.curX div g.moveSpeed mod SnakeRunN + 1;
|
||||
DrawFieldAscii(g.curX - SnakeWidth div WidthCoefficient div 2,
|
||||
g.curY - SnakeHeight div 2 + 1,
|
||||
SnakeHeight, SnakeWidth, SnakeAscii[asciiIdx])
|
||||
|
||||
end;
|
||||
|
||||
procedure DrawDrop(var g: creature);
|
||||
begin
|
||||
DrawFieldAscii(g.curX - DropWidth div WidthCoefficient div 2,
|
||||
g.curY - DropHeight div 2 + 1, DropHeight,
|
||||
DropWidth, DropAscii)
|
||||
end;
|
||||
}
|
||||
|
||||
procedure DrawCreature(var cr: creature);
|
||||
begin
|
||||
@ -600,7 +662,11 @@ begin
|
||||
creatureGhost:
|
||||
DrawGhost(cr);
|
||||
creatureSun:
|
||||
DrawSun(cr)
|
||||
DrawSun(cr);
|
||||
creatureSnake:
|
||||
DrawSnake(cr);
|
||||
creatureDrop:
|
||||
DrawDrop(cr)
|
||||
end
|
||||
end;
|
||||
|
||||
|
||||
169
src/arena_m.pas
169
src/arena_m.pas
@ -2,7 +2,7 @@ unit arena_m;
|
||||
|
||||
interface
|
||||
|
||||
uses creature_m, trace_m;
|
||||
uses creature_m, cell_m, trace_m;
|
||||
|
||||
const
|
||||
ArenaH = 33;
|
||||
@ -32,13 +32,11 @@ procedure MakeEnemySteps(var a: arena; var h: creature;
|
||||
procedure MakeHamsterStep(var h: creature; var t: tracePtr; var a: arena);
|
||||
procedure SetArenaBorder(var t: tracePtr; var a: arena);
|
||||
procedure TurnStubbornEnemies(var a: arena; var e: creatureList);
|
||||
procedure MakeStep(var a: arena; var cr: creature);
|
||||
|
||||
|
||||
procedure MakeStep(var a: arena; var enemy: creature);
|
||||
|
||||
implementation
|
||||
|
||||
uses arena_graphics_m, cell_m, crt, graphics_m, math_m, Math;
|
||||
uses arena_graphics_m, crt, graphics_m, snake_m, drop_m, math_m, Math;
|
||||
|
||||
const
|
||||
MaxTurnAttempts = 3;
|
||||
@ -413,29 +411,14 @@ begin
|
||||
DrawAfterHamsterStep(h, t, a)
|
||||
end;
|
||||
|
||||
function GhostShouldTurn(var g: creature; var a: arena): boolean;
|
||||
var
|
||||
nextX, nextY: integer;
|
||||
begin
|
||||
nextX := g.curX + g.dX;
|
||||
nextY := g.curY + g.dY;
|
||||
GhostShouldTurn := StepBeyondEdge(g) or
|
||||
a.borders[g.curY][g.curX] and a.captured[nextY][nextX]
|
||||
end;
|
||||
|
||||
function SunShouldTurn(var g: creature; var a: arena): boolean;
|
||||
begin
|
||||
SunShouldTurn := true
|
||||
end;
|
||||
|
||||
function VerticalBorder(nextX, nextY: integer; var a: arena): boolean;
|
||||
function VerticalBorder(var a: arena; nextX, nextY: integer): boolean;
|
||||
begin
|
||||
VerticalBorder :=
|
||||
a.borders[nextY][nextX] and
|
||||
(a.borders[nextY - 1][nextX] or a.borders[nextY + 1][nextX])
|
||||
end;
|
||||
|
||||
function HorizontalBorder(nextX, nextY: integer; var a: arena): boolean;
|
||||
function HorizontalBorder(var a: arena; nextX, nextY: integer): boolean;
|
||||
begin
|
||||
HorizontalBorder :=
|
||||
a.borders[nextY][nextX] and
|
||||
@ -444,30 +427,39 @@ end;
|
||||
|
||||
function IsCorner(x, y: integer; var a: arena): boolean;
|
||||
begin
|
||||
IsCorner := HorizontalBorder(x, y, a) and VerticalBorder(x, y, a)
|
||||
IsCorner := HorizontalBorder(a, x, y) and VerticalBorder(a, x, y)
|
||||
end;
|
||||
|
||||
procedure TurnGhost(var g: creature; var a: arena);
|
||||
procedure TpDrop(var a: arena; var e: creature);
|
||||
var
|
||||
nx, ny: integer;
|
||||
begin
|
||||
if (OnEdgeX(g.curX) or VerticalBorder(g.curX, g.curY, a)) then
|
||||
g.dX := g.dX * -1;
|
||||
if (OnEdgeY(g.curY) or HorizontalBorder(g.curX, g.curY, a)) then
|
||||
g.dY := g.dY * -1
|
||||
while true do
|
||||
begin
|
||||
nx := RandomLR(1, ArenaW);
|
||||
ny := RandomLR(1, ArenaH);
|
||||
if not a.captured[ny][nx] then
|
||||
break
|
||||
end;
|
||||
e.curX := nx;
|
||||
e.curY := ny
|
||||
end;
|
||||
|
||||
procedure TurnSun(var g: creature; var a: arena);
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure MakeEnemyStep(var a: arena; var e, h: creature; t: tracePtr);
|
||||
procedure MakeEnemyStep(var a: arena; var e, hamster: creature; t: tracePtr);
|
||||
var
|
||||
prevX, prevY: integer;
|
||||
begin
|
||||
if (e.t = creatureDrop) and (e.beforeTransform = 0) then
|
||||
begin
|
||||
TpDrop(a, e);
|
||||
exit
|
||||
end;
|
||||
|
||||
prevX := e.curX;
|
||||
prevY := e.curY;
|
||||
MakeStep(a, e);
|
||||
if TraceCrossed(prevX, prevY, e, t) then
|
||||
h.alive := false
|
||||
hamster.alive := false
|
||||
end;
|
||||
|
||||
procedure KillCapturedEnemies(var a: arena; var e: creatureList);
|
||||
@ -483,24 +475,95 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
procedure TurnOtherwise(var a: arena; var g: creature);
|
||||
begin
|
||||
if (OnEdgeX(g.curX) or VerticalBorder(a, g.curX, g.curY)) then
|
||||
g.dX := g.dX * -1;
|
||||
if (OnEdgeY(g.curY) or HorizontalBorder(a, g.curX, g.curY)) then
|
||||
g.dY := g.dY * -1
|
||||
end;
|
||||
|
||||
procedure SetVerticalMove(var g: creature; ms: integer);
|
||||
begin
|
||||
g.dX := 0;
|
||||
g.dY := ms;
|
||||
if RandomBool then
|
||||
g.dY := -g.dY
|
||||
end;
|
||||
|
||||
procedure SetHorizontalMove(var g: creature; ms: integer);
|
||||
begin
|
||||
g.dX := ms;
|
||||
g.dY := 0;
|
||||
if RandomBool then
|
||||
g.dX := -g.dX
|
||||
end;
|
||||
|
||||
procedure TurnToDiagonal(var g: creature; ms: integer);
|
||||
begin
|
||||
if (g.dX <> 0) and (g.dY <> 0) then
|
||||
begin
|
||||
g.dX := -g.dX;
|
||||
g.dY := -g.dY
|
||||
end
|
||||
else
|
||||
begin
|
||||
g.dX := ms;
|
||||
if RandomBool then
|
||||
g.dX := -g.dX;
|
||||
g.dY := ms;
|
||||
if RandomBool then
|
||||
g.dY := -g.dY
|
||||
end
|
||||
end;
|
||||
|
||||
procedure EightDimensionTurn(var a: arena; var g: creature;
|
||||
var diagonalMove: boolean; ms: integer);
|
||||
begin
|
||||
if RandomBool then
|
||||
diagonalMove := not diagonalMove;
|
||||
if diagonalMove then
|
||||
begin
|
||||
TurnToDiagonal(g, ms)
|
||||
end
|
||||
else
|
||||
begin
|
||||
if OnEdgeX(g.curX) or VerticalBorder(a, g.curX, g.curY) then
|
||||
SetVerticalMove(g, ms)
|
||||
else
|
||||
SetHorizontalMove(g, ms)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure TurnEnemy(var cr: creature; var a: arena);
|
||||
begin
|
||||
case cr.t of
|
||||
creatureGhost:
|
||||
TurnGhost(cr, a);
|
||||
TurnOtherwise(a, cr);
|
||||
creatureSun:
|
||||
TurnGhost(cr, a)
|
||||
TurnOtherwise(a, cr);
|
||||
creatureSnake, creatureDrop:
|
||||
begin
|
||||
if cr.t = creatureSnake then
|
||||
EightDimensionTurn(a, cr, cr.diagonalMove, SnakeMovespeed)
|
||||
else
|
||||
EightDimensionTurn(a, cr, cr.diagonalMove, DropMovespeed)
|
||||
end;
|
||||
end
|
||||
end;
|
||||
|
||||
function EnemyShouldTurn(var cr: creature; var a: arena): boolean;
|
||||
function EnemyShouldTurn(var e: creature; var a: arena): boolean;
|
||||
var
|
||||
oldX, oldY, newX, newY: integer;
|
||||
begin
|
||||
case cr.t of
|
||||
creatureGhost:
|
||||
EnemyShouldTurn := GhostShouldTurn(cr, a);
|
||||
creatureSun:
|
||||
EnemyShouldTurn := GhostShouldTurn(cr, a)
|
||||
end
|
||||
oldX := e.curX;
|
||||
oldY := e.curY;
|
||||
MakeStep(a, e);
|
||||
newX := e.curX;
|
||||
newY := e.curY;
|
||||
e.curX := oldX;
|
||||
e.curY := oldY;
|
||||
EnemyShouldTurn := (oldX = newX) and (oldY = newY)
|
||||
end;
|
||||
|
||||
procedure TurnStubbornEnemies(var a: arena; var e: creatureList);
|
||||
@ -529,6 +592,8 @@ begin
|
||||
tmp := e.first;
|
||||
while tmp <> nil do
|
||||
begin
|
||||
if tmp^.cr^.curY = 1 then
|
||||
RedrawInterfaceArea(tmp^.cr^.curX, tmp^.cr^.t);
|
||||
if tmp^.cr^.alive and not EnemyShouldTurn(tmp^.cr^, a) then
|
||||
RedrawArea(a, tmp^.cr^.curX, tmp^.cr^.curY, tmp^.cr^.t);
|
||||
tmp := tmp^.next
|
||||
@ -549,19 +614,19 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
procedure MakeStep(var a: arena; var cr: creature);
|
||||
procedure MakeStep(var a: arena; var enemy: creature);
|
||||
var
|
||||
absDx, absDy, maxD, stepX, stepY, i, nX, nY: integer;
|
||||
begin
|
||||
absDx := Abs(cr.dX);
|
||||
absDy := Abs(cr.dY);
|
||||
absDx := Abs(enemy.dX);
|
||||
absDy := Abs(enemy.dY);
|
||||
maxD := Max(absDx, absDy);
|
||||
stepX := Signum(cr.dX, 0);
|
||||
stepY := Signum(cr.dY, 0);
|
||||
stepX := Signum(enemy.dX, 0);
|
||||
stepY := Signum(enemy.dY, 0);
|
||||
for i := 1 to maxD do
|
||||
begin
|
||||
nX := cr.curX + stepX;
|
||||
nY := cr.curY + stepY;
|
||||
nX := enemy.curX + stepX;
|
||||
nY := enemy.curY + stepY;
|
||||
if a.captured[nY][nX] or (nX < 1) or (nX > ArenaW) or
|
||||
(nY < 1) or (nY > ArenaH) then
|
||||
begin
|
||||
@ -569,8 +634,8 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
cr.curX := nX;
|
||||
cr.curY := nY
|
||||
enemy.curX := nX;
|
||||
enemy.curY := nY
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
@ -244,7 +244,7 @@ const
|
||||
)
|
||||
);
|
||||
|
||||
SunHeight = 5;
|
||||
SunHeight = 4;
|
||||
SunWidth = 7;
|
||||
SunRunN = 2;
|
||||
SunAscii: array[1..SunRunN] of CreatureImage = (
|
||||
@ -253,28 +253,55 @@ const
|
||||
' / \',
|
||||
'<|o o|>',
|
||||
' \_^_/',
|
||||
' V'
|
||||
''
|
||||
),
|
||||
(
|
||||
' _A_',
|
||||
' / \',
|
||||
'{|o o|}',
|
||||
'{-o o-}',
|
||||
' \_^_/',
|
||||
' v'
|
||||
)
|
||||
);
|
||||
|
||||
RageSunHeight = 4;
|
||||
RageSunRunN = 1;
|
||||
RageSunAscii: array[1..RageSunRunN] of CreatureImage = (
|
||||
(
|
||||
' ___',
|
||||
' / Z \',
|
||||
'||> <||',
|
||||
' \___/',
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
GoidaSunHeight = 4;
|
||||
GoidaSunAscii: CreatureImage = (
|
||||
' ___',
|
||||
' / Z \',
|
||||
'||> <||',
|
||||
' \___/',
|
||||
''
|
||||
);
|
||||
|
||||
SnakeHeight = 5;
|
||||
SnakeWidth = 7;
|
||||
SnakeRunN = 2;
|
||||
SnakeAscii: array[1..SnakeRunN] of CreatureImage = (
|
||||
(
|
||||
' /v\ ',
|
||||
'3 |o |',
|
||||
'\\ \ / ',
|
||||
' \\_\\ ',
|
||||
' \_// '
|
||||
),
|
||||
(
|
||||
' /v\ ',
|
||||
' o ',
|
||||
'\\ \ / ',
|
||||
' ',
|
||||
' \_// '
|
||||
)
|
||||
);
|
||||
|
||||
DropHeight = 5;
|
||||
DropWidth = 7;
|
||||
DropAscii: CreatureImage = (
|
||||
' _',
|
||||
' / \',
|
||||
' / \',
|
||||
'/ 0_0 \',
|
||||
'\_____/'
|
||||
);
|
||||
|
||||
implementation
|
||||
end.
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
GameCompleteScoreWidth 50
|
||||
== BANNER START ==
|
||||
' _____ _ _ _ ',
|
||||
' / ____| | | | | | |',
|
||||
'| | __ __ _ _ __ ___ ___ ___ ___ _ __ ___ _ __ | | ___| |_ ___| |',
|
||||
|
||||
@ -1,28 +1,40 @@
|
||||
program convbanners;
|
||||
|
||||
uses Math;
|
||||
|
||||
const
|
||||
BannerModuleName = '_banners_m.pas';
|
||||
GameCompleteFile = 'completed.txt';
|
||||
ExitFile = 'exit.txt';
|
||||
KeysFile = 'keys.txt';
|
||||
|
||||
AutobannerModuleName = '_autobanners_m.pas';
|
||||
|
||||
BannerStartS = '== BANNER START ==';
|
||||
BannersN = 7;
|
||||
MenuFile = 'menu.txt';
|
||||
GameOverFile = 'gameover.txt';
|
||||
PausedFile = 'paused.txt';
|
||||
LevelFile = 'level.txt';
|
||||
PauseFile = 'paused.txt';
|
||||
GameOverFile = 'gameover.txt';
|
||||
GameCompleteFile = 'completed.txt';
|
||||
KeyInfoFile = 'keys.txt';
|
||||
ExitFile = 'exit.txt';
|
||||
BannerFiles: array[1..BannersN] of string = (
|
||||
MenuFile, LevelFile, PauseFile, GameOverFile,
|
||||
GameCompleteFile, KeyInfoFile, ExitFile
|
||||
);
|
||||
|
||||
MenuVarsPrefix = 'MenuBanner';
|
||||
LevelVarsPrefix = 'LevelAnnounceBanner';
|
||||
PauseVarsPrefix = 'PauseBanner';
|
||||
GameOverVarsPrefix = 'GameOverBanner';
|
||||
GameCompleteVarsPrefix = 'GameCompleteBanner';
|
||||
KeysVarsPrefix = 'KeysInfoBanner';
|
||||
ExitVarsPrefix = 'ExitBanner';
|
||||
VarsPrefixes: array[1..BannersN] of string = (
|
||||
MenuVarsPrefix, LevelVarsPrefix, PauseVarsPrefix, GameOverVarsPrefix,
|
||||
GameCompleteVarsPrefix, KeysVarsPrefix, ExitVarsPrefix
|
||||
);
|
||||
|
||||
DecimalBase = 10;
|
||||
AfterImageLinesN = 2;
|
||||
|
||||
|
||||
ModuleBeginH = 13;
|
||||
|
||||
{
|
||||
const
|
||||
MaxBannerWidth = KeyInfoWidth;
|
||||
MaxBannerHeight = KeyInfoHeight;
|
||||
type
|
||||
BannerImage = array[1..MaxBannerHeight] of string[MaxBannerWidth];
|
||||
}
|
||||
|
||||
|
||||
ModuleBegin: array[1..ModuleBeginH] of string = (
|
||||
'{ ************************************************** }',
|
||||
'{ ************************************************** }',
|
||||
@ -33,104 +45,19 @@ type
|
||||
'{ *** *** }',
|
||||
'{ ************************************************** }',
|
||||
'{ ************************************************** }',
|
||||
'unit _banners_m;',
|
||||
'unit _autobanners_m;',
|
||||
'',
|
||||
'interface',
|
||||
'const'
|
||||
);
|
||||
|
||||
KeyInfoCodeH = 10;
|
||||
BannersKeyInfo: array[1..KeyInfoCodeH] of string = (
|
||||
'KeyInfoHeight = 42;',
|
||||
'KeyInfoWidth = 98;',
|
||||
'MaxBannerHeight = KeyInfoHeight;',
|
||||
'MaxBannerWidth = KeyInfoWidth;',
|
||||
'type',
|
||||
'BannerImage = array[1..MaxBannerHeight] of string[MaxBannerWidth];',
|
||||
'const',
|
||||
'KeyInfoScreen: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
{
|
||||
KeyInfoCodeH = 5;
|
||||
BannersKeyInfo: array[1..KeyInfoCodeH] of string = (
|
||||
'KeyInfoHeight = 42;',
|
||||
'KeyInfoWidth = 98;',
|
||||
'KeyInfoScreen: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
}
|
||||
BannerImageTypeStr =
|
||||
'BannerImage = array[1..MaxBannerHeight] of string[MaxBannerWidth];';
|
||||
|
||||
ExitCodeH = 6;
|
||||
BannersExit: array[1..ExitCodeH] of string = (
|
||||
'ExitScreenHeight = 16;',
|
||||
'ExitWidth = 70;',
|
||||
'ExitHeight = 8;',
|
||||
'ExitScreen: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
PauseCodeH = 5;
|
||||
BannersPause: array[1..PauseCodeH] of string = (
|
||||
'PauseHeight = 22;',
|
||||
'PauseWidth = 76;',
|
||||
'PauseAscii: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
CompleteCodeH = 6;
|
||||
BannersGameComplete: array[1..CompleteCodeH] of string = (
|
||||
'GameCompleteHeight = 14;',
|
||||
'GameCompleteWidth = 74;',
|
||||
'GameCompleteScoreWidth = 50;',
|
||||
'GameComplete: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
MenuCodeH = 11;
|
||||
BannersMenu: array[1..MenuCodeH] of string = (
|
||||
'GameMenuHeight = 36;',
|
||||
'GameNameHeight = 6;',
|
||||
'GameNameWidth = 58;',
|
||||
'NewGameHeight = 6;',
|
||||
'HighScoreHeight = 8;',
|
||||
'MenuInfoHeight = 8;',
|
||||
'ContinueHeight = 6;',
|
||||
'ContinueWidth = 41;',
|
||||
'GameMenuScreen: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
GameOverCodeH = 5;
|
||||
BannersGameOver: array[1..GameOverCodeH] of string = (
|
||||
'GameOverHeight = 40;',
|
||||
'GameOverWidth = 63;',
|
||||
'GameOverScreen: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
LevelCodeH = 5;
|
||||
BannersLevel: array[1..LevelCodeH] of string = (
|
||||
'LevelAnnounceHeight = 6;',
|
||||
'LevelAnnounceWidth = 24;',
|
||||
'LevelAnnounce: BannerImage = (',
|
||||
');',
|
||||
''
|
||||
);
|
||||
|
||||
ModuleEndH = 3;
|
||||
ModuleEndH = 2;
|
||||
ModuleEnd: array[1..ModuleEndH] of string = (
|
||||
'implementation',
|
||||
'end.',
|
||||
''
|
||||
'end.'
|
||||
);
|
||||
|
||||
procedure AppendText(var f: text; var t: array of string; h: integer);
|
||||
@ -141,55 +68,185 @@ begin
|
||||
writeln(f, t[i - 1])
|
||||
end;
|
||||
|
||||
procedure ConcatenateFiles(var fTo: text; var filename: string);
|
||||
function ParsedStrLength(var s: string): integer;
|
||||
var
|
||||
res: integer = 0;
|
||||
backtickCnt: integer = 0;
|
||||
i, sLen: integer;
|
||||
begin
|
||||
sLen := Length(s);
|
||||
res := sLen;
|
||||
for i := 1 to Length(s) do
|
||||
if s[i] = '''' then
|
||||
backtickCnt := backtickCnt + 1;
|
||||
if s[sLen] = ',' then
|
||||
res := res - 1;
|
||||
res := res - 2; {Subtract first and last '}
|
||||
backtickCnt := backtickCnt - 2; {Subtract first and last '}
|
||||
ParsedStrLength := res - (backtickCnt div 2)
|
||||
end;
|
||||
|
||||
procedure GetMaxBannersDimensions(var h, w: integer);
|
||||
var
|
||||
i, len: integer;
|
||||
curH: integer = 0;
|
||||
t: text;
|
||||
ln: string;
|
||||
fFrom: text;
|
||||
isBanner: boolean = false;
|
||||
begin
|
||||
assign(fFrom, fileName);
|
||||
reset(fFrom);
|
||||
while not eof(fFrom) do
|
||||
h := 0;
|
||||
w := 0;
|
||||
for i := 1 to BannersN do
|
||||
begin
|
||||
readln(fFrom, ln);
|
||||
writeln(fTo, ln)
|
||||
curH := 0;
|
||||
isBanner := false;
|
||||
assign(t, BannerFiles[i]);
|
||||
reset(t);
|
||||
while not eof(t) do
|
||||
begin
|
||||
readln(t, ln);
|
||||
if not isBanner then
|
||||
begin
|
||||
isBanner := (ln = BannerStartS);
|
||||
continue
|
||||
end;
|
||||
curH := curH + 1;
|
||||
len := ParsedStrLength(ln);
|
||||
w := Max(w, len);
|
||||
if len > 0 then
|
||||
h := max(h, curH)
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
procedure AppendAsciiBanner(var f: text; var t: array of string;
|
||||
h: integer; fileName: string);
|
||||
var
|
||||
i: integer;
|
||||
procedure AppendMaxBannersDimensions(var t: text; maxH, maxW: integer);
|
||||
begin
|
||||
for i := 1 to h do
|
||||
writeln(t, 'MaxBannerHeight = ', maxH, ';');
|
||||
writeln(t, 'MaxBannerWidth = ', maxW, ';');
|
||||
writeln(t, '')
|
||||
end;
|
||||
|
||||
procedure AppendBannersType(var t: text);
|
||||
begin
|
||||
writeln(t, 'type');
|
||||
writeln(t, BannerImageTypeStr);
|
||||
writeln(t, '')
|
||||
end;
|
||||
|
||||
procedure GetBannerDimensions(var fileName: string; var h, w: integer);
|
||||
var
|
||||
sLen: integer;
|
||||
hNow: integer = 0;
|
||||
fileFrom: text;
|
||||
ln: string;
|
||||
isBanner: boolean = false;
|
||||
begin
|
||||
w := 0;
|
||||
h := 0;
|
||||
assign(fileFrom, fileName);
|
||||
reset(fileFrom);
|
||||
while not eof(fileFrom) do
|
||||
begin
|
||||
writeln(f, t[i - 1]);
|
||||
if i = h - AfterImageLinesN then
|
||||
ConcatenateFiles(f, fileName)
|
||||
readln(fileFrom, ln);
|
||||
if not isBanner then
|
||||
begin
|
||||
isBanner := (ln = BannerStartS);
|
||||
continue
|
||||
end;
|
||||
sLen := ParsedStrLength(ln);
|
||||
w := Max(w, sLen);
|
||||
hNow := hNow + 1;
|
||||
if sLen > 0 then
|
||||
h := hNow
|
||||
end
|
||||
end;
|
||||
|
||||
procedure CreateBannerModule;
|
||||
procedure ParseNum(var ln, res: string; idx: integer);
|
||||
var
|
||||
i, n: integer;
|
||||
begin
|
||||
n := Length(ln);
|
||||
for i := idx to n do
|
||||
begin
|
||||
if (ln[i] <= '0') or (ln[i] >= '9') then
|
||||
begin
|
||||
res := copy(ln, idx, i - 1);
|
||||
break
|
||||
end;
|
||||
if i = n then
|
||||
res := copy(ln, idx, i)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure TryAddConst(var fileTo: text; var ln: string);
|
||||
var
|
||||
idx: integer = 1;
|
||||
lenS: integer;
|
||||
num: string;
|
||||
constName: string = '';
|
||||
begin
|
||||
lenS := Length(ln);
|
||||
while (idx <= lenS) do
|
||||
begin
|
||||
if ln[idx] = ' ' then
|
||||
break;
|
||||
idx := idx + 1
|
||||
end;
|
||||
if (idx >= lenS) or (idx = 1) then
|
||||
exit;
|
||||
constName := copy(ln, 1, idx - 1);
|
||||
ParseNum(ln, num, idx + 1);
|
||||
writeln(fileTo, constName, ' = ', num, ';')
|
||||
end;
|
||||
|
||||
procedure AppendBanner(var fileTo: text; var fileName, varPrefix: string);
|
||||
var
|
||||
w, h: integer;
|
||||
isBanner: boolean = false;
|
||||
fileFrom: text;
|
||||
ln: string;
|
||||
begin
|
||||
GetBannerDimensions(fileName, h, w);
|
||||
writeln(fileTo, varPrefix, 'H = ', h, ';');
|
||||
writeln(fileTo, varPrefix, 'W = ', w, ';');
|
||||
assign(fileFrom, fileName);
|
||||
reset(fileFrom);
|
||||
while not isBanner do
|
||||
begin
|
||||
readln(fileFrom, ln);
|
||||
isBanner := (ln = BannerStartS);
|
||||
if not isBanner and (Length(ln) > 0) then
|
||||
TryAddConst(fileTo, ln)
|
||||
end;
|
||||
writeln(fileTo, varPrefix, ': BannerImage = (');
|
||||
while not eof(fileFrom) do
|
||||
begin
|
||||
readln(fileFrom, ln);
|
||||
writeln(fileTo, ln)
|
||||
end;
|
||||
writeln(fileTo, ');');
|
||||
writeln(fileTo, '');
|
||||
end;
|
||||
|
||||
procedure CreateAutobannerModule;
|
||||
var
|
||||
i, maxH, maxW: integer;
|
||||
newModule: text;
|
||||
begin
|
||||
assign(newModule, BannerModuleName);
|
||||
assign(newModule, AutobannerModuleName);
|
||||
rewrite(newModule);
|
||||
AppendText(newModule, ModuleBegin, ModuleBeginH);
|
||||
AppendAsciiBanner(newModule, BannersKeyInfo, KeyInfoCodeH, KeysFile);
|
||||
AppendAsciiBanner(newModule, BannersExit, ExitCodeH, ExitFile);
|
||||
AppendAsciiBanner(newModule, BannersPause, PauseCodeH, PausedFile);
|
||||
AppendAsciiBanner(newModule, BannersGameComplete, CompleteCodeH,
|
||||
GameCompleteFile);
|
||||
AppendAsciiBanner(newModule, BannersMenu, MenuCodeH, MenuFile);
|
||||
AppendAsciiBanner(newModule, BannersGameOver, GameOverCodeH, GameOverFile);
|
||||
|
||||
AppendAsciiBanner(newModule, BannersLevel, LevelCodeH, LevelFile);
|
||||
|
||||
writeln(newModule, 'const');
|
||||
GetMaxBannersDimensions(maxH, maxW);
|
||||
AppendMaxBannersDimensions(newModule, maxH, maxW);
|
||||
AppendBannersType(newModule);
|
||||
writeln(newModule, 'const');
|
||||
for i := 1 to BannersN do
|
||||
AppendBanner(newModule, BannerFiles[i], VarsPrefixes[i]);
|
||||
AppendText(newModule, ModuleEnd, ModuleEndH);
|
||||
close(newModule)
|
||||
end;
|
||||
|
||||
begin
|
||||
CreateBannerModule
|
||||
CreateAutobannerModule
|
||||
end.
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@ unit creature_m;
|
||||
|
||||
interface
|
||||
|
||||
uses sun_fields_m, snake_fields_m, drop_fields_m;
|
||||
|
||||
type
|
||||
creatureType = (creatureHamster, creatureGhost, creatureSun,
|
||||
creatureSnake, creatureDrop);
|
||||
@ -14,9 +12,13 @@ type
|
||||
curX, curY, dX, dY, moveSpeed, animation: integer;
|
||||
alive: boolean;
|
||||
t: creatureType;
|
||||
sunf: sunStatePtr;
|
||||
snakef: snakeStatePtr;
|
||||
dropf: dropStatePtr;
|
||||
|
||||
rageMode: boolean; {for sun }
|
||||
bigStep: boolean; {for sun }
|
||||
beforeTransform: integer; {for sun and drop }
|
||||
diagonalMove: boolean; {for snake and drop}
|
||||
beforeReverse: integer; {for snake and drop}
|
||||
|
||||
end;
|
||||
|
||||
creatureItemPtr = ^creatureItem;
|
||||
@ -72,15 +74,6 @@ begin
|
||||
lst.first := lst.first^.next;
|
||||
if lst.first = nil then
|
||||
lst.last := nil;
|
||||
|
||||
if tmp^.cr^.t = creatureSun then
|
||||
dispose(tmp^.cr^.sunf)
|
||||
else
|
||||
if tmp^.cr^.t = creatureSnake then
|
||||
dispose(tmp^.cr^.snakef)
|
||||
else
|
||||
if tmp^.cr^.t = creatureDrop then
|
||||
dispose(tmp^.cr^.dropF);
|
||||
dispose(tmp^.cr);
|
||||
dispose(tmp);
|
||||
lst.len := lst.len - 1
|
||||
|
||||
@ -4,12 +4,49 @@ interface
|
||||
|
||||
uses creature_m;
|
||||
|
||||
procedure UpdateDropState(var cr: creature);
|
||||
procedure UpdateDropState(var d: creature);
|
||||
procedure InitRandomDrop(var s: creature);
|
||||
|
||||
const
|
||||
DropMovespeed = 2;
|
||||
|
||||
implementation
|
||||
|
||||
procedure UpdateDropState(var cr: creature);
|
||||
uses arena_m, Math, math_m;
|
||||
|
||||
const
|
||||
MinToTp = 10;
|
||||
MaxToTp = 75;
|
||||
|
||||
procedure InitDrop(var s: creature; x, y, sigdx, sigdy: integer);
|
||||
begin
|
||||
s.t := creatureDrop;
|
||||
s.curX := x;
|
||||
s.curY := y;
|
||||
s.dX := DropMovespeed * sigdx;
|
||||
s.dY := DropMovespeed * sigdy;
|
||||
s.alive := true;
|
||||
s.moveSpeed := DropMovespeed;
|
||||
s.beforeTransform := RandomLR(MinToTp, MaxToTp);
|
||||
s.diagonalMove := false
|
||||
end;
|
||||
|
||||
procedure InitRandomDrop(var s: creature);
|
||||
var
|
||||
x, y, sigdx, sigdy: integer;
|
||||
begin
|
||||
sigdx := IfThen(RandomBool, 1, -1);
|
||||
sigdy := IfThen(RandomBool, 1, -1);
|
||||
x := RandomLR(2, ArenaW - 1);
|
||||
y := RandomLR(2, ArenaH - 1);
|
||||
InitDrop(s, x, y, sigdx, sigdy)
|
||||
end;
|
||||
|
||||
procedure UpdateDropState(var d: creature);
|
||||
begin
|
||||
if d.beforeTransform = 0 then
|
||||
d.beforeTransform := RandomLR(MinToTp, MaxToTp);
|
||||
d.beforeTransform := d.beforeTransform - 1
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -13,31 +13,21 @@ procedure AppendEnemies(var lst: creatureList; t: enemyPackType);
|
||||
|
||||
implementation
|
||||
|
||||
uses ghost_m, sun_m;
|
||||
uses ghost_m, sun_m, snake_m, drop_m;
|
||||
|
||||
const
|
||||
{
|
||||
LevelGhostN: array[enemyPackType] of integer = (
|
||||
4, 4, 2, 4, 4, 2, 4, 2, 4, 4
|
||||
);
|
||||
}
|
||||
|
||||
LevelGhostN: array[enemyPackType] of integer = (
|
||||
4, 4, 2, 4, 4, 2, 4, 2, 4, 4
|
||||
);
|
||||
LevelSunN: array[enemyPackType] of integer = (
|
||||
0, 1, 4, 2, 0, 2, 2, 2, 2, 0
|
||||
);
|
||||
|
||||
|
||||
{
|
||||
LevelSnakeN: array[enemyPackType] of integer = (
|
||||
0, 0, 0, 1, 2, 2, 2, 4, 2, 2
|
||||
);
|
||||
LevelDropN: array[enemyPackType] of integer = (
|
||||
0, 0, 0, 0, 2, 2, 1, 1, 2, 4
|
||||
);
|
||||
}
|
||||
LevelSnakeN: array[enemyPackType] of integer = (
|
||||
0, 0, 0, 1, 2, 2, 2, 4, 2, 2
|
||||
);
|
||||
LevelDropN: array[enemyPackType] of integer = (
|
||||
0, 0, 0, 0, 2, 2, 1, 1, 2, 4
|
||||
);
|
||||
|
||||
procedure AppendRandomGhosts(var lst: creatureList; t: enemyPackType);
|
||||
var
|
||||
@ -66,11 +56,29 @@ begin
|
||||
end;
|
||||
|
||||
procedure AppendRandomSnakes(var lst: creatureList; t: enemyPackType);
|
||||
var
|
||||
i: integer;
|
||||
c: creaturePtr;
|
||||
begin
|
||||
for i := 1 to LevelSnakeN[t] do
|
||||
begin
|
||||
new(c);
|
||||
InitRandomSnake(c^);
|
||||
AppendCreature(lst, c)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure AppendRandomDrops(var lst: creatureList; t: enemyPackType);
|
||||
var
|
||||
i: integer;
|
||||
c: creaturePtr;
|
||||
begin
|
||||
for i := 1 to LevelDropN[t] do
|
||||
begin
|
||||
new(c);
|
||||
InitRandomDrop(c^);
|
||||
AppendCreature(lst, c)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure AppendEnemies(var lst: creatureList; t: enemyPackType);
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
ExitHeight 8
|
||||
|
||||
== BANNER START ==
|
||||
' ______ _ _ _ _ ___',
|
||||
'| ____| (_) | | | | | |__ \',
|
||||
'| |__ __ ___| |_ | |_| |__ ___ __ _ __ _ _ __ ___ ___ ) |',
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
{ MainLoop -- main loop }
|
||||
unit game_m;
|
||||
|
||||
interface
|
||||
@ -23,8 +22,7 @@ type
|
||||
|
||||
procedure InitGame(var g: gameState);
|
||||
procedure MainLoop(var g: gameState);
|
||||
procedure NextExitState(var g: gameState);
|
||||
procedure PreviousExitState(var g: gameState);
|
||||
procedure ChangeOtherExitState(var g: gameState);
|
||||
|
||||
implementation
|
||||
|
||||
@ -33,11 +31,11 @@ uses arena_m, arena_graphics_m, crt, creature_m, graphics_m, hamster_m,
|
||||
|
||||
const
|
||||
KeyDelayMs = 25;
|
||||
MoveDelayMs = 120;
|
||||
MoveDelayMs = 125;
|
||||
EraseLifeThreshold = 10;
|
||||
AnnounceDelayMs = 1500;
|
||||
LevelCompleteDelayMs = 1500;
|
||||
LevelCount = 2;
|
||||
LevelCount = 20;
|
||||
StartLifeN = 3;
|
||||
|
||||
procedure DecreaseLife(var life: integer);
|
||||
@ -117,7 +115,7 @@ begin
|
||||
EraseGameOver;
|
||||
if g.curState = gameLevelAnnounce then
|
||||
begin
|
||||
InitLevel(level, enemyPack1)
|
||||
InitLevel(level, g.enemyPack)
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -140,17 +138,17 @@ end;
|
||||
|
||||
procedure GameNextLevel(var g: gameState; var level: levelState);
|
||||
begin
|
||||
g.level := g.level + 1;
|
||||
DisposeCreatureList(level.enemyList);
|
||||
if g.level > LevelCount then
|
||||
if g.level = LevelCount then
|
||||
begin
|
||||
g.levelInited := false;
|
||||
g.curState := gameComplete
|
||||
end
|
||||
else
|
||||
begin
|
||||
g.curState := gameLevelComplete
|
||||
end
|
||||
g.curState := gameComplete;
|
||||
exit
|
||||
end;
|
||||
g.level := g.level + 1;
|
||||
g.curState := gameLevelComplete;
|
||||
if g.level mod 2 = 1 then
|
||||
g.enemyPack := succ(g.enemyPack)
|
||||
end;
|
||||
|
||||
procedure GameKillHamster(var g: gameState; var level: levelState);
|
||||
@ -186,9 +184,7 @@ begin
|
||||
TurnStubbornEnemies(level.a, level.enemyList);
|
||||
EraseEnemies(level.a, level.enemyList);
|
||||
MakeEnemySteps(level.a, level.h, level.t, level.enemyList);
|
||||
|
||||
UpdateEnemyStates(level.enemyList);
|
||||
|
||||
DrawAliveEnemies(level.enemyList)
|
||||
end;
|
||||
|
||||
@ -242,7 +238,7 @@ begin
|
||||
g.score := 0
|
||||
end;
|
||||
g.curState := gameLevelLoop;
|
||||
InitLevel(level, enemyPack1);
|
||||
InitLevel(level, g.enemyPack);
|
||||
DrawLevel(level, g.life, g.score);
|
||||
LevelLoop(g, level)
|
||||
end;
|
||||
@ -273,6 +269,7 @@ begin
|
||||
if (g.curState = gameMenu) and not prevMenu then
|
||||
begin
|
||||
DrawMenu(g);
|
||||
GotoXY(1, 1);
|
||||
prevMenu := true
|
||||
end;
|
||||
delay(KeyDelayMs);
|
||||
@ -294,6 +291,7 @@ var
|
||||
i: integer;
|
||||
begin
|
||||
DrawAnnounce(g.level);
|
||||
GotoXY(1, 1);
|
||||
for i := 1 to AnnounceDelayMs div KeyDelayMs do
|
||||
begin
|
||||
delay(KeyDelayMs);
|
||||
@ -371,23 +369,12 @@ begin
|
||||
gameComplete:
|
||||
RunGameCompleteState(g, level)
|
||||
end;
|
||||
EraseAll
|
||||
clrscr
|
||||
end;
|
||||
|
||||
procedure NextExitState(var g: gameState);
|
||||
procedure ChangeOtherExitState(var g: gameState);
|
||||
begin
|
||||
if not g.curExit then
|
||||
g.curExit := true
|
||||
else
|
||||
g.curExit := false
|
||||
end;
|
||||
|
||||
procedure PreviousExitState(var g: gameState);
|
||||
begin
|
||||
if g.curExit then
|
||||
g.curExit := false
|
||||
else
|
||||
g.curExit := true
|
||||
g.curExit := not g.curExit
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
== BANNER START ==
|
||||
' _____ __ __ ______ ',
|
||||
' / ____| /\ | \/ | ____|',
|
||||
' | | __ / \ | \ / | |__ ',
|
||||
|
||||
@ -24,8 +24,7 @@ begin
|
||||
g.dX := GhostStartDX * sigdx;
|
||||
g.dY := GhostStartDY * sigdy;
|
||||
g.moveSpeed := GhostMovespeed;
|
||||
g.alive := true;
|
||||
g.animation := 1;
|
||||
g.alive := true
|
||||
end;
|
||||
|
||||
procedure InitRandomGhost(var g: creature);
|
||||
|
||||
@ -33,9 +33,8 @@ begin
|
||||
PrintTerminalHelp;
|
||||
exit
|
||||
end;
|
||||
clrscr;
|
||||
InitGame(g);
|
||||
EraseAll;
|
||||
clrscr;
|
||||
MainLoop(g)
|
||||
end.
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ unit graphics_m;
|
||||
|
||||
interface
|
||||
|
||||
uses arena_m, creature_m, trace_m, game_m, level_m, _banners_m, ascii_arts_m;
|
||||
uses arena_m, creature_m, trace_m, game_m, level_m, _autobanners_m, ascii_arts_m;
|
||||
|
||||
const
|
||||
BorderSize = 1;
|
||||
@ -28,7 +28,6 @@ procedure DrawNumber(x, y: integer; n: longint);
|
||||
procedure DrawRectangle(x0, y0, h, w: integer; ch: char);
|
||||
procedure DrawMenuState(s: menuState);
|
||||
procedure DrawMenu(var g: gameState);
|
||||
procedure EraseAll;
|
||||
procedure EraseAnnounce(lvl: integer);
|
||||
procedure EraseExit;
|
||||
procedure EraseExitState(b: boolean);
|
||||
@ -45,7 +44,7 @@ implementation
|
||||
uses crt, math_m;
|
||||
|
||||
const
|
||||
AnnounceY = (ScreenH - LevelAnnounceHeight) div 2;
|
||||
AnnounceY = (ScreenH - LevelAnnounceBannerH) div 2;
|
||||
BigLetterWidth = 8;
|
||||
BorderN = 2;
|
||||
DecimalDelimiter = 10;
|
||||
@ -55,34 +54,47 @@ const
|
||||
MenuHeightPadding = 2;
|
||||
MenuInfoY = NewGameY + NewGameHeight + MenuHeightPadding;
|
||||
ContinueY = MenuInfoY + MenuInfoHeight;
|
||||
ExitGameY = (ScreenH - ExitScreenHeight) div 2 - MenuHeightPadding;
|
||||
ExitGameY = (ScreenH - ExitBannerH) div 2 - MenuHeightPadding;
|
||||
ExitYesY = ExitGameY + ExitHeight - 1 + MenuHeightPadding;
|
||||
ExitHamsterY = ExitYesY;
|
||||
GameNameX = ScreenW * WidthCoefficient div 3 + 4;
|
||||
MenuWidthPadding = 4;
|
||||
MenuHamsterX = GameNameX - HamsterWidth - MenuWidthPadding;
|
||||
MenuPaddingX = 4;
|
||||
MenuHamsterX = GameNameX - HamsterWidth - MenuPaddingX;
|
||||
ExitYesX = MenuHamsterX;
|
||||
ExitNoX = ScreenW * WidthCoefficient - ExitYesX - NoWidth;
|
||||
GameOverX = (ScreenW * WidthCoefficient - GameNameWidth) div 2;
|
||||
GameOverY = (ScreenH - GameOverHeight) div 2;
|
||||
HamsterNoX = ExitNoX - HamsterWidth - MenuWidthPadding;
|
||||
HamsterYesX = ExitYesX - HamsterWidth - MenuWidthPadding;
|
||||
KeyInfoX = (ScreenW * WidthCoefficient - KeyInfoWidth) div 2;
|
||||
KeyInfoY = (ScreenH - KeyInfoHeight) div 2;
|
||||
GameOverX = (ScreenW * WidthCoefficient - GameOverBannerW) div 2;
|
||||
GameOverY = (ScreenH - GameOverBannerH) div 2;
|
||||
HamsterNoX = ExitNoX - HamsterWidth - MenuPaddingX;
|
||||
HamsterYesX = ExitYesX - HamsterWidth - MenuPaddingX;
|
||||
KeyInfoX = (ScreenW * WidthCoefficient - KeysInfoBannerW) div 2;
|
||||
KeyInfoY = (ScreenH - KeysInfoBannerH) div 2;
|
||||
LetterWidth = 5;
|
||||
LevelNumberMargin = 3;
|
||||
GameCompleteX = (ScreenW * WidthCoefficient - GameCompleteWidth) div 2;
|
||||
GameCompleteY = (ScreenH - GameCompleteHeight) div 2;
|
||||
GameCompleteX = (ScreenW * WidthCoefficient - GameCompleteBannerW) div 2;
|
||||
GameCompleteY = (ScreenH - GameCompleteBannerH) div 2;
|
||||
GameCompleteScoreX = GameCompleteX + GameCompleteScoreWidth + 3;
|
||||
GameCompleteScoreY = GameCompleteY + 9;
|
||||
EndOfLine = 256;
|
||||
MaxStringLen = 255;
|
||||
|
||||
var
|
||||
firstMenuDraw: boolean = true;
|
||||
|
||||
function CountLeadSpaces(var s: string): integer;
|
||||
var
|
||||
i, res: integer;
|
||||
begin
|
||||
res := 0;
|
||||
for i := 1 to Length(s) do
|
||||
if s[i] <> ' ' then
|
||||
break
|
||||
else
|
||||
res := res + 1;
|
||||
CountLeadSpaces := res
|
||||
end;
|
||||
|
||||
procedure PrintStringScreen(x, y, dy: integer; var s: string);
|
||||
var
|
||||
cutLen: integer;
|
||||
cutLen, leadSpaces: integer;
|
||||
sCopy: string;
|
||||
begin
|
||||
if y + dy - 1 > ScreenH then
|
||||
@ -91,15 +103,22 @@ begin
|
||||
begin
|
||||
cutLen := x * -1 + 1;
|
||||
GotoXY(1, y + dy - 1);
|
||||
sCopy := copy(s, cutLen, EndOfLine);
|
||||
sCopy := copy(s, cutLen, MaxStringLen);
|
||||
write(sCopy)
|
||||
end
|
||||
else
|
||||
begin
|
||||
GotoXY(x, y + dy - 1);
|
||||
write(s)
|
||||
end;
|
||||
GotoXY(1, 1)
|
||||
leadSpaces := CountLeadSpaces(s);
|
||||
GotoXY(x + leadSpaces, y + dy - 1);
|
||||
sCopy := copy(s, leadSpaces + 1, MaxStringLen);
|
||||
write(sCopy)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure PrintDigitS(x, y, dy: integer; var s: string);
|
||||
begin
|
||||
GotoXY(x, y + dy - 1);
|
||||
write(s)
|
||||
end;
|
||||
|
||||
procedure DrawCreatureImage(x, y, h: integer; var a: CreatureImage);
|
||||
@ -123,7 +142,7 @@ var
|
||||
i: integer;
|
||||
begin
|
||||
for i := 1 to h do
|
||||
PrintStringScreen(x, y, i, a[i])
|
||||
PrintDigitS(x, y, i, a[i])
|
||||
end;
|
||||
|
||||
procedure DrawDigit(x, y, digit: integer);
|
||||
@ -145,19 +164,22 @@ procedure DrawExit(var g: gameState);
|
||||
var
|
||||
realX: integer = ScreenW * WidthCoefficient;
|
||||
begin
|
||||
DrawBannerImage((realX - ExitWidth) div 2, ExitGameY,
|
||||
ExitScreenHeight, ExitScreen);
|
||||
DrawExitState(g.curExit)
|
||||
DrawBannerImage((realX - ExitBannerW) div 2, ExitGameY,
|
||||
ExitBannerH, ExitBanner);
|
||||
DrawExitState(g.curExit);
|
||||
GotoXY(1, 1)
|
||||
end;
|
||||
|
||||
procedure DrawGameOver;
|
||||
begin
|
||||
DrawBannerImage(GameOverX, GameOverY, GameOverHeight, GameOverScreen)
|
||||
DrawBannerImage(GameOverX, GameOverY, GameOverBannerH, GameOverBanner);
|
||||
GotoXY(1, 1)
|
||||
end;
|
||||
|
||||
procedure DrawKeyInfo;
|
||||
begin
|
||||
DrawBannerImage(KeyInfoX, KeyInfoY, KeyInfoHeight, KeyInfoScreen)
|
||||
DrawBannerImage(KeyInfoX, KeyInfoY, KeysInfoBannerH, KeysInfoBanner);
|
||||
GotoXY(1, 1)
|
||||
end;
|
||||
|
||||
procedure DrawLineX(x, y, len: integer; ch: char);
|
||||
@ -166,8 +188,7 @@ var
|
||||
begin
|
||||
GotoXY(x, y);
|
||||
for i := 1 to len do
|
||||
write(ch);
|
||||
GotoXY(1, 1)
|
||||
write(ch)
|
||||
end;
|
||||
|
||||
procedure DrawLineY(x, y, len: integer; ch: char);
|
||||
@ -178,8 +199,7 @@ begin
|
||||
begin
|
||||
GotoXY(x, y + i - 1);
|
||||
write(ch)
|
||||
end;
|
||||
GotoXY(1, 1)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure DrawMenuState(s: menuState);
|
||||
@ -209,8 +229,7 @@ begin
|
||||
GotoXY(x0 + w - 1, y0 + i);
|
||||
write(ch)
|
||||
end;
|
||||
DrawLineX(x0, y0 + h - 1, w, ch);
|
||||
GotoXY(1, 1)
|
||||
DrawLineX(x0, y0 + h - 1, w, ch)
|
||||
end;
|
||||
|
||||
procedure DrawMenu(var g: gameState);
|
||||
@ -222,7 +241,7 @@ begin
|
||||
DrawRectangle(1, 1, ScreenH, ScreenW * WidthCoefficient, BorderSymbol);
|
||||
firstMenuDraw := not firstMenuDraw
|
||||
end;
|
||||
DrawBannerImage(GameNameX, y, GameMenuHeight, GameMenuScreen);
|
||||
DrawBannerImage(GameNameX, y, MenuBannerH, MenuBanner);
|
||||
if not g.levelInited then
|
||||
DrawLineX(GameNameX, ContinueY + ContinueHeight div 2,
|
||||
ContinueWidth, '-');
|
||||
@ -231,15 +250,15 @@ end;
|
||||
|
||||
procedure FillRectangle(x, y, w, h: integer; ch: char);
|
||||
var
|
||||
i, j: integer;
|
||||
i: integer;
|
||||
s: string;
|
||||
begin
|
||||
s := StringOfChar(ch, w);
|
||||
for i := 0 to h - 1 do
|
||||
begin
|
||||
GotoXY(x, y + i);
|
||||
for j := 0 to w - 1 do
|
||||
write(ch)
|
||||
end;
|
||||
GotoXY(1, 1)
|
||||
write(s)
|
||||
end
|
||||
end;
|
||||
|
||||
procedure EraseRectangle(x, y, w, h: integer);
|
||||
@ -247,36 +266,32 @@ begin
|
||||
FillRectangle(x, y, w, h, ' ')
|
||||
end;
|
||||
|
||||
procedure EraseAll;
|
||||
begin
|
||||
EraseRectangle(1, 1, ScreenW * WidthCoefficient, ScreenH)
|
||||
end;
|
||||
|
||||
procedure EraseExit;
|
||||
begin
|
||||
EraseRectangle(HamsterYesX, ExitGameY,
|
||||
ExitWidth + HamsterWidth + MenuWidthPadding,
|
||||
ExitScreenHeight + MenuHeightPadding + YesHeight)
|
||||
ExitBannerW + HamsterWidth + MenuPaddingX,
|
||||
ExitBannerH + MenuHeightPadding + YesHeight)
|
||||
end;
|
||||
|
||||
procedure EraseExitState(b: boolean);
|
||||
var
|
||||
x: integer;
|
||||
begin
|
||||
if b then
|
||||
EraseRectangle(HamsterYesX, ExitHamsterY,
|
||||
HamsterWidth, HamsterHeight)
|
||||
x := HamsterYesX
|
||||
else
|
||||
EraseRectangle(HamsterNoX, ExitHamsterY,
|
||||
HamsterWidth, HamsterHeight)
|
||||
x := HamsterNoX;
|
||||
EraseRectangle(x, ExitHamsterY, HamsterWidth, HamsterHeight)
|
||||
end;
|
||||
|
||||
procedure EraseGameOver;
|
||||
begin
|
||||
EraseRectangle(GameOverX, GameOverY, GameOverWidth, GameOverHeight)
|
||||
EraseRectangle(GameOverX, GameOverY, GameOverBannerW, GameOverBannerH)
|
||||
end;
|
||||
|
||||
procedure EraseKeyInfo;
|
||||
begin
|
||||
EraseRectangle(KeyInfoX, KeyInfoY, KeyInfoWidth, KeyInfoHeight)
|
||||
EraseRectangle(KeyInfoX, KeyInfoY, KeysInfoBannerW, KeysInfoBannerH)
|
||||
end;
|
||||
|
||||
procedure EraseLevel;
|
||||
@ -290,7 +305,7 @@ end;
|
||||
procedure EraseMenu;
|
||||
begin
|
||||
EraseRectangle(MenuHamsterX, GameNameY,
|
||||
GameNameWidth + HamsterWidth + MenuWidthPadding,
|
||||
MenuBannerW + HamsterWidth + MenuPaddingX,
|
||||
ScreenH - GameNameY * 2)
|
||||
end;
|
||||
|
||||
@ -306,7 +321,7 @@ begin
|
||||
menuContinue:
|
||||
EraseRectangle(MenuHamsterX, ContinueY + 1,
|
||||
HamsterWidth, HamsterHeight)
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
type
|
||||
@ -387,12 +402,12 @@ var
|
||||
digitCnt: integer = 0;
|
||||
begin
|
||||
digitCnt := CountDigits(lvl);
|
||||
w := LevelAnnounceWidth + LevelNumberMargin +
|
||||
w := LevelAnnounceBannerW + LevelNumberMargin +
|
||||
DigitWidth * digitCnt + DigitSpaceWidth * (digitCnt - 1);
|
||||
x := (ScreenW * WidthCoefficient - w) div 2;
|
||||
DrawBannerImage(x, AnnounceY, LevelAnnounceHeight, LevelAnnounce);
|
||||
DrawNumber(x + LevelAnnounceWidth + LevelNumberMargin, AnnounceY + 1, lvl)
|
||||
|
||||
DrawBannerImage(x, AnnounceY, LevelAnnounceBannerH, LevelAnnounceBanner);
|
||||
DrawNumber(x + LevelAnnounceBannerW + LevelNumberMargin,
|
||||
AnnounceY + 1, lvl)
|
||||
end;
|
||||
|
||||
procedure EraseAnnounce(lvl: integer);
|
||||
@ -400,16 +415,16 @@ var
|
||||
w, x, digitCnt: integer;
|
||||
begin
|
||||
digitCnt := CountDigits(lvl);
|
||||
w := LevelAnnounceWidth + LevelNumberMargin +
|
||||
w := LevelAnnounceBannerW + LevelNumberMargin +
|
||||
DigitWidth * digitCnt + DigitSpaceWidth * (digitCnt - 1);
|
||||
x := (ScreenW * WidthCoefficient - w) div 2;
|
||||
EraseRectangle(x, AnnounceY, w, LevelAnnounceHeight)
|
||||
EraseRectangle(x, AnnounceY, w, LevelAnnounceBannerH)
|
||||
end;
|
||||
|
||||
procedure DrawGameComplete(score: integer);
|
||||
begin
|
||||
DrawBannerImage(GameCompleteX, GameCompleteY,
|
||||
GameCompleteHeight, GameComplete);
|
||||
GameCompleteBannerH, GameCompleteBanner);
|
||||
DrawNumber(GameCompleteScoreX, GameCompleteScoreY, score)
|
||||
end;
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
== BANNER START ==
|
||||
' _',
|
||||
' | |',
|
||||
' _ __ ___ _____ _____ | | _____ _ _ ___ _',
|
||||
|
||||
@ -85,8 +85,7 @@ begin
|
||||
GotoXY(2, 60);
|
||||
write(' ');
|
||||
GotoXY(2, 60);
|
||||
writeln(GetLength(level.t));
|
||||
GotoXY(1, 1)
|
||||
writeln(GetLength(level.t))
|
||||
end;
|
||||
{DEBUG}
|
||||
if (k = ArrowLeftOrd) or (k = ArrowRightOrd) or (k = ArrowUpOrd) or
|
||||
@ -194,10 +193,8 @@ end;
|
||||
procedure ChangeExitState(k: integer; var g: gameState);
|
||||
begin
|
||||
case k of
|
||||
ArrowRightOrd:
|
||||
NextExitState(g);
|
||||
ArrowLeftOrd:
|
||||
PreviousExitState(g)
|
||||
ArrowRightOrd, ArrowLeftOrd:
|
||||
ChangeOtherExitState(g)
|
||||
end
|
||||
end;
|
||||
|
||||
@ -280,7 +277,8 @@ begin
|
||||
HandleGameOverKey(g, k);
|
||||
gameComplete:
|
||||
HandleGameCompleteKey(g, k)
|
||||
end
|
||||
end;
|
||||
GotoXY(1, 1)
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
== BANNER START ==
|
||||
' _ _ ',
|
||||
'| | | |',
|
||||
'| | _____ _____| |',
|
||||
|
||||
@ -1,3 +1,11 @@
|
||||
GameNameHeight 6
|
||||
NewGameHeight 6
|
||||
MenuInfoHeight 8
|
||||
HighScoreHeight 8
|
||||
ContinueHeight 6
|
||||
ContinueWidth 41
|
||||
|
||||
== BANNER START ==
|
||||
' _____ _ _ _ _',
|
||||
' / ____| | | | | | | | |',
|
||||
'| | __ ___ | | | |__| | __ _ _ __ ___ ___| |_ ___ _ __',
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
== BANNER START ==
|
||||
' _',
|
||||
' | |',
|
||||
' _ __ __ _ _ _ ___ ___ __| |',
|
||||
@ -17,7 +18,7 @@
|
||||
' __ _ __ _ _ _ _| |_ | |_ ___ _ __ ___ ___ _ __ _ _',
|
||||
' / _` | ______ / _` | | | | | __| | __/ _ \ | ''_ ` _ \ / _ \ ''_ \| | | |',
|
||||
'| (_| | |______| | (_| | |_| | | |_ | || (_) | | | | | | | __/ | | | |_| |',
|
||||
' \__, | \__, |\__,_|_|\__| \__\___/ |_| |_| |_|\___|_| '' |_|\__,_|',
|
||||
' \__, | \__, |\__,_|_|\__| \__\___/ |_| |_| |_|\___|_| |_|\__,_|',
|
||||
'====| |= | |',
|
||||
' |_| |_|',
|
||||
'',
|
||||
|
||||
@ -4,12 +4,53 @@ interface
|
||||
|
||||
uses creature_m;
|
||||
|
||||
procedure UpdateSnakeState(var cr: creature);
|
||||
procedure UpdateSnakeState(var s: creature);
|
||||
procedure InitRandomSnake(var s: creature);
|
||||
|
||||
const
|
||||
SnakeMovespeed = 2;
|
||||
|
||||
implementation
|
||||
|
||||
procedure UpdateSnakeState(var cr: creature);
|
||||
uses arena_m, Math, math_m;
|
||||
|
||||
const
|
||||
MinToReverse = 2;
|
||||
MaxToReverse = 75;
|
||||
|
||||
procedure InitSnake(var s: creature; x, y, sigdx, sigdy: integer);
|
||||
begin
|
||||
s.t := creatureSnake;
|
||||
s.curX := x;
|
||||
s.curY := y;
|
||||
s.dX := SnakeMovespeed * sigdx;
|
||||
s.dY := SnakeMovespeed * sigdy;
|
||||
s.alive := true;
|
||||
s.moveSpeed := SnakeMovespeed;
|
||||
s.beforeReverse := RandomLR(MinToReverse, MaxToReverse);
|
||||
s.diagonalMove := false
|
||||
end;
|
||||
|
||||
procedure InitRandomSnake(var s: creature);
|
||||
var
|
||||
x, y, sigdx, sigdy: integer;
|
||||
begin
|
||||
sigdx := IfThen(RandomBool, 1, -1);
|
||||
sigdy := IfThen(RandomBool, 1, -1);
|
||||
x := RandomLR(2, ArenaW - 1);
|
||||
y := RandomLR(2, ArenaH - 1);
|
||||
InitSnake(s, x, y, sigdx, sigdy)
|
||||
end;
|
||||
|
||||
procedure UpdateSnakeState(var s: creature);
|
||||
begin
|
||||
s.beforeReverse := s.beforeReverse - 1;
|
||||
if s.beforeReverse = 0 then
|
||||
begin
|
||||
s.beforeReverse := RandomLR(MinToReverse, MaxToReverse);
|
||||
s.dX := s.dX * -1;
|
||||
s.dY := s.dY * -1
|
||||
end
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@ -5,7 +5,7 @@ interface
|
||||
uses creature_m;
|
||||
|
||||
procedure InitRandomSun(var s: creature);
|
||||
procedure UpdateSunState(var cr: creature);
|
||||
procedure UpdateSunState(var s: creature);
|
||||
|
||||
implementation
|
||||
|
||||
@ -14,31 +14,27 @@ uses arena_m, Math, math_m;
|
||||
const
|
||||
SunSlowMovespeed = 1;
|
||||
SunFastMovespeed = 2;
|
||||
SunRageMovespeed = 4;
|
||||
|
||||
SunGoidaMovespeed = 3;
|
||||
SunStartDX = SunSlowMovespeed;
|
||||
SunStartDY = SunSlowMovespeed;
|
||||
SunSymbol = 's';
|
||||
MinToRageSwitch = 15;
|
||||
MaxToRageSwitch = 25;
|
||||
|
||||
MinToGoidaSwitch = 25;
|
||||
MaxToGoidaSwitch = 35;
|
||||
MinToNormSwitch = 5;
|
||||
MaxToNormSwitch = 15;
|
||||
MaxToNormSwitch = 30;
|
||||
|
||||
procedure InitSun(var g: creature; x, y, sigdx, sigdy: integer);
|
||||
procedure InitSun(var s: creature; x, y, sigdx, sigdy: integer);
|
||||
begin
|
||||
g.t := creatureSun;
|
||||
g.curX := x;
|
||||
g.curY := y;
|
||||
g.dX := SunStartDX * sigdx;
|
||||
g.dY := SunStartDY * sigdy;
|
||||
g.movespeed := SunSlowMovespeed;
|
||||
g.alive := true;
|
||||
g.animation := 1;
|
||||
new(g.sunf);
|
||||
g.sunf^.bigStep:= true;
|
||||
g.sunf^.rageMode := false;
|
||||
g.sunf^.beforeRageSwitch := RandomLR(MinToRageSwitch, MaxToRageSwitch);;
|
||||
s.t := creatureSun;
|
||||
s.curX := x;
|
||||
s.curY := y;
|
||||
s.dX := SunStartDX * sigdx;
|
||||
s.dY := SunStartDY * sigdy;
|
||||
s.alive := true;
|
||||
s.moveSpeed := SunFastMovespeed;
|
||||
s.bigStep:= true;
|
||||
s.rageMode := false;
|
||||
s.beforeTransform := RandomLR(MinToGoidaSwitch, MaxToGoidaSwitch)
|
||||
end;
|
||||
|
||||
procedure InitRandomSun(var s: creature);
|
||||
@ -52,46 +48,46 @@ begin
|
||||
InitSun(s, x, y, sigdx, sigdy)
|
||||
end;
|
||||
|
||||
procedure SwitchRageMode(var cr: creature);
|
||||
procedure SwitchGoidaMode(var cr: creature);
|
||||
begin
|
||||
cr.sunf^.rageMode := not cr.sunf^.rageMode;
|
||||
if cr.sunf^.rageMode then
|
||||
cr.sunf^.beforeRageSwitch := RandomLR(MinToNormSwitch, MaxToNormSwitch)
|
||||
cr.rageMode := not cr.rageMode;
|
||||
if cr.rageMode then
|
||||
cr.beforeTransform := RandomLR(MinToNormSwitch, MaxToNormSwitch)
|
||||
else
|
||||
cr.sunf^.beforeRageSwitch := RandomLR(MinToRageSwitch, MaxToRageSwitch);
|
||||
if cr.sunf^.rageMode then
|
||||
cr.beforeTransform := RandomLR(MinToGoidaSwitch, MaxToGoidaSwitch);
|
||||
if cr.rageMode then
|
||||
begin
|
||||
cr.dX := Signum(cr.dX, 0) * SunRageMovespeed;
|
||||
cr.dY := Signum(cr.dY, 0) * SunRageMovespeed
|
||||
cr.dX := Signum(cr.dX, 0) * SunGoidaMovespeed;
|
||||
cr.dY := Signum(cr.dY, 0) * SunGoidaMovespeed
|
||||
end
|
||||
else
|
||||
begin
|
||||
cr.dX := Signum(cr.dX, 0) * SunSlowMovespeed;
|
||||
cr.dY := Signum(cr.dY, 0) * SunSlowMovespeed;
|
||||
cr.sunf^.bigStep := false
|
||||
cr.bigStep := false
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure UpdateSunState(var cr: creature);
|
||||
procedure UpdateSunState(var s: creature);
|
||||
begin
|
||||
if cr.sunf^.beforeRageSwitch = 0 then
|
||||
if s.beforeTransform = 0 then
|
||||
begin
|
||||
SwitchRageMode(cr);
|
||||
SwitchGoidaMode(s);
|
||||
exit
|
||||
end;
|
||||
cr.sunf^.beforeRageSwitch := cr.sunf^.beforeRageSwitch - 1;
|
||||
if cr.sunf^.rageMode then
|
||||
s.beforeTransform := s.beforeTransform - 1;
|
||||
if s.rageMode then
|
||||
exit;
|
||||
cr.sunf^.bigStep := not cr.sunf^.bigStep;
|
||||
if cr.sunf^.bigStep then
|
||||
s.bigStep := not s.bigStep;
|
||||
if s.bigStep then
|
||||
begin
|
||||
cr.dX := Signum(cr.dX, 0) * SunFastMovespeed;
|
||||
cr.dY := Signum(cr.dY, 0) * SunFastMovespeed
|
||||
s.dX := Signum(s.dX, 0) * SunFastMovespeed;
|
||||
s.dY := Signum(s.dY, 0) * SunFastMovespeed
|
||||
end
|
||||
else
|
||||
begin
|
||||
cr.dX := Signum(cr.dX, 0) * SunSlowMovespeed;
|
||||
cr.dY := Signum(cr.dY, 0) * SunSlowMovespeed
|
||||
s.dX := Signum(s.dX, 0) * SunSlowMovespeed;
|
||||
s.dY := Signum(s.dY, 0) * SunSlowMovespeed
|
||||
end
|
||||
end;
|
||||
|
||||
|
||||
@ -18,8 +18,7 @@ type
|
||||
|
||||
function FindIndex(var t: tracePtr; x, y, curIdx: integer): integer;
|
||||
function GetLength(var t: tracePtr): integer;
|
||||
function
|
||||
TraceCrossed(pX, pY: integer; var cr: creature; t: tracePtr): boolean;
|
||||
function TraceCrossed(pX, pY: integer; var cr: creature; t: tracePtr): boolean;
|
||||
procedure ChangeHamsterTrace(var h: creature; var t: tracePtr);
|
||||
procedure DeleteTrace(var t: tracePtr);
|
||||
procedure GetStart(var traceStart: tracePtr; a: tracePtr);
|
||||
@ -165,8 +164,7 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
function
|
||||
TraceCrossed(pX, pY: integer; var cr: creature; t: tracePtr): boolean;
|
||||
function TraceCrossed(pX, pY: integer; var cr: creature; t: tracePtr): boolean;
|
||||
var
|
||||
dX, dY, prevX, prevY: integer;
|
||||
begin
|
||||
@ -184,10 +182,7 @@ begin
|
||||
prevX := prevX + dX;
|
||||
prevY := prevY + dY
|
||||
end;
|
||||
if IsOnTrace(prevX, prevY, t) then
|
||||
TraceCrossed := true
|
||||
else
|
||||
TraceCrossed := false
|
||||
TraceCrossed := IsOnTrace(prevX, prevY, t)
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user