minecrawler
Grünschnabel
Ich hab aus Langeweile nen Snake Klon gemacht. Ist natürlich noch nicht ganz fertig, aber die Basissteuerung und so sollte eigentlich schonmal funktionieren. Der Code lässt sich kompilieren, aber sobald ich das Programm starte kommen Fehlermeldungen: "Fehler bei Adresse xy lesen von yxz". Ich vermute, dass er Probleme mit meinen Variablen breite und hoehe hat. Vielleicht sieht jemand, wie man das in Ordnung bringt...
Anmerkung: tmr1 auf 500ms und tmr2 auf 10ms.
Code:
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cyPaintBox, cyAdvPaintBox, ExtCtrls;
type
TForm3 = class(TForm)
cyAdvPaintBox1: TcyAdvPaintBox;
tmr1: TTimer;
tmr2: TTimer;
procedure FormShow(Sender: TObject);
procedure tmr2Timer(Sender: TObject);
procedure cyAdvPaintBox1Paint(Sender: TObject);
procedure FormShortCut(var Msg: TWMKey; var Handled: Boolean);
procedure tmr1Timer(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
const farben : array[0..2] of TColor = (clBlack, clWhite,clRed);
raster : Integer = 8;
var breite : Integer;
hoehe : Integer;
map: Array of array of Integer;
kopf, dir, futter: TPoint;
_length, points: Integer;
game : Boolean;
procedure spiel_ende;
begin
game:=False;
end;
procedure feed;
begin
futter := Point(Random(breite), Random(hoehe));
while map[futter.X, futter.Y]<>0 do
futter := Point(Random(breite), Random(hoehe));
map[futter.X,futter.Y] := -1;
end;
procedure movesnake;
var
i, j: Integer;
begin
for i := 0 to breite do
for j := 0 to hoehe do
if map[i, j]>0 then
Dec(map[i, j]);
kopf.X:=kopf.X+dir.X;
kopf.Y:=kopf.Y+dir.Y;
if (kopf.X<0) or (kopf.X>breite) or (kopf.Y<0) or (kopf.Y>hoehe) then
begin
spiel_ende;
ShowMessage('Sie haben den Rand berührt! F2 für neues Spiel!');
end;
if (map[kopf.X, kopf.Y]>0) and (game) then
begin
spiel_ende;
ShowMessage('Sie haben sich selbst gebissen! F2 für neues Spiel!');
end;
if (kopf.X=futter.X) and (kopf.Y=futter.Y) then
begin
Inc(_length);
feed;
end;
map[kopf.X, kopf.Y] := _length;
end;
procedure TForm3.cyAdvPaintBox1Paint(Sender: TObject);
var i,j : Integer;
col: TColor;
begin
for i := 0 to breite do
for j := 0 to hoehe do
begin
case map[i, j] of
-1: col := farben[2];
0: col := farben[0];
else
col := farben[1];
end;
CyAdvPaintBox1.Canvas.Brush.Color:=col;
CyAdvPaintBox1.Canvas.FillRect(Rect(i*raster, j*raster, (i+1)*raster, (j+1)*raster));
end;
end;
procedure setstart;
var
J, I: Integer;
begin
points:=0;
_length:=5;
map[0,0]:=5;
kopf.X:=1;
kopf.Y:=1;
dir.X:=0;
dir.Y:=1;
feed;
Form3.tmr2.Enabled:=True;
end;
procedure TForm3.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
if Msg.CharCode=vk_F2 then setstart;
if Msg.CharCode=VK_ESCAPE then
begin
game:=False;
TerminateProcess(GetCurrentProcess,0);
end;
end;
procedure TForm3.FormShow(Sender: TObject);
begin
Randomize;
Left:=0;
Top:=0;
cyAdvPaintBox1.Left:=0;
cyAdvPaintBox1.Top:=0;
Width:=Screen.Width;
Height:=Screen.Height;
cyAdvPaintBox1.Width:=Width;
cyAdvPaintBox1.Height:=Height;
breite:=Round((Screen.Width / raster));
hoehe:=Round((Screen.Height / raster));
SetLength(map,breite,hoehe);
setstart;
end;
procedure gamecontrol;
begin
if GetAsyncKeyState(VK_UP)<>0 then
if dir.Y<1 then begin dir.Y:=-1; dir.X:=0; end;
if GetAsyncKeyState(VK_DOWN)<>0 then
if dir.Y>-1 then begin dir.Y:=1; dir.X:=0; end;
if GetAsyncKeyState(VK_LEFT)<>0 then
if dir.X<1 then begin dir.X:=-1; dir.Y:=0; end;
if GetAsyncKeyState(VK_RIGHT)<>0 then
if dir.X>-1 then begin dir.X:=1; dir.Y:=0; end;
end;
procedure Main;
begin
game:=true;
while game do
begin
gamecontrol;
Form3.cyAdvPaintBox1.Repaint;
if GetAsyncKeyState(VK_ESCAPE)<>0 then
begin
game:=False;
TerminateProcess(GetCurrentProcess,0);
end;
end;
end;
procedure TForm3.tmr1Timer(Sender: TObject);
begin
if game then
movesnake;
end;
procedure TForm3.tmr2Timer(Sender: TObject);
begin
Form3.tmr2.Enabled:=False;
ShowMessage('Bereit? Wenn du OK gedrückt hast kannst du das Spiel jederzeit mit ESC beenden!');
Main;
end;
end.
Anmerkung: tmr1 auf 500ms und tmr2 auf 10ms.