dos_compilers/Borland Turbo Pascal v55/WALLS.PAS
2024-07-02 06:49:04 -07:00

205 lines
4.7 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ Copyright (c) 1989 by Borland International, Inc. }
unit Walls;
{ Turbo Pascal 5.5 object-oriented example.
See BREAKOUT.PAS.
This unit defines the Wall object type.
It's a fairly complex object, because it plays such a
pivotal role in the game.
}
interface
uses Screen, Bricks, Bounds, Crt;
type
BrickPtr = ^Brick;
BW = array[1..1000] of Brick;
WallPtr = ^BW;
Wall = object(Obstacle)
BrickWall : WallPtr;
Height : Integer;
NumLeft : Integer;
Value : Integer;
NCells : Integer;
constructor Init(InitX, InitY, InitWidth, InitHeight : Integer);
destructor Done; virtual;
procedure Show; virtual;
procedure Hide; virtual;
function Collide(var B : Ball) : Boolean; virtual;
function GetValue : Integer; virtual;
procedure Reset;
end;
implementation
function RandomColor(MaxColors : Integer) : Integer;
var
C : Integer;
begin
C := Random(MaxColors);
while C = (TextAttr SHR 4) do
C := Random(MaxColors);
RandomColor := C;
end;
procedure Beep;
begin
Sound(100);
Delay(20);
NoSound;
end;
{ A wall is an array of bricks. Its constructor actually builds a
conformant array, so we don't have to hardcode the size of the
wall. }
constructor Wall.Init(InitX, InitY, InitWidth, InitHeight : Integer);
begin
Obstacle.Init(InitX, InitY, InitWidth, False);
Height := InitHeight;
NCells := Width*5;
GetMem(BrickWall, Width*Height*SizeOf(Brick));
Reset;
end;
destructor Wall.Done;
begin
FreeMem(BrickWall, Width*Height*SizeOf(Block));
end;
{ This procedure could be made simpler, but you wouldn't get the slick
effect you see when the wall is built. }
procedure Wall.Show;
var
CurCol : Integer;
Count : Integer;
CurBlock : Integer;
begin
Visible := True;
NumLeft := Width*Height;
for CurCol := 1 to Width + Height - 1 do
for Count := 0 to Height - 1 do
begin
CurBlock := CurCol + Count*(Width-1);
if (CurCol - Count >= 1) and (CurCol - Count <= Width) then
begin
BrickWall^[CurBlock].Show;
Delay(5);
end;
end;
GoToXY(X + (5*Width DIV 2) - 7, Y);
TextColor(WHITE);
Write('Turbo Breakout');
end;
procedure Wall.Hide;
var
CurCol : Integer;
Count : Integer;
CurBlock : Integer;
begin
Visible := False;
for CurCol := 1 to Width + Height - 1 do
for Count := 0 to Height - 1 do
begin
CurBlock := CurCol + Count*(Width-1);
if (CurCol - Count >= 1) and (CurCol - Count <= Width) then
begin
if BrickWall^[CurBlock].IsVisible then
begin
BrickWall^[CurBlock].Hide;
Delay(5);
end;
end;
end;
end;
function Wall.Collide(var B : Ball) : Boolean;
var
CollideV, CollideH : Boolean;
{ To check for a collision with a brick, first we check if the ball is in
the area where the wall is located, then we see if there's a brick that's
still visible at the ball's position. If so, we destroy the brick, grab
its value, and beep. }
function CheckCollide(XPos, YPos : Integer) : Boolean;
var
ThisBrick : BrickPtr;
begin
CheckCollide := False;
if (YPos < Y) or (YPos > Y + Height - 1) or
(XPos < X) or (XPos > X + NCells - 1) then
Exit;
ThisBrick := @BrickWall^[1 + ((XPos-1) DIV 5) + Width*(YPos - 1)];
if ThisBrick^.IsVisible then
begin
CheckCollide := True;
Inc(Value, ThisBrick^.GetValue);
ThisBrick^.Hide;
Dec(NumLeft);
Beep;
if NumLeft = 0 then
Show;
end
end;
{ When checking for a collision with the wall, we have to watch out
for special cases involving corners. }
begin
Collide := False;
Value := 0;
CollideV := CheckCollide(B.X, B.NextY);
CollideH := CheckCollide(B.NextX, B.Y);
if CollideV then
begin
Collide := True;
B.ReverseY;
end;
if CollideH then
begin
Collide := True;
B.ReverseX;
end;
if not CollideV and not CollideH then
if CheckCollide(B.NextX, B.NextY) then
begin
Collide := True;
B.ReverseX;
B.ReverseY;
end;
end;
function Wall.GetValue : Integer;
begin
GetValue := Value;
end;
procedure Wall.Reset;
var
CurRow : Integer;
CurCol : Integer;
MaxColors : Integer;
begin
if LastMode = Mono then
MaxColors := 4
else
MaxColors := 16;
NumLeft := Width*Height;
for CurRow := 0 to Height - 1 do
for CurCol := 0 to Width - 1 do
BrickWall^[CurRow*Width+CurCol+1].Init(X + CurCol*5,
Y + CurRow,
RandomColor(MaxColors),
Height - Y - CurRow + 1);
if Visible then
Show;
end;
end.