Tank battle game.
{$A+,B+,D+,E-,F-,G+,I+,L+,N+,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}
{$M 16384, 0, 65535}
unit BOshared;
interface
uses
crt, graph, dos, globals, general, mouse;
const
PATHTO_DATA = 'DATA\';
MAXTANKS = 100;
INACTIVECOLOR = 7;
NAMESELCOL2 = 8;
FIELDWIDTH = 484; { field length }
FIELDHEIGhT = 300;
DELTACENTER = 9;
type
switchstatus = ( first, second );
tankarray = array [ 0..23, 0..59 ] of shortint;
TPlayer1 = record
name : string;
tanks : integer;
score : longint;
tankbox : ^tankarray;
getcagex : shortint;
getcagey : shortint;
end;
TPlayer2 = record
name : string;
tanks : integer;
score : longint;
tankbox : ^tankarray;
getcagex : shortint;
getcagey : shortint;
end;
TMatchStat = record
hour1 : byte;
minute1 : byte;
second1 : byte;
second2 : byte;
sec100 : byte;
hour2 : byte;
minute2 : byte;
hour : byte;
end;
var
player1 : TPlayer1;
player2 : TPlayer2;
playerswitch : switchstatus;
gamestarted : boolean;
tanksizex : byte;
tanksizey : byte;
center : integer;
matchstat : TMatchStat;
procedure displayplayersinfo;
procedure drawcage( cagexpos, cageypos : byte; selectedplayer : switchstatus );
function mainmenu : byte;
procedure playgame;
procedure quit;
procedure rankingtable;
procedure visfield;
Implementation
{----------------------------------------------------------------------------}
procedure displayplayersinfo;
begin
bardeluxe( 510, 0, 200, 100, 1, 0 );
bardeluxe( 510, 305, 200, 100, 1, 0 );
case playerswitch of
first :
begin
{ 1 player info /active/ }
if player1.tanks > player2.tanks then setcolor( 14 ) else setcolor( 15 );
settextstyle( 3, 0, 1 );
outtextxy( 520, 0, player1.name );
outtextxy( 640, 10, inttostr( player1.score ));
if player1.tanks < 10 then setcolor( 12 ) else setcolor( 15 );
settextstyle( 2, 0, 0 );
outtextxy( 530, 40, 'Tanks -> ' + inttostr( player1.tanks ));
{ 2 player info /inactive/ }
setcolor( INACTIVECOLOR );
settextstyle( 3, 0, 1 );
outtextxy( 520, 310, player2.name );
outtextxy( 640, 320, inttostr( player2.score ));
settextstyle( 2, 0, 0 );
outtextxy( 530, 350, 'Tanks -> ' + inttostr( player2.tanks ));
setlinestyle( 3, 0, 0 );
setcolor( 10 );
rectangle( 0, 0, FIELDWIDTH, getmaxy div 2 - 6 );
setcolor( 7 );
rectangle( 0, getmaxy div 2 + 6, FIELDWIDTH, getmaxy );
end;
second :
begin
{ 1 player info /inactive/ }
setcolor( INACTIVECOLOR );
settextstyle( 3, 0, 1 );
outtextxy( 520, 0, player1.name );
outtextxy( 640, 10, inttostr( player1.score ));
settextstyle( 2, 0, 0 );
outtextxy( 530, 40, 'Tanks -> ' + inttostr( player1.tanks ));
{ 2 player info /active/ }
if player1.tanks < player2.tanks then setcolor( 14 ) else setcolor( 15 );
settextstyle( 3, 0, 1 );
outtextxy( 520, 310, player2.name );
outtextxy( 640, 320, inttostr( player2.score ));
settextstyle( 2, 0, 0 );
if player2.tanks < 10 then setcolor( 12 ) else setcolor( 15 );
outtextxy( 530, 350, 'Tanks -> ' + inttostr( player2.tanks ));
setlinestyle( 3, 0, 0 );
setcolor( 7 );
rectangle( 0, 0, FIELDWIDTH, getmaxy div 2 - 6 );
setcolor( 10 );
rectangle( 0, getmaxy div 2 + 6, FIELDWIDTH, getmaxy );
end;
end; { case }
end;
{----------------------------------------------------------------------------}
procedure drawcage;
begin
setlinestyle( 0, 0, 0 );
if selectedplayer = first then
rectangle( 2 + cagexpos * (tanksizex+1), center - DELTACENTER - cageypos * (tanksizey+1) - (tanksizey+1),
2 + cagexpos * (tanksizex+1) + (tanksizex+1), center - DELTACENTER - cageypos * (tanksizey+1) )
else
rectangle( 2 + cagexpos * (tanksizex+1), center + DELTACENTER + cageypos * (tanksizey+1) + (tanksizey+1),
2 + cagexpos * (tanksizex+1) + (tanksizex+1), center + DELTACENTER + cageypos * (tanksizey+1) );
end;
{----------------------------------------------------------------------------}
function mainmenu;
const
MENUITEMS : array [ 0..5 ] of string=( 'New game',
'Return',
'Options',
'High Scores',
'Credits',
'Quit' );
CONTEXTHELP : array [ 0..5 ] of string=( 'Start new game with players personalizing and match rules.',
'Return to current game.',
'Configure game global options, such as rules, etc.',
'View ranking table.',
'Information about game and me.',
'Quit the game.' );
MENUYPOS = 230;
MAXITEMS = 6;
var
menujumper : shortint;
procedure vismenu;
begin
for counter := 0 to MAXITEMS-1 do
begin
if counter = menujumper then setcolor( 12 ) else setcolor( 15 );
if not gamestarted and (counter = 1) then setcolor( 7 );
settextstyle( 1, 0, 0 );
outtextxy( ( getmaxx - textwidth( MENUITEMS[ counter ]) ) div 2,
MENUYPOS + counter * ( textheight( MENUITEMS[ counter ] ) + 5 ), MENUITEMS[ counter ]);
if counter = menujumper then { display context help }
begin
bardeluxe( 0, getmaxy - 25, getmaxx, 25, 10, 3 );
setcolor( 14 );
settextstyle( 0, 0, 0 );
outtextxy(( getmaxx - textwidth( CONTEXTHELP[ counter ]) ) div 2,
582, CONTEXTHELP[ counter ]);
end;
end;
end; { vismenu }
begin
menujumper := 0;
cleardevice;
bardeluxe( 0, 0, getmaxx, getmaxy, 11, 3 );
bardeluxe( 5, 6, 348, 31, 10, 3 );
setcolor( 1 );
settextstyle( 8, 0, 1 );
for counter := 0 to 2 do
outtextxy( 18 - counter, 6 - counter, '2001 Created by Sergei Drozdov' );
setcolor( 9 );
outtextxy( 17 - counter, 5 - counter, '2001 Created by Sergei Drozdov' );
setcolor( 3 );
settextstyle( 3, 0, 9 );
for counter := 0 to 8 do
outtextxy(( getmaxx - textwidth( 'Brains Out' )) div 2 - counter + 11, 70 - counter, 'Brains Out' );
setcolor( 4 );
for counter := 8 to 11 do
outtextxy(( getmaxx - textwidth( 'Brains Out' )) div 2 - counter + 11, 70 - counter, 'Brains Out' );
vismenu;
repeat
oldmousex := mousex;
oldmousey := mousey;
mouseread( mousex, mousey, mouseButton );
if mousemove then mousedraw;
{ mouse in menu area }
if (( mousex > 305 ) and ( mousex < 490 ))
and (( mousey > 230 ) and ( mousey < 445 )) then
begin
if mouseButton = 1 then { LMB }
if not gamestarted and (menujumper = 1) then
else
begin
mainmenu := menujumper;
exit;
end;
if mousemove then { jump to menu items }
begin
menujumper := (mousey - 230) div ( textheight( MENUITEMS[0] ) + 5 );
vismenu;
end;
end;
if keypressed then
begin
key := readkey;
case key of
ENTER : if not gamestarted and (menujumper = 1) then
else
begin
mainmenu := menujumper;
exit;
end;
ESC : quit;
#0 :
begin
key := readkey;
case key of
DOWNARROW_ext : begin
inc( menujumper );
if not gamestarted and (menujumper = 1) then inc( menujumper );
end;
UPARROW_ext : begin
dec( menujumper );
if not gamestarted and (menujumper = 1) then dec( menujumper );
end;
end; { case }
if menujumper < 0 then menujumper := (MAXITEMS-1);
if menujumper = MAXITEMS then menujumper := 0;
end;
end;
vismenu;
end;
until false;
end;
{----------------------------------------------------------------------------}
procedure playgame;
begin
repeat
oldmousex := mousex;
oldmousey := mousey;
mouseread( mousex, mousey, mouseButton );
if mousemove then
begin
if (( mousex > 3 ) and ( mousex < FIELDWIDTH ))
and (( mousey > 3 ) and ( mousey < center )) then
begin
mousehide; { hide mouse when in play area }
if playerswitch = first then
begin
setcolor( 8 );
drawcage( player1.getcagex, player1.getcagey, playerswitch );
player1.getcagex := mousex div 7;
player1.getcagey := 23 - mousey div 11 ;
if player1.getcagex > 59 then player1.getcagex := 59;
if player1.getcagey < 0 then player1.getcagey := 0;
setcolor( 7 );
drawcage( player1.getcagex, player1.getcagey, playerswitch );
bardeluxe( 0,0,30,30,1,0);
outtextxy( 5,5,inttostr(player2.tankbox^[player1.getcagex, player1.getcagey]));
end;
end else mousedraw;
setlinestyle( 0, 0, 0 );
if (( mousex > 510 ) and ( mousex < 638 ))
and (( mousey > 580 ) and ( mousey < 599 )) then
begin
setcolor( 9 );
settextstyle( 2, 0, 0 );
rectangle( 510, 580, 638, 599 );
bardeluxe( 511, 581, 126, 17, 1, 1 );
setcolor( 14 );
outtextxy( 530, 583, 'Match statistics ' );
end
else
begin
setcolor( 7 );
settextstyle( 2, 0, 0 );
rectangle( 510, 580, 638, 599 );
bardeluxe( 511, 581, 126, 17, 1, 8 );
outtextxy( 530, 583, 'Match statistics ' );
end;
if (( mousex > 662 ) and ( mousex < 790 ))
and (( mousey > 580 ) and ( mousey < 599 )) then
begin
setcolor( 9 );
settextstyle( 2, 0, 0 );
rectangle( 662, 580, 790, 599 );
bardeluxe( 663, 581, 126, 17, 1, 1 );
setcolor( 14 );
outtextxy( 700, 583, 'Main menu' );
end
else
begin
setcolor( 7 );
settextstyle( 2, 0, 0 );
rectangle( 662, 580, 790, 599 );
bardeluxe( 663, 581, 126, 17, 1, 8 );
outtextxy( 700, 583, 'Main menu' );
end;
end; { mouse move }
if mouseButton = 1 then { LMB }
if not disableLMB then
begin
disableLMB := true;
{ if pressed on 'main menu' then exit to main menu }
if (( mousex > 662 ) and ( mousex < 790 ))
and (( mousey > 580 ) and ( mousey < 599 )) then exit;
if playerswitch = first then { first player active }
if ( (mousex > 0) and (mousex < FIELDWIDTH) )
and ( (mousey > 0) and (mousey < center) ) then
begin
if player2.tankbox^[ player1.getcagex, player1.getcagey ] = 0 then
begin
player2.tankbox^[ player1.getcagex, player1.getcagey ] := 3;
visAGI( 3 + player1.getcagex * (tanksizex+1),
center + DELTACENTER + player1.getcagey * (tanksizey+1) + 1,
PATHTO_DATA + 'blast.agi' );
end;
if player2.tankbox^[ player1.getcagex, player1.getcagey ] = 1 then
begin { player 2 tank destroyed }
player2.tankbox^[ player1.getcagex, player1.getcagey ] := 2;
dec( player2.tanks );
inc( player1.score, 10 );
visAGI( 3 + player1.getcagex * (tanksizex+1),
center + DELTACENTER + player1.getcagey * (tanksizey+1) + 1,
PATHTO_DATA + 'tank2_w.agi' );
end;
if player2.tanks = 0 then
begin
displayplayersinfo;
setcolor(14);
settextstyle(1,0,0);
outtextxy(200,200, player1.name + ' winner!' );
readkey;
closegraph;
halt;
end;
setcolor( 4 );
drawcage( player1.getcagex, player1.getcagey, playerswitch );
playerswitch := second;
setcolor( 7 );
drawcage( player2.getcagex, player2.getcagey, playerswitch );
displayplayersinfo;
end;
end { LMB }
else disableLMB := false;
if KeyPressed then { keyboard control }
begin
key := readkey;
if key = #27 then exit; { exit to main menu }
if playerswitch = second then
case key of
ESC : exit;
#0 :
begin
key := readkey;
setcolor( 8 );
drawcage( player2.getcagex, player2.getcagey, playerswitch );
if playerswitch=second then
case key of
LEFTARROW_ext : dec( player2.getcagex );
RIGHTARROW_ext : inc( player2.getcagex );
UPARROW_ext : dec( player2.getcagey );
DOWNARROW_ext : inc( player2.getcagey );
end; { case }
if player2.getcagex < 0 then player2.getcagex := 59;
if player2.getcagex > 59 then player2.getcagex := 0;
if player2.getcagey < 0 then player2.getcagey := 23;
if player2.getcagey > 23 then player2.getcagey := 0;
setcolor( 7 );
drawcage( player2.getcagex, player2.getcagey, playerswitch );
end;
SPACE :
begin
if player1.tankbox^[ player2.getcagex, player2.getcagey ] = 0 then
begin
player1.tankbox^[ player2.getcagex, player2.getcagey ] := 3;
visAGI( 3 + player2.getcagex * (tanksizex+1),
center - DELTACENTER - player2.getcagey * (tanksizey+1) - (tanksizey+1) + 1,
PATHTO_DATA + 'blast.agi' );
end;
if player1.tankbox^[ player2.getcagex, player2.getcagey ] = 1 then
begin { player 1 tank destroyed }
player1.tankbox^[ player2.getcagex, player2.getcagey ] := 2;
dec( player1.tanks );
inc( player2.score, 10 );
visAGI( 3 + player2.getcagex * (tanksizex+1),
center - DELTACENTER - player2.getcagey * (tanksizey+1) - (tanksizey+1) + 1,
PATHTO_DATA + 'tank1_w.agi' );
end;
if player1.tanks = 0 then
begin
displayplayersinfo;
setcolor(14);
settextstyle(1,0,0);
outtextxy(200,200, player2.name + ' winner!' );
readkey;
closegraph;
halt;
end;
setcolor( 4 );
drawcage( player2.getcagex, player2.getcagey, playerswitch );
playerswitch := first;
setcolor( 7 );
drawcage( player1.getcagex, player1.getcagey, playerswitch );
displayplayersinfo;
end;
end; { case }
end;
until false;
end;
{----------------------------------------------------------------------------}
procedure quit;
begin
closegraph;
textbackground( 0 );
clrscr;
textcolor( 7 );
writeln( 'Brains Out' );
writeln( '(c) 2001 Created by Sergeant Skeleton' );
writeln;
textcolor( 2 );
writeln( '-=[ Sergei Drozdov ]=-' );
write( 'e-mail : ' );
textcolor( 7 );
write( 'punksalive@mail.lv' );
textcolor( 2 );
write( ' or ' );
textcolor( 7 );
writeln( 'punksalive@navigators.lv' );
textcolor( 2 );
write( 'phone : ' );
textcolor( 7 );
writeln( '(53) 42169' );
textcolor( 2 );
write( 'Address : ' );
textcolor( 7 );
writeln( 'Rigas iela 8a-48, Livani, LV-5316, Latvija' );
textcolor( 7 );
dispose( player1.tankbox );
dispose( player2.tankbox );
halt;
end;
{----------------------------------------------------------------------------}
procedure rankingtable;
type
TRankingTable = record
name : string;
score : longint;
end;
var
ranktable : array [ 0..39 ] of ^TRankingTable;
begin
{ assign( f, 'brains.his' );
reset( f, 1 );
settextstyle( 2, 0, 0 );
for counter := 0 to 39 do
begin
new( ranktable^[counter].name);
end;
for counter := 0 to 39 do
begin
blockread( f, ranktable[counter].name, 10 );
blockread( f, ranktable[counter].score, 10 );
outtextxy( 200, 20 + counter * 15,
ranktable[counter].name+ ' ..................................... ' + inttostr(ranktable[counter].score) );
end;
close( f );
dispose( ranktable );
repeat
until keypressed;
}
end;
{----------------------------------------------------------------------------}
procedure visfield;
begin
{ draw fields separator }
bardeluxe( 0, center - 2, getmaxx, 4, 5, 6 );
setcolor( 8 );
rectangle( 500, 572, 799, 573 );
{ two inactive buttons }
setcolor( 7 );
settextstyle( 2, 0, 0 );
rectangle( 510, 580, 638, 599 );
bardeluxe( 511, 581, 126, 17, 1, 8 );
outtextxy( 530, 583, 'Match statistics ' );
rectangle( 662, 580, 790, 599 );
bardeluxe( 663, 581, 126, 17, 1, 8 );
outtextxy( 700, 583, 'Main menu' );
{ draw grid }
setlinestyle( 0, 0, 0 );
setcolor( 8 );
for tmpy := 0 to 23 do
for tmpx := 0 to 59 do
begin
drawcage( tmpx, tmpy, first );
drawcage( tmpx, tmpy, second );
end;
if gamestarted = false then { game not started }
begin
{ tanks initilization }
for tmpy := 0 to 23 do
for tmpx := 0 to 59 do
begin
if random( MAXTANKS ) = 1 then
begin
inc( player1.tanks );
player1.tankbox^[ tmpx, tmpy ] := 1;
end else player1.tankbox^[ tmpx, tmpy ] := 0;
if random( MAXTANKS ) = 1 then
begin
inc( player2.tanks );
player2.tankbox^[ tmpx, tmpy ] := 1;
end else player2.tankbox^[ tmpx, tmpy ] := 0;
end;
end;
{ for tmpy := 0 to 23 do
for tmpx := 0 to 59 do
begin
setcolor(10);
settextstyle(2,0,0);
outtextxy( 3+tmpx*7, tmpy*8, inttostr(player2.tankbox^[ tmpx, tmpy ]));
end;
}
{ terrain and tanks visualization }
for tmpy := 0 to 23 do
for tmpx := 0 to 59 do
begin
if player1.tankbox^[ tmpx, 23 - tmpy ] = 1 then { display tank }
visAGI( 3 + tmpx * (tanksizex+1), center - DELTACENTER - tmpy * (tanksizey+1) - (tanksizey+1) + 1,
PATHTO_DATA + 'tank1.agi' );
if player1.tankbox^[ tmpx, 23 - tmpy ] = 2 then { display wrecked tank }
visAGI( 3 + tmpx * (tanksizex+1), center - DELTACENTER - tmpy * (tanksizey+1) - (tanksizey+1) + 1,
PATHTO_DATA + 'tank1_w.agi' );
if player1.tankbox^[ tmpx, 23 - tmpy ] = 3 then { display wrecked terrain }
visAGI( 3 + tmpx * (tanksizex+1), center - DELTACENTER - tmpy * (tanksizey+1) - (tanksizey+1) + 1,
PATHTO_DATA + 'blast.agi' );
if player2.tankbox^[ tmpx, tmpy ] = 1 then { display tank }
visAGI( 3 + tmpx * (tanksizex+1), center + DELTACENTER + tmpy * (tanksizey+1) + 1,
PATHTO_DATA + 'tank2.agi' );
if player2.tankbox^[ tmpx, tmpy ] = 2 then { display wrecked tank }
visAGI( 3 + tmpx * (tanksizex+1), center + DELTACENTER + tmpy * (tanksizey+1) + (tanksizey+1) + 1,
PATHTO_DATA + 'tank2_w.agi' );
if player2.tankbox^[ tmpx, tmpy ] = 3 then { display wrecked terrain }
visAGI( 3 + tmpx * (tanksizex+1), center + DELTACENTER + tmpy * (tanksizey+1) + (tanksizey+1) + 1,
PATHTO_DATA + 'blast.agi' );
end;
{ players cursors visualization }
case playerswitch of
first : begin
setcolor( 7 );
drawcage( player1.getcagex, player1.getcagey, first );
setcolor( 4 );
drawcage( player2.getcagex, player2.getcagey, second );
end;
second : begin
setcolor( 4 );
drawcage( player1.getcagex, player1.getcagey, first );
setcolor( 7 );
drawcage( player2.getcagex, player2.getcagey, second );
end;
end; { case }
end;
{----------------------------------------------------------------------------}
end. { shared components for this game }