ArrayIndex eines anderen Objektes benutzen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.

ArrayIndex eines anderen Objektes benutzen

Beitragvon Nugi89 » 18. Aug 2015, 10:13 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 :oops:

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.
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon theo » 18. Aug 2015, 10:51 Re: ArrayIndex eines anderen Objektes benutzen

:?:
theo
 
Beiträge: 8167
Registriert: 11. Sep 2006, 18:01

Beitragvon Nugi89 » 18. Aug 2015, 11:46 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?
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon Michl » 18. Aug 2015, 12:33 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):
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;
oder
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; 
Michl
 
Beiträge: 2320
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon Nugi89 » 18. Aug 2015, 12:48 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]
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon Nugi89 » 18. Aug 2015, 12:50 Re: ArrayIndex eines anderen Objektes benutzen

sorry aber weis nicht wie man hier den quelltext vernünftig einfügt :( :oops:
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon af0815 » 18. Aug 2015, 12:59 Re: ArrayIndex eines anderen Objektes benutzen

Nugi89 hat geschrieben:sorry aber weis nicht wie man hier den quelltext vernünftig einfügt :( :oops:

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).
af0815
 
Beiträge: 3651
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon Michl » 18. Aug 2015, 13:12 Re: ArrayIndex eines anderen Objektes benutzen

Nugi89 hat geschrieben:Bei meiner schlange sind nur die FTeile vom array of TPoint.
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):
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; 
Michl
 
Beiträge: 2320
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon Nugi89 » 18. Aug 2015, 13:28 Re: ArrayIndex eines anderen Objektes benutzen

danke also soweit klappt es ja schonmal, bis auf das dass Futter jetzt nur am rum springen ist. ^^
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon Michl » 18. Aug 2015, 14:05 Re: ArrayIndex eines anderen Objektes benutzen

Nugi89 hat geschrieben:danke also soweit klappt es ja schonmal, bis auf das dass Futter jetzt nur am rum springen ist. ^^
:) Das passiert, wenn man einfach was abtippt... Sorry...

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; 
Michl
 
Beiträge: 2320
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon Nugi89 » 18. Aug 2015, 14:27 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. :oops:
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon Michl » 18. Aug 2015, 15:11 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:
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;
wobei FAnzahlTeile bei 3 Schlangenelementen auch 3 und nicht 2 sein müsste...
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2320
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon Nugi89 » 18. Aug 2015, 15:23 Re: ArrayIndex eines anderen Objektes benutzen

Werde es mal probieren so und mal mit dem Debugger.
Werde morgen antworten.
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon Nugi89 » 19. Aug 2015, 14:05 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:

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. :oops:
Nugi89
 
Beiträge: 68
Registriert: 26. Feb 2015, 13:46

Beitragvon Michl » 19. Aug 2015, 14:58 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.
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 :roll: )

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; 
Michl
 
Beiträge: 2320
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Sonstiges



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried