Kreis in einem 2d-Array

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Littellittel
Beiträge: 20
Registriert: Mi 22. Apr 2015, 16:25

Kreis in einem 2d-Array

Beitrag von Littellittel »

Hallo,
ich bin realtiv neu im Programmieren und wollte mich nun an einem Tower defens spiel probieren. Ich bin so weit das ich Tower setzen kann und ein Gegner einen Weg entlang geht. Jetzt wollte ich den Turm auf den Gegner schießen lassen sofern er in der Reichweite des Towers ist. Die Position des Gegners ebenso wie die des Turmes ist in einem Array gespeichert. Ich bin leider daran gescheitert zu überprüfen ob der Gegner im Radius ist, zudem weiß ich nicht wie ich den Weg des Projektils berechnen soll. :cry:
Danke im Voraus für jegliche Hilfe.

Mathias
Beiträge: 6916
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Kreis in einem 2d-Array

Beitrag von Mathias »

Da der Turm und der Gegner eine xy-Position hat, sollte es eigentlich mit dem Pythagoras zu lösen sein.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Littellittel
Beiträge: 20
Registriert: Mi 22. Apr 2015, 16:25

Re: Kreis in einem 2d-Array

Beitrag von Littellittel »

Danke für die Antwort,
ich habe ein bisschen rumprobiert und gegoogelt aber mir ist trotzdem nicht ganz klar wie ich mittels des Pythagoras dem Projektil sagen kann wo es lang fliegen soll. Ich kann halt den Abstand ermitteln aber wie kann ich den Weg des Projektils lenken? Ich habe zwar eine Linie aber wie soll ich dem Projektil sagen das es der Linie folgen soll?

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1620
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Kreis in einem 2d-Array

Beitrag von corpsman »

Schau die mal das PingPong Beispiel an, da ist bewegung und Kollision mit dabei.
--
Just try it

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Kreis in einem 2d-Array

Beitrag von Komoluna »

hast du dich schonmal mit Vektoren beschäftigt?
Ohne selbige wird das nämlich relativ schwer zu implementieren.

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

Littellittel
Beiträge: 20
Registriert: Mi 22. Apr 2015, 16:25

Re: Kreis in einem 2d-Array

Beitrag von Littellittel »

Komoluna hat geschrieben:hast du dich schonmal mit Vektoren beschäftigt?
Ohne selbige wird das nämlich relativ schwer zu implementieren.

MFG

Komoluna
Danke, Ich habe es nun Geschafft das das Projektil auf den Gegner zufliegt sofern sich dieser im Radius des Turmes befindet. Allerdings bin ich nun auf ein neues Problem gestoßen welches ich nicht zu lösen vermag. Ich habe bis jetzt immer nur einen Gegner auf dem Feld gehabt, Ich habe mittels zweier for-Shleifen (in einem Timer) das Array nach dem Aktuellen Standpunkt durchsucht und ihn dann dementsprechend Beweg. Damit er sich aber nur einmal pro Intervall des Timers bewegt benutze ich "break;" um die schleife zu unterbrechen, Jetzt (mit mehreren Gegnern) bewegt sich aber natürlich immer nur einer. Jetzt meine Frage: Wie schaffe ich es das jeder Wert (Integer) nur einmal bewegt wird (es sind die selben Zahlen weil es der selbe Gegnertyp ist)?

Danke an die schnellen und Hilfreichen Antworten.

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Kreis in einem 2d-Array

Beitrag von Komoluna »

Littellittel hat geschrieben: Ich habe bis jetzt immer nur einen Gegner auf dem Feld gehabt, Ich habe mittels zweier for-Shleifen (in einem Timer) das Array nach dem Aktuellen Standpunkt durchsucht und ihn dann dementsprechend Beweg. Damit er sich aber nur einmal pro Intervall des Timers bewegt benutze ich "break;" um die schleife zu unterbrechen, Jetzt (mit mehreren Gegnern) bewegt sich aber natürlich immer nur einer. Jetzt meine Frage: Wie schaffe ich es das jeder Wert (Integer) nur einmal bewegt wird (es sind die selben Zahlen weil es der selbe Gegnertyp ist)?
Sry, aber daraus werde ich nicht schlau. Poste doch einfach mal deinen Timercode (Highlighter nicht vergessen).

P.S.: Ah, jetzt hab ichs verstanden... nimm einfach das break raus, und frag vor dem bewegen eines Gegners, ob das zielfeld noch frei ist.
(Deinen Code darfst du trotzdem gerne posten)

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

Littellittel
Beiträge: 20
Registriert: Mi 22. Apr 2015, 16:25

Re: Kreis in einem 2d-Array

Beitrag von Littellittel »

Code: Alles auswählen

procedure TForm1.tmWegTimer(Sender: TObject);
var
  i,j:integer;
begin
  fertig:=false;
  for i:=0 to 401 do
        begin for j:=0 to 401 do
              begin if Enemypos[i,j]=101 then              //break um zu verhindern das
                          begin Enemypos[i,j-1]:=101;      //er einen gegner vor sich
                                Enemypos[i,j]:=0;          //herschiebt, weil er sie sonst
                                break;                     //mehrfach findet und bewegt
                          end;
                          if Feld[i,j]=2 then              //101=der Gegner
                          begin Enemypos[i+1,j]:=101;      //die Zahlen 1-4 in einem anderen
                                Enemypos[i,j]:=0;          //Array die den weg darstellen
                                break;                     //(die Richtung)
                          end;
                          if Feld[i,j]=3 then
                          begin Enemypos[i,j+1]:=101;
                                Enemypos[i,j]:=0;
                                break;
                          end;
                          if Feld[i,j]=4 then
                          begin Enemypos[i-1,j]:=101;
                                Enemypos[j,i]:=0;
                                break;
                          end;
                    end;
              end;
        end;
  draw;
