197 lines
5.1 KiB
ObjectPascal
197 lines
5.1 KiB
ObjectPascal
|
|
uses WPFObjects, Timers, Controls;
|
|||
|
|
|
|||
|
|
type
|
|||
|
|
BulletWPF = class(CircleWPF) end;
|
|||
|
|
MonsterWPF = class(SquareWPF) end;
|
|||
|
|
PlayerWPF = class(EllipseWPF) end;
|
|||
|
|
TGameState = (Paused, Started, EndOfGame);
|
|||
|
|
|
|||
|
|
var
|
|||
|
|
// Состояние игры
|
|||
|
|
GameState: TGameState := Paused;
|
|||
|
|
// Глобальные интерфейсные объекты
|
|||
|
|
sb: StatusBarWPF;
|
|||
|
|
bstart, bstop, bnewgame: ButtonWPF;
|
|||
|
|
// Глобальные игровые объекты
|
|||
|
|
Player: PlayerWPF;
|
|||
|
|
// Клавиатура
|
|||
|
|
kl, kr, ku, kd: boolean;
|
|||
|
|
|
|||
|
|
|
|||
|
|
procedure InitGame;
|
|||
|
|
begin
|
|||
|
|
Player := new PlayerWPF(GraphWindow.Center, 30, 50, RandomColor);
|
|||
|
|
Player.Velocity := 100;
|
|||
|
|
Player.Number := 0;
|
|||
|
|
|
|||
|
|
loop 10 do
|
|||
|
|
begin
|
|||
|
|
var m := new MonsterWPF(750, Random(10, 550), 30, RandomColor);
|
|||
|
|
m.Velocity := 50;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure NewGame;
|
|||
|
|
begin
|
|||
|
|
sb.Text := '';
|
|||
|
|
Objects.Clear;
|
|||
|
|
InitGame;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
// Конец игры - игрок погиб
|
|||
|
|
procedure GameOver;
|
|||
|
|
begin
|
|||
|
|
sb.Text := 'Игрок погиб';
|
|||
|
|
GameState := EndOfGame;
|
|||
|
|
bstart.Enabled := False;
|
|||
|
|
bstop.Enabled := False;
|
|||
|
|
bnewgame.Enabled := True;
|
|||
|
|
Player.Color := Colors.Black;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
// Конец игры - победа!
|
|||
|
|
procedure GameOverWin;
|
|||
|
|
begin
|
|||
|
|
sb.Text := 'Победа!';
|
|||
|
|
GameState := EndOfGame;
|
|||
|
|
bstart.Enabled := False;
|
|||
|
|
bstop.Enabled := False;
|
|||
|
|
bnewgame.Enabled := True;
|
|||
|
|
Player.Color := Colors.Yellow;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
procedure InitInterface;
|
|||
|
|
begin
|
|||
|
|
Window.SetSize(1000, 600);
|
|||
|
|
LeftPanel(200, Colors.Orange);
|
|||
|
|
bstart := Button('Start');
|
|||
|
|
bstop := Button('Stop');
|
|||
|
|
bnewgame := Button('Новая игра');
|
|||
|
|
bstop.Enabled := False;
|
|||
|
|
bstart.Enabled := False;
|
|||
|
|
bstart.Click := procedure → begin
|
|||
|
|
GameState := Started;
|
|||
|
|
bstart.Enabled := False;
|
|||
|
|
bstop.Enabled := True;
|
|||
|
|
end;
|
|||
|
|
bstop.Click := procedure → begin
|
|||
|
|
GameState := Paused;
|
|||
|
|
bstart.Enabled := True;
|
|||
|
|
bstop.Enabled := False;
|
|||
|
|
end;
|
|||
|
|
bNewGame.Click := procedure → begin
|
|||
|
|
GameState := Started;
|
|||
|
|
bnewgame.Enabled := False;
|
|||
|
|
bstart.Enabled := False;
|
|||
|
|
bstop.Enabled := True;
|
|||
|
|
NewGame;
|
|||
|
|
end;
|
|||
|
|
sb := StatusBar;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
// Обработчик таймера убивания монстров и умирания объектов за пределами экрана
|
|||
|
|
procedure KillMonstersHandler;
|
|||
|
|
begin
|
|||
|
|
if GameState <> Started then
|
|||
|
|
exit;
|
|||
|
|
// Удалить пули, вылетевшие за экран
|
|||
|
|
Objects.DestroyAll(o → o.OutOfGraphWindow and not (o is PlayerWPF));
|
|||
|
|
// Удалить монстра, убитого пулей, вместе с пулей
|
|||
|
|
foreach var o in Objects do
|
|||
|
|
begin
|
|||
|
|
if o is BulletWPF then
|
|||
|
|
foreach var x in o.IntersectionList do
|
|||
|
|
if x is MonsterWPF then
|
|||
|
|
begin
|
|||
|
|
x.Destroy;
|
|||
|
|
o.Destroy;
|
|||
|
|
Player.Number += 1;
|
|||
|
|
break;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
// Обработчик перерисовки экрана
|
|||
|
|
procedure DrawFrame(dt: real);
|
|||
|
|
begin
|
|||
|
|
if GameState <> Started then exit;
|
|||
|
|
Window.Title := 'Количество объектов: ' + Objects.Count;
|
|||
|
|
|
|||
|
|
// Перемещение игрока
|
|||
|
|
if kr then
|
|||
|
|
Player.Dx := 1
|
|||
|
|
else if kl then
|
|||
|
|
Player.Dx := -1
|
|||
|
|
else Player.Dx := 0;
|
|||
|
|
if ku then
|
|||
|
|
Player.Dy := -1
|
|||
|
|
else if kd then
|
|||
|
|
Player.Dy := 1
|
|||
|
|
else Player.Dy := 0;
|
|||
|
|
|
|||
|
|
// Перемещение остальных объектов
|
|||
|
|
foreach var o in Objects do // все перемещаются в своём направлении со своей скоростью
|
|||
|
|
begin
|
|||
|
|
if o is MonsterWPF then
|
|||
|
|
o.Direction := (Player.Center.X - o.Center.X, Player.Center.Y - o.Center.Y);
|
|||
|
|
o.MoveTime(dt);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
// Проверка гибели игрока
|
|||
|
|
if Player.IntersectionList.Any(o → o is MonsterWPF) then
|
|||
|
|
GameOver;
|
|||
|
|
|
|||
|
|
// Проверка выигрыша игрока
|
|||
|
|
if Player.Number >= 10 then
|
|||
|
|
GameOverWin;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
/// Обработчик таймера рождения монстров
|
|||
|
|
procedure CreateMonstersHandler;
|
|||
|
|
begin
|
|||
|
|
if GameState <> Started then exit;
|
|||
|
|
var x := if Random(2) = 0 then 750 else 50;
|
|||
|
|
var m := new MonsterWPF(x, Random(10, 550), 30, RandomColor);
|
|||
|
|
m.Velocity := 50;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
begin
|
|||
|
|
InitInterface;
|
|||
|
|
|
|||
|
|
CreateTimerAndStart(100, KillMonstersHandler);
|
|||
|
|
CreateTimerAndStart(1000, CreateMonstersHandler);
|
|||
|
|
|
|||
|
|
// Обработчик перерисовки кадров
|
|||
|
|
OnDrawFrame := DrawFrame;
|
|||
|
|
|
|||
|
|
// Обработчики мыши и клавиатуры
|
|||
|
|
OnMouseMove := (x, y, mb) → begin
|
|||
|
|
if GameState <> Started then exit;
|
|||
|
|
Player.RotateToPoint(x, y);
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
OnMouseDown := (x, y, mb) → begin
|
|||
|
|
if GameState <> Started then exit;
|
|||
|
|
var cc := new BulletWPF(Player.CenterTop, 5, Colors.Red);
|
|||
|
|
cc.Direction := (x - Player.Center.X, y - Player.Center.Y);
|
|||
|
|
cc.Velocity := 300;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
OnKeyDown := k → begin
|
|||
|
|
case k of
|
|||
|
|
Key.w, Key.Up: begin ku := true; kd := false; end;
|
|||
|
|
Key.s, Key.Down: begin kd := true; ku := false; end;
|
|||
|
|
Key.a, Key.Left: begin kl := true; kr := false; end;
|
|||
|
|
Key.d, Key.Right: begin kr := true; kl := false end;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
|
|||
|
|
OnKeyUp := k → begin
|
|||
|
|
case k of
|
|||
|
|
Key.w, Key.Up: ku := false;
|
|||
|
|
Key.s, Key.Down: kd := false;
|
|||
|
|
Key.a, Key.Left: kl := false;
|
|||
|
|
Key.d, Key.Right: kr := false;
|
|||
|
|
end;
|
|||
|
|
end;
|
|||
|
|
end.
|