ArrayIndex eines anderen Objektes benutzen
ArrayIndex eines anderen Objektes benutzen
Hallo habe mir ein Snake-Spiel gebastelt und nun ja habe da dass Problem das dass Futter ab und zu auf der Schlange erstellt wird.
Um das Problem zu lösen habe ich bereits versucht auf den Index der Schlange zuzugreifen das gelingt mir aber nicht
Hier mal der Quelltext der Abfrage:
[code=laz] if (Happen.Haeppchen.x = Snake.FTeile[].x) and (Happen.Haeppchen.y = Snake.FTeile[].y) then
begin
//Abfrage für das Fressen des Futters und wachsen
if (Snake.FTeile[0].x = Happen.Haeppchen.x) and (Snake.FTeile[0].y = Happen.Haeppchen.y) then
begin
fressen;
end
else
begin
Umsetzen;
end;
end;[/code]
ich hoffe mir kann jemand helfen das Problem zu lösen ich hänge gerade ziemlich durch.
Habe bei Snake.FTeile[].x bewusst leer gelassen.
Danke schon mal im Voraus.
Um das Problem zu lösen habe ich bereits versucht auf den Index der Schlange zuzugreifen das gelingt mir aber nicht
Hier mal der Quelltext der Abfrage:
[code=laz] if (Happen.Haeppchen.x = Snake.FTeile[].x) and (Happen.Haeppchen.y = Snake.FTeile[].y) then
begin
//Abfrage für das Fressen des Futters und wachsen
if (Snake.FTeile[0].x = Happen.Haeppchen.x) and (Snake.FTeile[0].y = Happen.Haeppchen.y) then
begin
fressen;
end
else
begin
Umsetzen;
end;
end;[/code]
ich hoffe mir kann jemand helfen das Problem zu lösen ich hänge gerade ziemlich durch.
Habe bei Snake.FTeile[].x bewusst leer gelassen.
Danke schon mal im Voraus.
Re: ArrayIndex eines anderen Objektes benutzen
also der index meiner schlange erweitert sich ja pro futter was ich einsammel und ich möchte jetzt den gesamten index des arrays haben damit ich ihn in meiner abfrage benutzen kann.
Oder mal anders gefragt wie kann ich es verhindern, das sich das Futter auf der selben Koordinate wie ein Teil der Schlange befindet?
Oder mal anders gefragt wie kann ich es verhindern, das sich das Futter auf der selben Koordinate wie ein Teil der Schlange befindet?
Re: ArrayIndex eines anderen Objektes benutzen
Du müsstest etwas mehr zu deiner Datenstruktur preis geben, sonst kann dir nicht wirklich erfolgreich geantwortet werden.
Generell könnte man die Abfrage so gestalten (falls die Schlange "SnakeArray" aus einem Array of TPoint besteht):oder
Generell könnte man die Abfrage so gestalten (falls die Schlange "SnakeArray" aus einem Array of TPoint besteht):
Code: Alles auswählen
function IsSnakeOnPoint(p: TPoint): Boolean;
var
aPoint: TPoint;
begin
Result := false;
for aPoint in SnakeArray do
if (p.x = aPoint.x) and (p.y = aPoint.y) then
Result := true;
end;
Code: Alles auswählen
function IsSnakeOnPoint(p: TPoint): Boolean;
var
i: Integer;
begin
Result := false;
for i := 0 to High(SnakeArray) do
if (SnakeArray[i].x = p.x) and (SnakeArray[i].y = p.y) then
Result := true;
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: ArrayIndex eines anderen Objektes benutzen
Bei meiner schlange sind nur die FTeile vom array of TPoint.
Hier ist mal der ganze Code von der Schlange:
[code=laz]TSchlange = class(TObject)
FTeile: array[0..40*30-1] of TPoint;
FAnzahlTeile: Word;
FRichtung: Byte;
FWurdeBewegt: boolean;
FFarbe: TColor;
Richtung: Byte;
AnzahlTeile: Word;
FCanvas: TCanvas;
constructor Create;
function PruefeObTot: boolean;
function LiesTeil(index: Word): TPoint;
function Farbe: TColor;
property Teile[index: Word]: TPoint read LiesTeil;
property Canvas: TCanvas read FCanvas write FCanvas;
procedure Init;
procedure Render;
procedure Update;
procedure WachseUm1;
procedure AendereRichtung(NeueRichtung: integer);
end;
implementation
{ TSchlange }
constructor TSchlange.Create;
begin
FFarbe:= clWhite;
end;
function TSchlange.PruefeObTot: boolean;
var
i: integer;
index: word;
begin
for index:= 1 to FAnzahlTeile do
begin
if (FTeile[0].x = FTeile[index].x) and (FTeile[0].y = FTeile[index].y) then
begin
Result:= true;
Exit;
end;
end;
Result:= false;
end;
function TSchlange.LiesTeil(index: Word): TPoint;
begin
Result:= FTeile[index];
end;
function TSchlange.Farbe: TColor;
begin
Result:= FFarbe;
end;
procedure TSchlange.Init;
begin
FAnzahlTeile:= 2;
FTeile[0]:= Point(3, 3);
FTeile[1]:= Point(2, 3);
FTeile[2]:= Point(1, 3);
FRichtung:= 3;
FWurdeBewegt:= true;
end;
procedure TSchlange.Render;
var
index: word;
Startx, Starty: integer;
Endex, Endey: integer;
begin
FCanvas.Pen.Color:= Self.FFarbe;
FCanvas.Brush.Color:= Self.FFarbe;
for Index:= 0 to FAnzahlTeile do
begin
Startx:= FTeile[index].x * 16;
Starty:= FTeile[index].y * 16;
Endex:= FTeile[index].x * 16 + 16;
Endey:= FTeile[index].y * 16 + 16;
FCanvas.Rectangle(Startx, Starty, Endex, Endey);
end;
end;
procedure TSchlange.Update;
var
index: Word;
begin
//Teile hinterher ziehen
for index:= FAnzahlTeile downto 1 do
begin
FTeile[index]:= FTeile[index - 1];
end;
//Ablauf für das Verlassen des Spielfeldes und Wiedererscheinen auf der gegenüberliegenden Seite
case FRichtung of
0: //Bewegung nach oben
begin
FTeile[0].y:= FTeile[0].y - 1;
if FTeile[0].y < 0 then
begin
FTeile[0].y:= 29;
FWurdeBewegt:= true;
end;
end;
1: //Bewegung nach unten
begin
FTeile[0].y:= FTeile[0].y + 1;
if FTeile[0].y > 29 then
begin
FTeile[0].y:= 0;
FWurdeBewegt:= true;
end;
end;
2: //Bewegung nach links
begin
FTeile[0].x:= FTeile[0].x - 1;
if FTeile[0].x < 0 then
begin
FTeile[0].x:= 39;
FWurdeBewegt:= true;
end;
end;
3: //Bewegung nach rechts
begin
FTeile[0].x:= FTeile[0].x + 1;
if FTeile[0].x > 39 then
begin
FTeile[0].x:= 0;
FWurdeBewegt:= true;
end;
end;
end;
end;
procedure TSchlange.WachseUm1;
begin
FAnzahlTeile:= FAnzahlTeile + 1;
end;
procedure TSchlange.AendereRichtung(NeueRichtung: integer);
begin
case NeueRichtung of
0: //Nach Oben
begin
if not Self.FRichtung = 1 then
begin
Self.FRichtung:= 0;
end;
end;
1: //Nach Unten
begin
if not Self.FRichtung = 0 then
begin
Self.FRichtung:= 1;
end;
end;
2: //Nach Links
begin
if not Self.FRichtung = 3 then
begin
Self.FRichtung:= 2;
end;
end;
3: //Nach Rechts
begin
if not Self.FRichtung = 2 then
begin
Self.FRichtung:= 3;
end;
end;
end;
FRichtung:= NeueRichtung;
FWurdeBewegt:= false;
end;
end.[/code]
Hier ist mal der ganze Code von der Schlange:
[code=laz]TSchlange = class(TObject)
FTeile: array[0..40*30-1] of TPoint;
FAnzahlTeile: Word;
FRichtung: Byte;
FWurdeBewegt: boolean;
FFarbe: TColor;
Richtung: Byte;
AnzahlTeile: Word;
FCanvas: TCanvas;
constructor Create;
function PruefeObTot: boolean;
function LiesTeil(index: Word): TPoint;
function Farbe: TColor;
property Teile[index: Word]: TPoint read LiesTeil;
property Canvas: TCanvas read FCanvas write FCanvas;
procedure Init;
procedure Render;
procedure Update;
procedure WachseUm1;
procedure AendereRichtung(NeueRichtung: integer);
end;
implementation
{ TSchlange }
constructor TSchlange.Create;
begin
FFarbe:= clWhite;
end;
function TSchlange.PruefeObTot: boolean;
var
i: integer;
index: word;
begin
for index:= 1 to FAnzahlTeile do
begin
if (FTeile[0].x = FTeile[index].x) and (FTeile[0].y = FTeile[index].y) then
begin
Result:= true;
Exit;
end;
end;
Result:= false;
end;
function TSchlange.LiesTeil(index: Word): TPoint;
begin
Result:= FTeile[index];
end;
function TSchlange.Farbe: TColor;
begin
Result:= FFarbe;
end;
procedure TSchlange.Init;
begin
FAnzahlTeile:= 2;
FTeile[0]:= Point(3, 3);
FTeile[1]:= Point(2, 3);
FTeile[2]:= Point(1, 3);
FRichtung:= 3;
FWurdeBewegt:= true;
end;
procedure TSchlange.Render;
var
index: word;
Startx, Starty: integer;
Endex, Endey: integer;
begin
FCanvas.Pen.Color:= Self.FFarbe;
FCanvas.Brush.Color:= Self.FFarbe;
for Index:= 0 to FAnzahlTeile do
begin
Startx:= FTeile[index].x * 16;
Starty:= FTeile[index].y * 16;
Endex:= FTeile[index].x * 16 + 16;
Endey:= FTeile[index].y * 16 + 16;
FCanvas.Rectangle(Startx, Starty, Endex, Endey);
end;
end;
procedure TSchlange.Update;
var
index: Word;
begin
//Teile hinterher ziehen
for index:= FAnzahlTeile downto 1 do
begin
FTeile[index]:= FTeile[index - 1];
end;
//Ablauf für das Verlassen des Spielfeldes und Wiedererscheinen auf der gegenüberliegenden Seite
case FRichtung of
0: //Bewegung nach oben
begin
FTeile[0].y:= FTeile[0].y - 1;
if FTeile[0].y < 0 then
begin
FTeile[0].y:= 29;
FWurdeBewegt:= true;
end;
end;
1: //Bewegung nach unten
begin
FTeile[0].y:= FTeile[0].y + 1;
if FTeile[0].y > 29 then
begin
FTeile[0].y:= 0;
FWurdeBewegt:= true;
end;
end;
2: //Bewegung nach links
begin
FTeile[0].x:= FTeile[0].x - 1;
if FTeile[0].x < 0 then
begin
FTeile[0].x:= 39;
FWurdeBewegt:= true;
end;
end;
3: //Bewegung nach rechts
begin
FTeile[0].x:= FTeile[0].x + 1;
if FTeile[0].x > 39 then
begin
FTeile[0].x:= 0;
FWurdeBewegt:= true;
end;
end;
end;
end;
procedure TSchlange.WachseUm1;
begin
FAnzahlTeile:= FAnzahlTeile + 1;
end;
procedure TSchlange.AendereRichtung(NeueRichtung: integer);
begin
case NeueRichtung of
0: //Nach Oben
begin
if not Self.FRichtung = 1 then
begin
Self.FRichtung:= 0;
end;
end;
1: //Nach Unten
begin
if not Self.FRichtung = 0 then
begin
Self.FRichtung:= 1;
end;
end;
2: //Nach Links
begin
if not Self.FRichtung = 3 then
begin
Self.FRichtung:= 2;
end;
end;
3: //Nach Rechts
begin
if not Self.FRichtung = 2 then
begin
Self.FRichtung:= 3;
end;
end;
end;
FRichtung:= NeueRichtung;
FWurdeBewegt:= false;
end;
end.[/code]
Re: ArrayIndex eines anderen Objektes benutzen
sorry aber weis nicht wie man hier den quelltext vernünftig einfügt
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: ArrayIndex eines anderen Objektes benutzen
Nugi89 hat geschrieben:sorry aber weis nicht wie man hier den quelltext vernünftig einfügt
Sollte so passen. Wenn ich es zu mir hereinkopiere wird es richtig angezeigt.
Ev. im persönlichen Bereich/Einstellungen/ BBCode/Nachrichten erstellen BBCode deaktiviert bzw. unten in der Eingabemaske vom Forum unter Optionen BBCode ausschalten aktiviert ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: ArrayIndex eines anderen Objektes benutzen
Dann erstelle doch einfach eine Funktion (z.B. in Klasse TSchlange), die prüft, ob ein Punkt gerade auf einer Schlange liegt (siehe oben). z.B. (ungetested):Nugi89 hat geschrieben:Bei meiner schlange sind nur die FTeile vom array of TPoint.
Code: Alles auswählen
function TSchlange.IsOnPoint(p: TPoint): Boolean;
var
aPoint: TPoint;
begin
Result := false;
for aPoint in FTeile do
if (p.x = aPoint.x) and (p.y = aPoint.y) then Result := true;
end;
Diese kannst du von extern aufrufen z.B.
Code: Alles auswählen
var
Schlange: TSchlange;
...
repeat
FutterPunkt.x := Random(40);
FutterPunkt.y := Random(30);
until not Schlange.IsOnPoint(FutterPunkt);
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: ArrayIndex eines anderen Objektes benutzen
danke also soweit klappt es ja schonmal, bis auf das dass Futter jetzt nur am rum springen ist. ^^
Re: ArrayIndex eines anderen Objektes benutzen
Das passiert, wenn man einfach was abtippt... Sorry...Nugi89 hat geschrieben:danke also soweit klappt es ja schonmal, bis auf das dass Futter jetzt nur am rum springen ist. ^^
Als kleiner Hinweis:
Code: Alles auswählen
procedure TSchlange.Init;
begin
FAnzahlTeile:= 2;
FTeile[0]:= Point(3, 3);
FTeile[1]:= Point(2, 3);
FTeile[2]:= Point(1, 3);
...
Was ist mit den restlichen Einträgen des Arrays FTeile? Evtl. schaust du dir noch die andere Funktion weiter oben an, evtl. kannst du diese ja mit FAnzahlTeile kombinieren?!
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: ArrayIndex eines anderen Objektes benutzen
Mit FTeile aus der procedure TSchlange.Init lege ich ja nur den Startpunkt der 3 Teile der Schlange fest und deren Anfangrichtung.Wüsste jetzt auch gerade nicht wie ich diese mit FAnzahlTeile kombinieren sollte?
aber ich weis worauf du hinaus willst. Hab da gerade voll ein Brett vorm Kopf.
aber ich weis worauf du hinaus willst. Hab da gerade voll ein Brett vorm Kopf.
Re: ArrayIndex eines anderen Objektes benutzen
Da ich das Prog nicht vorliegen habe, versuche ich dir mal den theoretischen Fehler zu erklären.
Mit "aPoint in FTeile" geht die Schleife alle Elemente von FTeile durch. FTeile hat eine Größe von 1200 (30 x 40) Elementen. Wenn du aber nur die ersten drei Elemente initialisert hast, was passiert dann, wenn aPoint auf dem vierten Element ankommt?!
Um so einen Fehler zu finden kann man auch wunderbar den Debugger einsetzen (Breakpoint setzen, mit F7 durch den Code steppen und immer dabei die Variableninhalte anschauen).
Wie auch immer, die Schlange soll sich ja in der Länge verändern. Das realisierst du sicherlich mit der Erhöhung von FAnzahlTeile?! Damit kannst du jetzt auch immer nur die entsprechende Zahl von FTeile nach einer Übereinstimmung durchforsten. So könnte es aussehen:wobei FAnzahlTeile bei 3 Schlangenelementen auch 3 und nicht 2 sein müsste...
Mit "aPoint in FTeile" geht die Schleife alle Elemente von FTeile durch. FTeile hat eine Größe von 1200 (30 x 40) Elementen. Wenn du aber nur die ersten drei Elemente initialisert hast, was passiert dann, wenn aPoint auf dem vierten Element ankommt?!
Um so einen Fehler zu finden kann man auch wunderbar den Debugger einsetzen (Breakpoint setzen, mit F7 durch den Code steppen und immer dabei die Variableninhalte anschauen).
Wie auch immer, die Schlange soll sich ja in der Länge verändern. Das realisierst du sicherlich mit der Erhöhung von FAnzahlTeile?! Damit kannst du jetzt auch immer nur die entsprechende Zahl von FTeile nach einer Übereinstimmung durchforsten. So könnte es aussehen:
Code: Alles auswählen
function TSchlange.IsOnPoint(p: TPoint): Boolean;
var
i: Integer;
begin
Result := false;
for i := 0 to FAnzahlTeile - 1 do
if (FTeile.x = p.x) and (FTeile.y = p.y) then Result := true;
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: ArrayIndex eines anderen Objektes benutzen
Werde es mal probieren so und mal mit dem Debugger.
Werde morgen antworten.
Werde morgen antworten.
Re: ArrayIndex eines anderen Objektes benutzen
Habe das ganze jetzt mal durchtesten können. der Fresspunkt springt immer noch wie wild hin und her. Mit dem Debugger bin ich den Abschnitt mal durchgegangen und mir scheint als ob die Fresspunkte (p.y und p.x) irgendwie gleich gesetzt werden, obwohl sie aber random erzeugt werden.
Hab das vom Code her so gemacht:
Die eigentliche Abfrage:
Hier die Funktion in der Klasse Schlange:
Ich habe keinen Plan wieso das Futter rum springt.
Hab das vom Code her so gemacht:
Die eigentliche Abfrage:
Code: Alles auswählen
if(Snake.FTeile[0].x = Happen.Haeppchen.x) and (Snake.FTeile[0].y = Happen.Haeppchen.y) then
begin
fressen;
end
else
begin
repeat
Happen.Haeppchen.x:= Random(35) +2;
Happen.Haeppchen.y:= Random(25) +2;
until not Snake.IsOnPoint(Happen.Haeppchen);
end;
Hier die Funktion in der Klasse Schlange:
Code: Alles auswählen
function TSchlange.IsOnPoint(p: TPoint): boolean;
var
i: integer;
index: Word;
begin
Result:= false;
for i:= 0 to FAnzahlTeile - 1 then
begin
if (FTeile[index].x = p.x) and (FTeile[index].y = p.y) then
begin
Result:= true;
end;
end;
end;
Ich habe keinen Plan wieso das Futter rum springt.
Re: ArrayIndex eines anderen Objektes benutzen
Ich habe keine Ahnung, in welcher Methode der obere gepostete Code zum Einsatz kommt und kann dir dazu nichts sagen.
Im zweiten geposteten Code ist aber ein Hund begraben. Ich dokumentiere den Code einmal.
Irgenwie hatte ich da ein "[i]" in dem geposteten Code vergessen (das kommt davon, wenn man den Code nicht testet )
Besser daher so:
PS: evtl. ist es besser das Projekt (ohne Exe) in ein Zip zu packen und hier anzuhängen, dann könnte man den Code tatsächlich auch testen.
Im zweiten geposteten Code ist aber ein Hund begraben. Ich dokumentiere den Code einmal.
Code: Alles auswählen
function TSchlange.IsOnPoint(p: TPoint): boolean;
var
i: integer;
index: Word; //ein Index - Variable mit dem Inhalt 0 oder sonstiger Zahl
begin
Result:= false;
for i:= 0 to FAnzahlTeile - 1 then //<- das kann nicht kompiliert werden, statt "then" hätte dort ein "do" hin gehört
begin
if (FTeile[index].x = p.x) and (FTeile[index].y = p.y) then //hier hat der Index immer noch den undefinierten Inhalt...
begin
Result:= true;
end;
end;
end;
Irgenwie hatte ich da ein "[i]" in dem geposteten Code vergessen (das kommt davon, wenn man den Code nicht testet )
Besser daher so:
Code: Alles auswählen
function TSchlange.IsOnPoint(p: TPoint): boolean;
var
index: Word;
begin
Result := false;
for index := 0 to FAnzahlTeile - 1 do
begin
if (FTeile[index].x = p.x) and (FTeile[index].y = p.y) then
begin
Result := true;
end;
end;
end;
PS: evtl. ist es besser das Projekt (ohne Exe) in ein Zip zu packen und hier anzuhängen, dann könnte man den Code tatsächlich auch testen.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;