home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
tpwinst
/
owldemos.pak
/
BONK.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-05-21
|
14KB
|
519 lines
{************************************************}
{ }
{ Turbo Pascal for Windows }
{ Demo program }
{ Copyright (c) 1991 by Borland International }
{ }
{************************************************}
program Bonk;
{$R BONK}
uses
WinTypes, WinProcs, WObjects, Strings;
const
idm_Reset = 100;
idm_Option = 101;
idm_About = 102;
idm_Pause = 103;
idm_Stop = 104;
InputEditBox = 109;
LiveTimeSB = 101;
PopSB = 102;
MissedPoints = -2;
HitPoints = 5;
MissedCritter = -1;
CritterSize = 72;
MaxPop = 35;
MaxLiveTime = 30;
Holes: array[1..5] of TPoint = ((X: 10; Y: 10), (X: 200; Y: 10),
(X: 100; Y: 100), (X: 10; Y: 200), (X: 200; Y: 200));
type
TApp = object(TApplication)
procedure InitMainWindow; virtual;
end;
THole = record
Time: Word;
Dead: Boolean;
end;
PGameWindow = ^TGameWindow;
TGameWindow = object(TWindow)
Live, Dead, GameOver, ScoreBoard: HBitMap;
CursorDown, CursorUp: HCursor;
Counter, Score, LiveTime, Frequence, GameTime: Integer;
Hits, Miss, Escaped: Integer;
IsGameOver, IsPause: Boolean;
HoleInfo: array[1..5] of THole;
constructor Init(AParent: PWindowsObject; Title: PChar);
procedure About(var Message: TMessage); virtual cm_First + idm_About;
procedure DrawBMP(DC: HDC; X, Y, BitMap: HBitmap);
procedure DrawGameOver(DC: HDC);
procedure DrawCritter(DC: HDC; CritterNumber: Byte);
procedure DrawScoreBoard(DC: HDC);
procedure GetWindowClass(var WndClass: TWndClass); virtual;
procedure Options(var Message: TMessage); virtual cm_First + idm_Option;
procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
procedure Pause(var Message: TMessage); virtual cm_First + idm_Pause;
procedure ResetGame(var Message: TMessage); virtual cm_First + idm_Reset;
procedure SetUpWindow; virtual;
procedure Stop(var Message: TMessage); virtual cm_First + idm_Stop;
procedure StopGame;
procedure WMDestroy(var Message: TMessage); virtual wm_Destroy;
procedure WMLButtonDown(var Message: TMessage); virtual wm_LButtonDown;
procedure WMLButtonUp(var Message: TMessage); virtual wm_LButtonUp;
procedure WMTimer(var Message: TMessage); virtual wm_Timer + wm_First;
procedure WMSize(var Message: TMessage); virtual wm_Size;
procedure WriteScore(DC: HDC);
end;
TOptionDialog = object(TDialog)
procedure OK(var Message: TMessage); virtual id_First + id_Ok;
procedure SetUpWindow; virtual;
procedure WMHScroll(var Message: TMessage); virtual wm_HScroll;
end;
{--------------- TOptionDialog ---------------}
procedure TOptionDialog.SetUpWindow;
var
S: String;
CS: array[0..20] of Char;
begin
TDialog.SetUpWindow;
SetScrollRange(GetDlgItem(HWindow, LiveTimeSB), sb_Ctl, 1,
MaxLiveTime, False);
SetScrollRange(GetDlgItem(HWindow, PopSB), sb_Ctl, 1, MaxPop, False);
SetScrollPos(GetDlgItem(HWindow, LiveTimeSB), sb_Ctl,
MaxLiveTime + 1 - PGameWindow(Parent)^.LiveTime, True);
SetScrollPos(GetDlgItem(HWindow, PopSB), sb_Ctl,
MaxPop + 6 - PGameWindow(Parent)^.Frequence, True);
Str(PGameWindow(Parent)^.GameTime div 10, S);
StrPCopy(CS, S);
SetDlgItemText(HWindow, InputEditBox, CS);
end;
procedure TOptionDialog.WMHScroll(var Message: TMessage);
const
PageStep = 10;
var
Pos: Integer;
Scroll: HWnd;
begin
Scroll := HiWord(Message.lParam);
Pos := GetScrollPos(Scroll, SB_Ctl);
case Message.wParam of
sb_LineUp: Dec(Pos);
sb_LineDown: Inc(Pos);
sb_PageUp: Dec(Pos, PageStep);
sb_PageDown: Inc(Pos, PageStep);
sb_ThumbPosition: Pos := LoWord(Message.lParam);
sb_ThumbTrack: Pos := LoWord(Message.lParam);
end;
SetScrollPos(Scroll, sb_Ctl, Pos, True);
end;
procedure TOptionDialog.OK(var Message: TMessage);
var
NoError: Bool;
Time: Integer;
begin
PGameWindow(Parent)^.LiveTime := MaxLiveTime + 1 - GetScrollPos(
GetDlgItem(HWindow, LiveTimeSB), sb_Ctl);
PGameWindow(Parent)^.Frequence := MaxPop + 1 - GetScrollPos(
GetDlgItem(HWindow, PopSB), sb_Ctl) + 5;
Time := GetDlgItemInt(HWindow, InputEditBox, @NoError, False) * 10;
if (NoError) and (Time > 0) then
begin
PGameWindow(Parent)^.GameTime := Time;
EndDlg(id_Ok);
end
else
MessageBox(HWindow, 'Game Time must be a number greater than 0!',
'Error', mb_Ok)
end;
{--------------- TGameWindow -----------------}
constructor TGameWindow.Init(AParent: PWindowsObject; Title: PChar);
begin
TWindow.Init(AParent, Title);
Attr.W := 282;
Attr.H := 400;
Attr.Style := WS_Caption or WS_SysMenu or WS_MinimizeBox;
Randomize;
end;
procedure TGameWindow.About(var Message: TMessage);
var
Dialog: TDialog;
begin
Dialog.Init(@Self, 'About');
Dialog.Execute;
Dialog.Done;
end;
procedure TGameWindow.DrawBMP(DC: HDC; X, Y, BitMap: HBitMap);
var
MemDC: HDC;
bm: TBitMap;
MadeDC: Boolean;
begin
if DC = 0 then
begin
DC := GetDC(HWindow);
MadeDC := True;
end
else
MadeDC := False;
MemDC := CreateCompatibleDC(DC);
SelectObject(MemDC, BitMap);
GetObject(GameOver, SizeOf(bm), @bm);
BitBlt(DC, X, Y, bm.bmWidth, bm.bmHeight, MemDC, 0, 0, SRCCopy);
DeleteDC(MemDC);
if MadeDC then ReleaseDC(HWindow, DC);
end;
procedure TGameWindow.DrawGameOver(DC: HDC);
begin
DrawBMP(DC, 10, 70, GameOver);
end;
procedure TGameWindow.DrawCritter(DC: HDC; CritterNumber: Byte);
var
MadeDC: Boolean;
MemDC: HDC;
begin
if DC = 0 then
begin
DC := GetDC(HWindow);
MadeDC := True;
end
else MadeDC := False;
if HoleInfo[CritterNumber].Time <> 0 then
begin
MemDC := CreateCompatibleDC(DC);
if HoleInfo[CritterNumber].Dead then SelectObject(MemDC, Dead)
else SelectObject(MemDC, Live);
BitBlt(DC, Holes[CritterNumber].X, Holes[CritterNumber].Y,
CritterSize, CritterSize, MemDC, 0, 0, SRCCopy);
DeleteDC(MemDC);
end
else
begin
SelectObject(DC, GetStockObject(White_Brush));
SelectObject(DC, GetStockObject(Null_Pen));
Rectangle(DC, Holes[CritterNumber].X, Holes[CritterNumber].Y,
Holes[CritterNumber].X + CritterSize + 1,
Holes[CritterNumber].Y + CritterSize + 1);
end;
if MadeDC then ReleaseDC(HWindow, DC);
end;
procedure TGameWindow.DrawScoreBoard(DC: HDC);
begin
DrawBMP(DC, 11, 214, ScoreBoard);
end;
procedure TGameWindow.GetWindowClass(var WndClass: TWndClass);
begin
TWindow.GetWindowClass(WndClass);
CursorUp := LoadCursor(hInstance, 'Malet');
WndClass.Style := 0;
WndClass.hCursor := CursorUp;
WndClass.hbrBackGround := GetStockObject(White_Brush);
WndClass.lpszMenuName := 'Menu';
WndClass.hIcon := LoadIcon(hInstance, 'Critter');
end;
procedure TGameWindow.Options(var Message: TMessage);
var
D: TOptionDialog;
begin
D.Init(@Self, 'OptionDlg');
D.Execute;
D.Done;
end;
procedure TGameWindow.Paint(PaintDC: HDC;var PaintInfo: TPaintStruct);
var
I: integer;
begin
DrawScoreBoard(PaintDC);
WriteScore(PaintDC);
if IsGameOver then
DrawGameOver(PaintDC)
else
for I := 1 to 5 do
DrawCritter(PaintDC, I);
end;
procedure TGameWindow.Pause(var Message: TMessage);
begin
if IsGameOver then Exit;
if IsPause then
begin
IsPause := False;
ModifyMenu(GetMenu(HWindow), idm_Pause, mf_ByCommand,
idm_Pause, '&Pause');
DrawMenuBar(hWindow);
if SetTimer(HWindow, 1, 100, nil) = 0 then
begin
MessageBox(HWindow, 'No Timers Left', 'Error', mb_Ok);
Halt(1);
end;
end
else
begin
IsPause := True;
KillTimer(HWindow, 1);
ModifyMenu(GetMenu(HWindow), idm_Pause, mf_ByCommand,
idm_Pause, '&Continue');
DrawMenuBar(hWindow);
end;
end;
procedure TGameWindow.ResetGame(var Message: TMessage);
begin
ModifyMenu(GetMenu(HWindow), idm_Option, mf_ByCommand or mf_Grayed,
idm_Option, '&Options');
ModifyMenu(GetMenu(HWindow), idm_Pause, mf_ByCommand,
idm_Pause, '&Pause');
ModifyMenu(GetMenu(HWindow), idm_Stop, mf_ByCommand,
idm_Stop, '&Stop');
DrawMenuBar(HWindow);
InValidateRect(HWindow, nil, True);
if SetTimer(HWindow, 1, 100, nil) = 0 then
begin
MessageBox(HWindow, 'No Timers Left', 'Error', mb_Ok);
Halt(1);
end;
FillChar(HoleInfo, SizeOf(HoleInfo), 0);
Counter := 0;
Score := 0;
Hits := 0;
Miss := 0;
Escaped := 0;
IsGameOver := False;
if IsPause then
begin
IsPause := False;
ModifyMenu(GetMenu(HWindow), idm_Pause, mf_ByCommand,
idm_Pause, '&Pause');
DrawMenuBar(hWindow);
end;
end;
procedure TGameWindow.SetUpWindow;
begin
CursorDown := LoadCursor(hInstance, 'MaletDown');
Live := LoadBitMap(hInstance, 'Live');
Dead := LoadBitMap(hInstance, 'Dead');
GameOver := LoadBitMap(hInstance, 'GameOver');
ScoreBoard := LoadBitMap(hInstance, 'Board');
IsGameOver := True;
IsPause := False;
LiveTime := 10;
Frequence := 20;
Counter := 0;
Score := 0;
Hits := 0;
Miss := 0;
Escaped := 0;
GameTime := 150 {fifteen seconds}
end;
procedure TGameWindow.Stop(var Message: TMessage);
begin
StopGame;
end;
procedure TGameWindow.StopGame;
begin
KillTimer(HWindow, 1);
ModifyMenu(GetMenu(HWindow), idm_Option, mf_ByCommand,
idm_Option, '&Options');
ModifyMenu(GetMenu(HWindow), idm_Pause, mf_ByCommand or mf_Grayed,
idm_Pause, '&Pause');
ModifyMenu(GetMenu(HWindow), idm_Stop, mf_ByCommand or mf_Grayed,
idm_Stop, '&Stop');
IsPause := False;
DrawMenuBar(HWindow);
IsGameOver := True;
InValidateRect(HWindow, nil, True);
Counter := GameTime;
end;
procedure TGameWindow.WMDestroy(var Message: TMessage);
begin
DeleteObject(Live);
DeleteObject(Dead);
DeleteObject(GameOver);
DeleteObject(ScoreBoard);
KillTimer(HWindow, 1);
TWindow.WMDestroy(Message);
end;
procedure TGameWindow.WMLButtonDown(var Message: TMessage);
var
Point: TPoint;
R: TRect;
I: Integer;
Hit: Boolean;
begin
SetClassWord(HWindow, GCW_hCursor, CursorDown);
GetCursorPos(Point);
SetCursorPos(Point.X, Point.Y);
if IsGameOver or IsPause then Exit;
Hit := False;
for I := 1 to 5 do
if not ((HoleInfo[I].Dead) or (HoleInfo[I].Time = 0)) then
begin
R.Top := Holes[I].X;
R.Left := Holes[I].Y;
R.Bottom := R.Top + CritterSize;
R.Right := R.Left + CritterSize;
Point.X := HiWord(Message.lParam);
Point.Y := LoWord(Message.lParam);
if PtInRect(R, Point) then
begin
Inc(Score, HitPoints);
HoleInfo[I].Dead := True;
HoleInfo[I].Time := Counter + 2 * LiveTime;
Inc(Hits);
Hit := True;
DrawCritter(0, I);
end;
end;
if not Hit then
begin
Inc(Score, MissedPoints);
Inc(Miss);
end;
WriteScore(0);
end;
procedure TGameWindow.WMLButtonUp(var Message: TMessage);
var
Point: TPoint;
begin
SetClassWord(HWindow, gcw_hCursor, CursorUp);
GetCursorPos(Point);
SetCursorPos(Point.X, Point.Y);
end;
procedure TGameWindow.WMTimer(var Message: TMessage);
var
R: TRect;
I: Integer;
begin
Inc(Counter);
I := Random(Frequence) + 1;
if I < 6 then
if HoleInfo[I].Time = 0 then
begin
HoleInfo[I].Time := Counter + LiveTime;
HoleInfo[I].Dead := False;
DrawCritter(0, I);
end;
for I := 1 to 5 do
if (Counter > HoleInfo[I].Time) and (HoleInfo[I].Time <> 0) then
begin
HoleInfo[I].Time := 0;
if not HoleInfo[I].Dead then
begin
Inc(Score, MissedCritter);
Inc(Escaped);
end;
DrawCritter(0, I);
end;
WriteScore(0);
if Counter >= GameTime then StopGame;
end;
procedure TGameWindow.WMSize(var Message: TMessage);
begin
if IsGameOver then Exit;
if IsIconic(HWindow) then KillTimer(HWindow, 1)
else
if not IsPause then
if SetTimer(HWindow, 1, 100, nil) = 0 then
begin
MessageBox(HWindow, 'No Timers Left', 'Error', mb_Ok);
Halt(1);
end;
end;
procedure TGameWindow.WriteScore(DC: HDC);
var
S: array[0..20] of Char;
MadeDC: Boolean;
begin
if DC = 0 then
begin
MadeDC := True;
DC := GetDC(HWindow);
end
else MadeDC := False;
SelectObject(DC, CreateSolidBrush($8080));
SelectObject(DC, GetStockObject(Null_Pen));
SetBKMode(DC, TransParent);
{Timer}
Rectangle(DC, 130, 252, 163, 275);
Str((GameTime-Counter):3, S);
S[3] :=S[2];
S[2]:='.';
TextOut(DC, 130, 252, S, 4);
{Hits}
Rectangle(DC, 40, 310, 71, 329);
Str(Hits:3, S);
TextOut(DC, 40, 310, S, StrLen(S));
{Misses}
Rectangle(DC, 77, 310, 117, 329);
Str(Miss:3, S);
TextOut(DC, 77, 310, S, StrLen(S));
{Escaped}
Rectangle(DC, 133, 310, 174, 329);
Str(Escaped:3, S);
TextOut(DC, 133, 310, S, StrLen(S));
{Total}
Rectangle(DC, 203, 310, 239, 328);
Str(Score:3, S);
TextOut(DC, 203, 310, S, StrLen(S));
DeleteObject(SelectObject(DC, GetStockObject(White_Brush)));
SelectObject(DC, GetStockObject(Null_Pen));
if MadeDC then ReleaseDC(HWindow, DC);
end;
{--------------- TApp ------------------------}
procedure TApp.InitMainWindow;
begin
MainWindow := New(PGameWindow, Init(nil, 'Bonk!'));
end;
{-------------Main Program--------------------}
var
App: TApp;
begin
App.Init('BonkGame');
App.Run;
App.Done;
end.