Compare commits

...

2 Commits

23 changed files with 745 additions and 444 deletions

View File

@ -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
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

View File

@ -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,7 +188,36 @@ begin
DrawFieldCell(x - 1, -1, ' ')
end;
procedure RedrawInterfaceArea(x: integer);
procedure EraseSunInterface(x: integer);
begin
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
@ -204,6 +237,16 @@ begin
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);
var
i, j: integer;
@ -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
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;

View File

@ -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;

View File

@ -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 = (
(
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.

View File

@ -1,3 +1,5 @@
GameCompleteScoreWidth 50
== BANNER START ==
' _____ _ _ _ ',
' / ____| | | | | | |',
'| | __ __ _ _ __ ___ ___ ___ ___ _ __ ___ _ __ | | ___| |_ ___| |',

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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
);
}
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);

View File

@ -1,3 +1,6 @@
ExitHeight 8
== BANNER START ==
' ______ _ _ _ _ ___',
'| ____| (_) | | | | | |__ \',
'| |__ __ ___| |_ | |_| |__ ___ __ _ __ _ _ __ ___ ___ ) |',

View File

@ -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.

View File

@ -1,3 +1,4 @@
== BANNER START ==
' _____ __ __ ______ ',
' / ____| /\ | \/ | ____|',
' | | __ / \ | \ / | |__ ',

View File

@ -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);

View File

@ -33,9 +33,8 @@ begin
PrintTerminalHelp;
exit
end;
clrscr;
InitGame(g);
EraseAll;
clrscr;
MainLoop(g)
end.

View File

@ -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
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;
GotoXY(1, 1)
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;
@ -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;

View File

@ -1,3 +1,4 @@
== BANNER START ==
' _',
' | |',
' _ __ ___ _____ _____ | | _____ _ _ ___ _',

View File

@ -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.

View File

@ -1,3 +1,4 @@
== BANNER START ==
' _ _ ',
'| | | |',
'| | _____ _____| |',

View File

@ -1,3 +1,11 @@
GameNameHeight 6
NewGameHeight 6
MenuInfoHeight 8
HighScoreHeight 8
ContinueHeight 6
ContinueWidth 41
== BANNER START ==
' _____ _ _ _ _',
' / ____| | | | | | | | |',
'| | __ ___ | | | |__| | __ _ _ __ ___ ___| |_ ___ _ __',

View File

@ -1,3 +1,4 @@
== BANNER START ==
' _',
' | |',
' _ __ __ _ _ _ ___ ___ __| |',
@ -17,7 +18,7 @@
' __ _ __ _ _ _ _| |_ | |_ ___ _ __ ___ ___ _ __ _ _',
' / _` | ______ / _` | | | | | __| | __/ _ \ | ''_ ` _ \ / _ \ ''_ \| | | |',
'| (_| | |______| | (_| | |_| | | |_ | || (_) | | | | | | | __/ | | | |_| |',
' \__, | \__, |\__,_|_|\__| \__\___/ |_| |_| |_|\___|_| '' |_|\__,_|',
' \__, | \__, |\__,_|_|\__| \__\___/ |_| |_| |_|\___|_| |_|\__,_|',
'====| |= | |',
' |_| |_|',
'',

View File

@ -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.

View File

@ -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;

View File

@ -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.