unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TSnake = class(TObject)
private
// Private Deklarationen
rTeile : array [0..40*30-1] of TPoint;
rAnzahlTeile : Word;
rCanvas : TCanvas;
rRichtung : Byte;
rWurdeBewegt : Boolean;
function LiesTeil( Index : Word ) : TPoint;
function PruefeObTot() : Boolean;
procedure AendereRichtung( NeueRichtung : Byte );
public
// Öffentliche Deklarationen
property Teile[ Index : Word ] : TPoint read LiesTeil;
property AnzahlTeile : Word read rAnzahlTeile;
property Canvas : TCanvas read rCanvas write rCanvas;
property Richtung : Byte read rRichtung write AendereRichtung;
property IstTot : Boolean read PruefeObTot;
procedure Init();
procedure Render();
procedure Update();
procedure Wachse();
end;
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private-Deklarationen }
Schlange : TSnake;
Haeppchen : TPoint;
Pause : Boolean;
procedure SetzeHaeppchen();
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ --- Snake Bereich --- }
function TSnake.LiesTeil( Index : Word ) : TPoint;
begin
result := rTeile[ Index ];
end;
procedure TSnake.Init();
begin
rAnzahlTeile := 2;
rTeile[0] := Point( 2, 0 );
rTeile[1] := Point( 1, 0 );
rTeile[2] := Point( 0, 0 );
rRichtung := 3;
rWurdeBewegt := true;
end;
procedure TSnake.Render();
var
Index : Word;
StartX, StartY : Integer;
EndeX, EndeY : Integer;
begin
rCanvas.Pen.Color := clGreen;
rCanvas.Brush.Color := clGreen;
for Index := 0 to rAnzahlTeile do
begin
StartX := rTeile[Index].X * 16;
EndeX := rTeile[Index].X * 16 + 16;
StartY := rTeile[Index].Y * 16;
EndeY := rTeile[Index].Y * 16 + 16;
rCanvas.Ellipse( StartX, StartY, EndeX, EndeY );
end;
end;
procedure TSnake.Update();
var
Index : Word;
begin
for Index := rAnzahlTeile downto 1 do
begin
rTeile[Index] := rTeile[Index-1];
end;
case rRichtung of
0:
begin
// Hoch
rTeile[0].Y := rTeile[0].Y - 1;
if ( rTeile[0].Y < 0 ) then rTeile[0].Y := 29;
rWurdeBewegt := true;
end;
1:
begin
// Runter
rTeile[0].Y := rTeile[0].Y + 1;
if ( rTeile[0].Y > 29 ) then rTeile[0].Y := 0;
rWurdeBewegt := true;
end;
2:
begin
// Links
rTeile[0].X := rTeile[0].X - 1;
if ( rTeile[0].X < 0 ) then rTeile[0].X := 39;
rWurdeBewegt := true;
end;
3:
begin
// Rechts
rTeile[0].X := rTeile[0].X + 1;
if ( rTeile[0].X > 39 ) then rTeile[0].X := 0;
rWurdeBewegt := true;
end;
end;
end;
procedure TSnake.AendereRichtung( NeueRichtung : Byte );
begin
if not rWurdeBewegt then Exit;
case rRichtung of
0, 1:
begin
if NeueRichtung = 0 then Exit;
if NeueRichtung = 1 then Exit;
end;
2, 3:
begin
if NeueRichtung = 2 then Exit;
if NeueRichtung = 3 then Exit;
end;
end;
rRichtung := NeueRichtung;
rWurdeBewegt := false;
end;
procedure TSnake.Wachse();
begin
rAnzahlTeile := rAnzahlTeile + 1;
end;
function TSnake.PruefeObTot() : Boolean;
var
Index : Word;
begin
for Index := 1 to rAnzahlTeile do
begin
if ( rTeile[ 0 ].X = rTeile[ Index ].X ) and ( rTeile[ 0 ].Y = rTeile[ Index].Y ) then
begin
result := true;
Exit;
end;
end;
result := false;
end;
{ --- Fenster Bereich --- }
procedure TForm1.FormCreate(Sender: TObject);
begin
Schlange := TSnake.Create;
Schlange.Canvas := Self.Canvas;
Schlange.Init();
Self.DoubleBuffered := true;
Randomize();
SetzeHaeppchen();
Pause := true;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Schlange.Free;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if ( Pause ) then
begin
Caption := 'Snake - Pause';
end
else
begin
Caption := 'Snake';
end;
Self.Canvas.Pen.Color := clWhite;
Self.Canvas.Brush.Color := clWhite;
Self.Canvas.Rectangle( 0, 0, ClientWidth, ClientHeight );
Self.Canvas.Pen.Color := clRed;
Self.Canvas.Brush.Color := clRed;
Self.Canvas.Ellipse( Haeppchen.X * 16, Haeppchen.Y * 16, Haeppchen.X * 16 + 16, Haeppchen.Y * 16 + 16 );
if ( not Pause ) then Schlange.Update();
Schlange.Render();
if ( Schlange.IstTot ) then
begin
Timer1.Enabled := false;
ShowMessage( 'Du hast verloren!' );
Schlange.Init();
SetzeHaeppchen();
Timer1.Enabled := true;
end;
if ( Schlange.Teile[ 0 ].X = Haeppchen.X ) and ( Schlange.Teile[ 0 ].Y = Haeppchen.Y ) then
begin
Schlange.Wachse();
SetzeHaeppchen();
end;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if ( not Pause ) then
begin
if Key = VK_UP then Schlange.Richtung := 0;
if Key = VK_DOWN then Schlange.Richtung := 1;
if Key = VK_LEFT then Schlange.Richtung := 2;
if Key = VK_RIGHT then Schlange.Richtung := 3;
end;
if Key = VK_SPACE then Pause := not Pause;
end;
procedure TForm1.SetzeHaeppchen();
var
Spielfeld : array [0..39, 0..29] of Integer;
X, Y : Integer;
Index : Integer;
FreieFelder : array [0..40*30-1] of TPoint;
AnzahlFelder : Integer;
begin
for Y := 0 to 29 do
begin
for X := 0 to 39 do
begin
Spielfeld[ X, Y ] := 0;
end;
end;
for Index := 0 to Schlange.AnzahlTeile do
begin
Spielfeld[ Schlange.Teile[Index].X, Schlange.Teile[Index].Y ] := 1;
end;
AnzahlFelder := 0;
for Y := 0 to 29 do
begin
for X := 0 to 39 do
begin
if Spielfeld[X , Y] = 0 then
begin
FreieFelder[AnzahlFelder] := Point(X, Y);
AnzahlFelder := AnzahlFelder + 1;
end;
end;
end;
Index := Random(AnzahlFelder + 1);
Haeppchen.X := FreieFelder[Index].X;
Haeppchen.Y := FreieFelder[Index].Y;
end;
end.