end;
das ist mein code^^
nur wenn ich das break rausnehme schiebt er den Gegner vor sich her weil er ihm im nächsten schritt noch einmal findet und das Feld vor dem Gegner ist ja trotzdem frei.

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Kreis in einem 2d-Array

Beitrag von Komoluna »

Ich würde das array immer mit irgendeinem erweiterten Typen (record/class) befüllen:

Code: Alles auswählen

 
TFieldTile = record
  Processed: Boolean;
  Groundtype: Integer; //Byte reicht eigentlich auch
  Enemy: Integer;       //<- Genauso hier
end;
Field: array of array of TFieldTile;
Und dann in deinem Timer:

Code: Alles auswählen

 
procedure TimerProc;
 
  procedure ProcessTile(ax,ay: Integer);
  begin
    if Field[ax,ay].Processed then
      exit;
    if Field[ax,ay].Enemy<>0 then
    begin
      {wenn zielfeld geblockt}
      begin
        ProcessTile(ax+mx,ay+my);
      end;
      {Gegner bewegen}
    end;
    Field[ax,ay].Processed:=True;
  end;
 
{X-Y Schleife}
begin
  Field[x,y].Processed:=False;
end;
{X-Y Schleife}
begin
  ProcessTile[x,y];
end;
(einfach Freihand geschrieben, keine garantie ;-) )

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

Littellittel
Beiträge: 20
Registriert: Mi 22. Apr 2015, 16:25

Re: Kreis in einem 2d-Array

Beitrag von Littellittel »

Mhhh, das versteh ich nicht ganz. Ich hab mal deinen code kopiert und meine Gedanken/Fragen drangeschrieben, wäre nett wenn du mir sie beantworten könntest auch wenn sie vielleicht ein bischen sehr basic sind :D. Außerdem sieht mein Array anders aus:

Code: Alles auswählen

Feld, Enemypos:Array [0..401,0..401] of integer; //TFieldTile findet er nicht 

Code: Alles auswählen

procedure TimerProc;
 
  procedure ProcessTile(ax,ay: Integer);  //was sind ax und ay für Werte? die koordinaten des Gegners?
  begin
    if Field[ax,ay].Processed then        //ich kann nichts weiter angeben wie .Processed mir wird gesagt das da ein illegaler Bezeichner ist
      exit;
    if Field[ax,ay].Enemy<>0 then         //hir wird abgefragt ob auf dem Aktuellen Feld ein Gegner steht
    begin
      {wenn zielfeld geblockt}
      begin                               //was bewirken zwei begin´s hintereinander?
        ProcessTile(ax+mx,ay+my);         //was sind mx und my für Werte? und was macht ProcessTile?
      end;
      {Gegner bewegen}
    end;
    Field[ax,ay].Processed:=True;         //das Bewirkt das er nicht weiter schaut, oder? Das heißt doch das er trotzdem nur einen Bewegt, die Koordinaten des Gegners ändern sich ja auch
  end;
 
{X-Y Schleife}
begin
  Field[x,y].Processed:=False;            //das setzt bei jedem wert Processed auf false richtig?
end;
{X-Y Schleife}
begin
  ProcessTile[x,y];                       //ProcessTile?, was heißt das?
end;                                      //sry wenn die Fragen zu dumm sind ;D 

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Kreis in einem 2d-Array

Beitrag von Komoluna »

Statt feld und EnemyPos brauchst du nurnoch ein array. in meinem Code habe ich ein dynamisches array (kann die größe zur laufzeit ändern) beschrieben. Ein statisches Array geht natürlich auch.
das TFieldTile hatte ich direkt darüber definiert, es muss aber in den "Type" Abschnitt der Unit(da wo auch TForm = class(TForm)... steht).
ProcessTile ist eine Prozedur, die nur in deiner TimerProzedur aufgerufen werden kann.

Das kommt zwischen das "procedure TimerProcedure" und das begin direkt dadrunter.
Das ist halt ein bezeichner, der nur innerhalb dieser Methode gültig ist, wie lokale Variablen.

Alle Abschnitte in dem Beispiel mit geschweiften Klammern muss du durch Code ersetzen.
z.b. {X-Y Schleife} mit

Code: Alles auswählen

for x:=0 to 401 do
for y:=0 to 401 do
das {wenn zielfeld geblockt} halt mit einer if klausel, die abfragt, ob auf dem feld ax+mx ay+my ein gegner steht. Dadurch stehen dann auch keine 2 begin's hintereinander

mx und my steht für movex und movey. Das gibt einfach nur die bewegungsrichtung des gegners an
beide variablen müssen werte zwischen -1 und 1 haben.

ProcessTile ist eine sich selbst aufrufende Methode (Rekursiv siehe http://de.wikipedia.org/wiki/Rekursion oder meine Signatur).

Sollte dir nach diesem Post immernoch nicht klar sein, was ich meine, so guck dir doch bitte einfach ein Tutorial zum Thema Objektorientierte Programmierung (Prozeduren und Records) and:
http://de.wikibooks.org/wiki/Programmie ... Funktionen
http://de.wikibooks.org/wiki/Programmie ... l:_Records

Wenn du dann immernoch nicht weiterweißt, darfst du gerne wieder unsere Hilfe in Anspruch nehmen ;-)

Und zu guter letzt: es gibt keine dummen Fragen.

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

Littellittel
Beiträge: 20
Registriert: Mi 22. Apr 2015, 16:25

Re: Kreis in einem 2d-Array

Beitrag von Littellittel »

Ah!,
vielen dank ich habe meinen code entsprechend abgeändert und jetzt funktioniert alles so wie es soll 8) .
Vielen Danke.

Antworten