nächstgelegenes Ziel anvisieren

Startseite Foren Deutsches LiveCode-Forum nächstgelegenes Ziel anvisieren

Schlagwörter: 

Ansicht von 40 Antwort-Themen
  • Autor
    Beiträge
    • #31374
      akrages
      Teilnehmer

        Hallo und guten Abend.
        Ich versuche mich gerade an einer Art „TowerDefense“ Spiel.
        Gibt es eine Möglichkeit, dem Tower zu sagen, dass er das nächstgelegene Ziel anvisieren soll?
        Und wenn dieses außer Reichweite ist, wieder das nächste Nächstgelegen Ziel… usw.?

      • #31378
        Torsten
        Teilnehmer

          Hi Akrages,

          die Lösung ist: Berechne für jedes Ziel den Abstand zum Turm und sortiere die Liste der Abstände.

          Nehmen wir an, die Namen aller Ziele (z.B. von Grafik-Objekten) sind in einer Liste vorhanden.
          Dann würde ich folgenden Code nehmen:

          put the loc of graphic tTower into tTowerLoc
          repeat for each line tTarget in tTargetList
             put the loc of graphic tTarget into tTargetLoc 
             -- an dieser Stelle kommt der gute alte Pythagoras hervor: a^2 + b^2 = c^2
             -- bitte zunächst selbst versuchen :-)
          end repeat 
          
          sort lines of tDistancesTargetTower numeric ascending

          Falls Du gar nicht weiterkommst, habe ich die Lösung schon mal programmiert, aber ich will Dir den Spass der Auffrischung der Schulmathematik (endlich mal eine sinnvoll Anwendung!) niocht nehmen 🙂

          Happy Coding!
          Torsten

        • #31484
          akrages
          Teilnehmer

            Vielen Dank für den Denkanstoß.
            Habe damit eine für mich gute Lösung gefunden.
            Nun stehe ich vor einer weiteren Herausforderung.
            Ich möchte gerne, dass sich die auf einem definierten Pfad bewegenden „Feinde“ bei einer Richtungsänderung, immer in Laufrichtung drehen.

            Also in etwa so etwas:

               if there is a grp ("TankA" & i) then
                  if intersect(grp "TankA1", graphic "Knoten1", "opaque Pixels") then set the angle of img "Tank" of grp "TankA1" to 26 
                  ##wait 1 milliseconds with messages
                  if the loc of grp "TankA1" = 403,326 then set the angle of img "Tank" of grp "TankA1" to 85
                  if the loc of grp "TankA1" = 409,232 then set the angle of img "Tank" of grp "TankA1" to 0
               end if

            Die graphic „Knoten befindet sich also immer an dem Punkt, an dem eine Richtungsänderung stattfindet.
            Das funktioniert zwar ganz gut, hat aber den Nachteil, das ich für derzeit fünf „Feinde“ für jeden Feind alle Knoten in einer neuen Zeile berücksichtigen muss.

            Und da ich mit:

            repeat with i = 1 to 5 ##Die zweite Ziffer ist die Anzahl der Feinde z.B. Ziffer ist 5 = 5 Feinde werden generiert!
                  clone grp "TankA" 
                  set the name of the last grp to ("TankA" & i)
                  set the loc of the last grp to (-30),(383) ##Hier werden die geclonten Feinde plaziert!
                  set the visible of the last grp to true
                  set the layer of the last grp to 3
                  wait .5 seconds with messages
               end repeat

            die fünf „Feinde generiere ist es auch ganz schön umständlich. Vor allem wenn ich später mal mehr als fünf „Feinde“ in das Spiel bringe.

            Hat jemand eine elegantere Idee zur Umsetzung?
            Am besten wäre es, wenn sich oben genannter Code im „Feind“ selber befände.
            Aber das funktioniert leider nicht.

          • #31542
            Torsten
            Teilnehmer

              Hallo akrages,

              ganz generell gesprochen baust Du gerade eine Simulation mit Objekten, die sich alle nach bestimmten Regeln verhalten sollen. In diesem Fall ist es, wie Du schon richtig bemerkt hast, am besten, das Verhalten = Code IM Objekt zu haben.
              Das geht auf zwei Weisen:

              1. Ein Objekt mit dem entsprechenden Objekt-Script erstellen und dieses dann entsprechend klonen.

              2. Das Objekt hat statt eines eigenen Skripts ein Behavior, d.h. es „erbt“ das Skript von einem anderen Objekt (typischerweise ein Button) mit dem Unterschied, dass in diesem Fall das Skript nur einmal existiert und daher auch nur einmal verändert werden muss, falls Du etwas neu machen willst. Auch die schon existierenden Objekte zeigen dann das neue Verhalten, bei 1. müsstest Du erstmal alle alten Objekte löschen und wieder neu klonen.

              Ich denke, die zweite Methode ist deshalb für Deine Zwecke besser geeignet.

              Happy Coding
              Torsten

            • #31544
              Klaus Major
              Administrator

                Kleiner Tip:

                ...
                repeat with i = 1 to 5
                   put ("TankA" & i) into tGruppenName
                
                   ## Wir können CLONEN und UMBENENNEN in einem Rutsch!
                   clone grp "TankA" AS tGruppenName
                   set the loc of grp tGruppenName to (-30),(383)
                   set the visible of grp tGruppenName to true
                   set the layer of grp tGruppenName to 3
                   wait .5 seconds with messages
                end repeat
                ...
              • #31546
                akrages
                Teilnehmer

                  Hallo Torsten.

                  Zu 1. Ich habe eine sogenannte (Schablonen-Gruppe) als „Feind“. Diese wird bei Spielstart fünfmal geclont. D.h. Die erste Lösung sollte keinen allzugroßen Aufwand bedeuten.
                  Bis auf die Umsetzung….

                  Die Türme (im Moment ist es, da ich noch am Testen bin nur einer) sollen dann auf die gleiche Weise geclont werden. Wenn sich jetzt das Script in der „Schablone befindet, dann befindet sich ja auch in jedem Clon das selbe Script und somit müsste jeder Turm eigenständig auf nahende „Feinde“ reagieren und deshalb glaube ich, dass das schon eine recht gute Lösung sein könnte.

                  Zu 2. Hört sich auch interresant an bliebe vom Aufwand her aber in meinem Fall gleich oder?

                  Aber um die erste Lösung umzusetzen brauche ich deine Hilfe.
                  Wie muss das Script aussehen, damit der Turm bzw. der Feind auch darauf reagiert?

                • #31596
                  Torsten
                  Teilnehmer

                    Die grundsätzliche Logik hat zwei Teile:

                    1. Bewegen der Ziele auf einem festen Pfad / Route
                    2. Entscheidung des Turms, ob und welches Ziel er attackiert

                    zu 1:

                    Eine der simpelsten Möglichkeiten, ein Objekt auf einer Strecke entlang zu bewegen ist:

                    move OBJEKT to the points of CURVEDLINE in XX seconds
                    OBJEKT = deine Graphic, Image etc.
                    CURVEDLINE = eine Polyline, die man mir der Mouse zeichnen kann

                    zu 2:

                    Die Türme müssen in regelmäßigen Abständen prüfen, ob Feinde in der Nähe sind und wer davon am nähesten ist.
                    Dazu brauchst Du die loc vom Turm und die locs der Feinde und musst dann mittels des guten alten Pythagoras die Entfernung von jedem Feind zum Turm bestimmen. Diese Liste wird dann nach Entfernung sortiert und der erste in der Liste ist das Ziel 🙂

                    -- Ermittelt die Distanz zwischen zwei Livecode-Locations (deren Format ist ja jeweils x,y z.B. 123,23) mittels Pythagoras: a^2 + b^2 = c^2
                    -- die Länge der Hypothenuse ist die Entfernung, da die jeweiligen Abstände der x und y-Werte ein rechtwinkliges Dreieck bilden
                    ------------------------------------------------------------------
                    function loc_distance pLoc_1, pLoc_2
                       
                       return round(sqrt(abs(item 1 of pLoc_1 - item 1 of pLoc_2)^2 + abs(item 2 of pLoc_1 - item 2 of pLoc_2)^2),2)
                       
                    end loc_distance

                    Happy Coding
                    Torsten

                  • #31849
                    akrages
                    Teilnehmer

                      Hallo Torsten.
                      Deine Antwort #31542
                      1. Ein Objekt mit dem entsprechenden Objekt-Script erstellen und dieses dann entsprechend klonen.

                      Wie geht das?
                      Also das klonen und plazieren des Turms ist kein Problem.
                      das mache ich mit diesem Code:

                      global lTowerXplaceOld, lTowerOffPlaceNeu
                      global lCloneTowerOff, lCloneTowerOn
                      on mouseDown
                         put the loc grp "TowerX.png" into lTowerXplaceOld ## Der Loc der Vorlage
                         lock screen
                         grab me
                         set the loc of me to the mouseloc
                      unlock screen
                      end mouseDown
                      
                      on mouseUp
                         put the mouseloc into lToweOffPlaceNeu
                         set the loc of Group "TowerX.png" to lTowerXplaceOld ##Die Vorlage wieder zurück auf ihren Ursprungsloc
                         clone grp "TowerOffVorlage"
                         add 1 to lCloneTowerOff
                         set the name of the last grp to ("TowerOff" & lCloneTowerOff)
                         set the loc of last grp to lToweOffPlaceNeu
                         
                         ##Den Geschützturm clonen.
                         clone img "TowerOnVorlage"
                         add 1 to lCloneTowerOn
                         ##Das geclonte img "TowerOn" in "TowerOn1" umbenennen
                         set the name of the last img to ("TowerOn" & lCloneTowerOn) ##img TowerOn heißt jetzt TowerOn1
                         
                         if there is a img ("TowerOn" & lCloneTowerOn) then 
                            ####portiere den geclonten Tower zur entsprechenden Plattform. 
                            set the visible of img ("TowerOn" & lCloneTowerOn) to false
                            set the loc of img ("TowerOn" & lCloneTowerOn) to lToweOffPlaceNeu
                            set the loc of img "Beam" to lToweOffPlaceNeu
                            set the loc of img "Beam2" to lToweOffPlaceNeu
                            show btn "Start"
                         end if
                      end mouseUp

                      Aber wie muss der Code im Turm aussehen, damit der geclonte Turm dann auch eigenständig reagiert?

                    • #31864
                      akrages
                      Teilnehmer

                        Kaum fragt man…

                        Habs jetzt rausgefunden.
                        Ich habe diesen Code in der „Vorlagen-Gruppe“

                        global lCloneTowerOff, lCloneTowerOn, gRadar, gFeuerFrei
                        global i, x, z

                        on checkLocation  --checks if the tower is in range at stops on the path. this is in the img script
                           if there is a grp ("TankA" & i) then
                              ##answer "Yes there is a group of Tanks"
                              ## Wenn der Feind sich im Erfassungsbereich des Radars des Turms befindet,
                              ## dann wird der Turm "ausgefahren" (sichtbar).
                              if distance (the loc of grp ("TankA" & i),the loc of me) < gRadar  then
                                 ##answer "Yes there is a group of Tanks"
                                 set the visible of img ("TowerOn" & lCloneTowerOn) to true
                                 TankATarget1  
                                 
                                 ## Wenn der Feind sich im Feuerbereich der Türme befindet, dann Feuer frei auf den
                                 ## nächstgelegenen sichtbaren Feind.
                                 if distance(the loc of grp ("TankA" & i),the loc of me) < gFeuerFrei then
                                    if the visible of grp ("TankA" & i) is true then
                                       moveBeam1u2 ##Immo wir nur der letzte Feind beschossen!?
                                    end if
                                 end if
                              end if
                           end if
                        end checkLocation

                        und im CardScript folgendes:

                        on updateScreen 
                           if sGameRunning is true then     
                              detectCollisions
                        call "checkLocation" of grp "TowerOff1" of cd "Welle_001"
                           end if  
                        end updateScreen

                        Der Turm grp „TowerOff1“ macht jetzt was er soll.
                        ABER…

                        Wenn ich einen zweiten Turm clone, dann reagiert dieser nicht.
                        d.h. Es reagiert immer nur der Turm, dem sich die Feinde zuerst nähern. Egal ob es sich dabei bei z.B. 2 gclonten Türmen um den ersten oder zweiten Clon handelt. Sobald die Gruppe der Feinde außer Reichweite des einen Turms ist und sich der Reichweite des anderen Turms nähert, reagiert dieser nicht.
                        Woran kann das jetzt wieder liegen?

                      • #31927
                        Torsten
                        Teilnehmer

                          Hi,
                          ich habe erstmal deinen Code etwas umstrukturiert, um ihn leichter lese- und wartbarer zu machen. Da hast eine Menge if-Strukturen, die nicht verzweigen, sondern den Handler beenden. Das ist übersichtlicher, wenn man diese nacheinander auflistet, anstatt sie immer weiter zu verschachteln.

                          Meine Kommentare habe ich mit –> im Skript eingefügt, der wichtigste könnte die Frage sein, wer die Variable i eingentlich hochsetzt.

                          
                          global lCloneTowerOff, lCloneTowerOn, gRadar, gFeuerFrei
                          global i, x, z
                          
                          on checkLocation  --checks if the tower is in range at stops on the path. this is in the img script
                             
                             --> Wer modifiziert die globale Variable i?
                             
                             if there is no grp ("TankA" & i) then
                                exit checkLocation
                             end if
                             --> wenn kein TankA & i existiert, braucht der Rest nicht ausgeführt zu werden
                             
                             if the visible of grp ("TankA" & i) is false then
                                exit checkLocation
                             end if
                             --> wenn der Tank unsichtbar ist, braucht der Rest nicht ausgeführt zu werden
                             
                             ## Wenn der Feind sich im Erfassungsbereich des Radars des Turms befindet,
                             ## dann wird der Turm "ausgefahren" (sichtbar).
                             if distance (the loc of grp ("TankA" & i),the loc of me) > gRadar  then
                                exit checkLocation
                             end if
                             --> ist der Tank nicht im Range, braucht der Rest nicht ausgeführt zu werden
                             
                             set the visible of img ("TowerOn" & lCloneTowerOn) to true
                             
                             TankATarget1  --> ??? Was soll dieser Befehl bedeuten ???
                             
                             ## Wenn der Feind sich im Feuerbereich der Türme befindet, dann Feuer frei auf den
                             ## nächstgelegenen sichtbaren Feind.
                             if distance(the loc of grp ("TankA" & i),the loc of me) < gFeuerFrei then
                                moveBeam1u2 ##Immo wir nur der letzte Feind beschossen!?
                                --> seltsamer Befehl, was passiert da?
                                
                             end if
                             
                          end checkLocation
                        • #31929
                          Torsten
                          Teilnehmer

                            Fehler im ersten Skript?

                            put the loc grp "TowerX.png" into lTowerXplaceOld ## Der Loc der Vorlage

                            muss heissen:

                            put the loc of grp "TowerX.png" into lTowerXplaceOld ## Der Loc der Vorlage

                          • #31933
                            Klaus Major
                            Administrator

                              Eine Gruppe „Towerx.PNG“ zu nennen, halte ich für etwas verwirrend. 😎

                            • #31935
                              Torsten
                              Teilnehmer
                                on updateScreen 
                                   if sGameRunning is true then     
                                      detectCollisions
                                call "checkLocation" of grp "TowerOff1" of cd "Welle_001"
                                   end if  
                                end updateScreen

                                und hier sprichst Du nur die group „TowerOff1“ an, obwohl Du ja schon eine „TowerOff2“ erzeugt hast. Diese bekommt aber die CheckLocation-Message nicht.

                                Du brauchst eine Möglichkeit, dir zu merken, wieviele Tower auf der Karte sind und diesen jeweils die Nachricht checkLocation zu schicken. Das geht so:

                                repeat with tControlNumber = 1 to the number of controls of the current card
                                  if "TowerOff" is in the name of control tControlNumber then
                                     put the short name of control tControlNumber of the current card & cr after tListOfTowers
                                  end if
                                end repeat
                                
                                repeat for each line tTower in tListOfTowers
                                  call "checkLocation" of grp tTower of the current card
                                end repeat
                                

                                Probiers mal aus!

                              • #31937
                                akrages
                                Teilnehmer

                                  Hallo Torsten.
                                  Ganz schön viel. Ich weiß gar nicht worauf ich zuerst Antworten soll.

                                  Also:
                                  Eine Gruppe „Towerx.PNG“ zu nennen, halte ich für etwas verwirrend.
                                  —–> Stimmt! Habs geändert.

                                  on updateScreen 
                                     if sGameRunning is true then     
                                        detectCollisions
                                  call "checkLocation" of grp "TowerOff1" of cd "Welle_001"
                                     end if  
                                  end updateScreen

                                  —–> hatte ich zwischenzeitlich so geändert:

                                  on updateScreen 
                                     if sGameRunning is true then     
                                        detectCollisions
                                        detectEnemyLocs
                                   dreht sich zum Feind)
                                        call "checkLocation" of grp ("TowerOff" & lCloneTowerOff) of cd "Welle_001"
                                     end if  
                                  end updateScreen

                                  Hat aber auch nichts geändert.

                                  • #31951
                                    Torsten
                                    Teilnehmer

                                      call "checkLocation" of grp ("TowerOff" & lCloneTowerOff) of cd "Welle_001"

                                      Die Variable lCloneTowerOff hat ja in dem Fall immer nur einen Wert, wahrscheinlich 1, aber du musst dafür sorgen, dass er die Nummern der Türme durchrattert und somit an jeden Turm die Botschaft schickt.

                                  • #31938
                                    akrages
                                    Teilnehmer

                                      Habs ausprobiert.
                                      Leider bekomme ich folgende Fehlermeldung in der call Anweisung
                                      call "checkLocation" of grp tTower of the current card

                                      card „Welle_001“: execution error at line 93 (Chunk: can´t find background), char 1

                                      Die tListOfTowers enthält folgendes:
                                      TowerOffVorlage
                                      TowerOff
                                      TowerOff.png
                                      TowerOff1
                                      TowerOff
                                      TowerOff2
                                      TowerOff

                                      Und was ist die grp tTower ?

                                    • #31949
                                      Torsten
                                      Teilnehmer

                                        Ah, ok, da muss der Code natürlich angepasst werden, ich wusste nicht, wieviele Objekte Du mit fast gleichen Namen auf der Karte hast 😉

                                        repeat with tControlNumber = 1 to the number of controls of the current card
                                          if the name of control tControlNumber begins with "group" and the short name of control tControlNumber begins with "TowerOff" then
                                             put the short name of control tControlNumber of the current card & cr after tListOfTowers
                                          end if
                                        end repeat
                                        
                                        repeat for each line tTower in tListOfTowers
                                          call "checkLocation" of grp tTower of the current card
                                        end repeat

                                        Die grp tTower ist die Gruppe, deren Name gerade in der Liste tListOfTowers abgearbeitet wird. Repeat for each line tTower bedeutet, dass der Inhalt der jeweiligen Zeile in tListOfTowers als Inhalt der Variable tTower eingesetzt wird.
                                        In der Zeile call… wird dann die Message checkLocation eben an die group mit dem Namen in tTower gesendet, so wie du es vorher hardkodiert als TowerOff1 gemacht hast.

                                      • #31963
                                        akrages
                                        Teilnehmer

                                          Aha. ok. verstehe.
                                          Dein neuer Code bringt keine Fehlermeldung mehr.
                                          Aber jetzt reagiert nur der 2te Turm (Wenn ich 2 Türme auf die Karte ziehe).
                                          Der 1ste Turm macht gar nichts.

                                        • #31966
                                          akrages
                                          Teilnehmer

                                            Und der Turm der reagiert reagiert zu früh
                                            d.h. er hält sich nicht mehr an die Distanceregel.

                                          • #31967
                                            akrages
                                            Teilnehmer

                                              in tTower steht auch nur der TowerOff2

                                              müssten da nicht beide, also TowerOff1 und TowerOff2 stehen?

                                            • #31980
                                              Torsten
                                              Teilnehmer

                                                Wenn Du magst, schick mir einfach Deinen Stack: torsten.holmer@web.de
                                                Das geht manchmal schneller, als immer wieder Code-Schnipsel zu posten 🙂

                                                Liebe Grüße
                                                Torsten

                                              • #31982
                                                akrages
                                                Teilnehmer

                                                  Mach ich gerne.
                                                  Aber nicht wundern.
                                                  Alles nur zum testen. ha ha…

                                                • #32144
                                                  akrages
                                                  Teilnehmer

                                                    Hi Torsten.

                                                    Vielen Dank für das Lob.
                                                    Nein ich habe kein anderes Spiel abgewandelt. Das meiste ist „learning by doing“.
                                                    Außerdem besitze ich das Buch „EIGENE APPS PROGRAMMIEREN“ von Hauke Fehr.
                                                    Und das eine oder andere findet sich im „World Wide Web“.
                                                    Leider aber, was Spiele betrifft sehr wenig. Deshalb bin ich ganz froh, auf dieses Forum gestoßen zu sein.

                                                    Nun aber zurück zu meinem aktuellen Problem.
                                                    Du empfiehlst die Verwendung einer globalen Feindesliste.

                                                    Hiermit bekomme ich zumindest schon mal eine Auflistung der generierten Feinde.

                                                    ## Die generierten Feinde in die Variable gTankList einlesen

                                                       repeat with t = 1 to 5
                                                          put the short name of grp ("TankA" & t) & return after gTanklist
                                                       end repeat

                                                    ##answer gTankList

                                                    TankA1
                                                    TankA2
                                                    ..
                                                    ..
                                                    TankA5
                                                    Aber wie geht es dann weiter?

                                                    `if distance (the loc of line 1 of gTankList, the loc of me) > gRadar then
                                                    exit checkLocation
                                                    end if`
                                                    funktioniert leider nicht. gibt folgende Fehlermeldung:

                                                    group „TowerOff1“: execution error at line 24 (Chunk: error in object expression) near „TankA1“, char 17

                                                    Scheint als könne die Anweisung den loc von TankA1 nicht finden. Oder?

                                                  • #32145
                                                    Klaus Major
                                                    Administrator

                                                      Hi Akrages,

                                                      kleiner Tip, spar Dir Tipparbeit. 🙂

                                                      repeat with t = 1 to 5
                                                            ## put the short name of grp ("TankA" & t) & return after gTanklist
                                                            put ("TankA" & t) & return after gTanklist
                                                      
                                                            ## ("TankA" & t) IST the short name of grp ("TankA" & t) :-D
                                                      end repeat

                                                      Zu Deiner Frage:

                                                      if distance (the loc of line 1 of gTankList, the loc of me) > gRadar then
                                                        exit checkLocation
                                                      end if

                                                      Line 1 of gTankList ist erst mal nur der String -> TankA1
                                                      Es fehlt GROUP!
                                                      Daher:

                                                      put line 1 of gTankList into tGruppe
                                                      if distance (the loc of GROUP tGruppe, the loc of me) > gRadar then
                                                        exit checkLocation
                                                      end if

                                                      Gruß

                                                      Klaus

                                                    • #32151
                                                      akrages
                                                      Teilnehmer

                                                        Dein Code sollte jetzt eigentlich funktionieren.
                                                        Tut er aber nicht. Es kommt folgende Fehlermeldung:
                                                        group „TowerOff1“: execution error at line 25 (Chunk: source is not a container), char 1

                                                      • #32157
                                                        akrages
                                                        Teilnehmer

                                                          Hab den Fehler 🙂
                                                          vorher
                                                          if distance (the loc of GROUP tGruppe, the loc of me) > gRadar then

                                                          nachher:
                                                          if distance ((the loc of GROUP tGruppe), the loc of me) > gRadar then

                                                          Die Klammern warn`s.

                                                        • #32158
                                                          akrages
                                                          Teilnehmer

                                                            Also ich bin jetzt soweit, dass das Radar vom „TowerOff1“ den ersten der fünf Feinde erkennt und das Geschütz ausfährt. Danach wird der erste Feind -sobald er in Schussreichweite kommt- aufs Korn genommen und beschossen. Nach fünf Treffern wird das visible dieses ersten Feindes auf false gesetzt.
                                                            Soweit so gut.
                                                            Nun sollen der 2te, respektive der 3te, 4te, und letztendlich der letzte Feind auf dieselbe Weise bekämpft werden.
                                                            Reicht es, wenn ich -nach dem der erste Feind bekämpft wurde- und sein Visible auf false gesetzt wurde, diesen aus der Feindliste gTankList lösche?
                                                            Oder gibt es eine bessere Lösung?

                                                          • #32167
                                                            akrages
                                                            Teilnehmer

                                                              Ich bin jetzt soweit, dass alle Feinde der Reihe nach bekämpft werden.
                                                              Spät genug, aber zum Glück hab ich ja Urlaub. 🙂
                                                              Danke Klaus und Torsten für die Hilfe.
                                                              Als nächstes steht die Lösung für das Problem mit mehreren Türmen an.
                                                              Aber für heute ist Schluss.
                                                              Gute Nacht.

                                                            • #32312
                                                              akrages
                                                              Teilnehmer

                                                                Hallo Torsten.

                                                                Ich habe mal dein Script „on checkLocationEnemys“ ausprobiert.

                                                                — die Ermittlung der Tanks ist eigentlich nicht notwendig, wenn die Variable vorher gesetzt wurde.

                                                                Stimmt! Und weil diese Variable ja schon existiert habe ich den Bereich auskommentiert.

                                                                Hier das Script so wie ich es jetzt verwende:

                                                                on checkLocationEnemys ##Feind dreht sich in Laufrichtung
                                                                   
                                                                   -- Anzahl der Knoten und Anzahl der Tanks ermitteln
                                                                   
                                                                   
                                                                   ##put empty into gTankList
                                                                   
                                                                   -- die Ermittlung der Tanks ist eigentlich nicht notwendig, wenn die Variable vorher gesetzt wurde
                                                                   
                                                                   -- diesen Handler habe ich vor der Idee geschrieben
                                                                   
                                                                   
                                                                   repeat with tControlNumber = 1 to the number of controls
                                                                      
                                                                      
                                                                      put word 1 of the name of control tControlNumber into tControlType
                                                                      
                                                                      put the short name of control tControlNumber into tControlName
                                                                      
                                                                      
                                                                      ##if tControlType is "group" and tControlName begins with "TankA" then
                                                                      
                                                                      ##if tControlName <> "TankA" then -- Vorlage nicht übernehmen
                                                                      
                                                                      ##put tControlName & cr after gTankList
                                                                      
                                                                      ##end if
                                                                      
                                                                      ##end if
                                                                      
                                                                      
                                                                      if tControlType is "field" and tControlName begins with "Knoten" then
                                                                         
                                                                         if tControlName <> "KnotenX" then -- Vorlage nicht übernehmen
                                                                            
                                                                            put tControlName & cr after tKnotenList
                                                                            
                                                                         end if
                                                                         
                                                                      end if
                                                                      
                                                                      
                                                                   end repeat
                                                                   
                                                                   
                                                                   -- Iteration: für jeden Knoten für jeden Tank
                                                                   
                                                                   repeat for each line tKnoten in tKnotenList
                                                                      
                                                                      repeat for each line tTank in gTankList
                                                                         
                                                                         
                                                                         if the loc of grp tTank is within the rect of field tKnoten then set the angle of img "TankA" of grp tTank to the text of field tKnoten
                                                                         
                                                                      end repeat
                                                                      
                                                                   end repeat
                                                                   
                                                                   
                                                                   ## Runde beenden, wenn der letzte Tank im Ziel ist
                                                                   
                                                                   put field "MaxTanks" into tMaxTanks
                                                                   
                                                                   if there is a grp ("TankA" & tMaxTanks) then
                                                                      
                                                                      if intersect(grp ("TankA" & tMaxTanks), graphic "Ziel", "opaque Pixels") then send mouseUp to btn "Start"
                                                                      
                                                                   end if
                                                                   
                                                                   if there is a grp "Assault5" then
                                                                      
                                                                      if intersect(grp "Assault5", graphic "Ziel2", "opaque Pixels") then send mouseUp to btn "Start"
                                                                      
                                                                   end if
                                                                   
                                                                end checkLocationEnemys

                                                                Folgendes passiert:
                                                                Beim ersten Start wird der letzte Tank anvissiert und erfolgreich bekämpft. Im Anschluss richtet sich der Turm auf den ersten Feind aus, schießt aber nicht mehr.
                                                                Und wenn der letzte der verbliebenen 4 Feinde das Ziel erreicht hat kommt es zu folgender Fehlermeldung: card „Welle_001“: execution error at line 255 (Chunk: can’t find background), char 13

                                                                In dieser Zeile:
                                                                if the loc of grp tTank is within the rect of field tKnoten then set the angle of img "TankA" of grp tTank to the text of field tKnoten

                                                                Und jetzt das merkwürdige an der ganzen Sache.

                                                                Wenn ich das Spiel erneut starte, dann werden alle Feinde in der richtigen Reihenfolge bekämpft.
                                                                Aber anschließend kommt es zur exakt selben Fehlermeldung.

                                                                Und dann geht das ganze von vorne los.

                                                                Ich kann nicht herausfinden, was da los ist.
                                                                Hast Du ne Idee?

                                                              • #32526
                                                                Torsten
                                                                Teilnehmer

                                                                  Hi,

                                                                  wenn “ can’t find background)“ kommt, bedeutet das immer, das eine Gruppe nicht existiert, die angesprochen werden soll. Früher zu Hypercard und Metacard-Zeiten gab es noch keine Gruppen, sondern das waren die Backgrounds der Karten (vielleicht könbte das Mutterschiff hier mal die Begriffe erneuern 🙂

                                                                  In so einem Fall musst Du unbedingt im Script-Editor nachschauen, was in den einzelnen Variablen tTank und tKnoten drin steht und im Projekt-Browser überprüfen, ob die Objekte existieren.

                                                                  In dem konkreten Fall scheint also die group tTank nicht zu existieren, es fragt sich also, was in tTank für ein Wert steht und warum dieses Objekt nicht da ist.

                                                                  Beste Grüße
                                                                  Torsten

                                                                • #32528
                                                                  Klaus Major
                                                                  Administrator

                                                                    Früher zu Hypercard und Metacard-Zeiten gab es noch keine Gruppen, sondern das waren die Backgrounds der Karten (vielleicht könnte das Mutterschiff hier mal die Begriffe erneuern

                                                                    Hypercard und Metacard sind über 20 Jahre tot!

                                                                    Livecode unterscheidet sehr wohl zwischen „group“ und „background“.
                                                                    Möglicherweise anders als HC, aber nicht anders als MC, daher wird
                                                                    es nicht passieren, daß diese Begriffe erneuert werden!
                                                                    Also gewöhnt euch dran. 😎

                                                                    GROUPS werden relativ zur Karte, BACKGROUNDS relativ zum Stack gezählt.

                                                                    ...
                                                                    put the num of grps
                                                                    ## Ergibt die Anzahl der Gruppen auf der aktuellen KARTE
                                                                    ...
                                                                    put the num of backgrounds
                                                                    ## Ergibt die Anzahl der Gruppen im aktuellen STACK
                                                                    ...
                                                                  • #32530
                                                                    Torsten
                                                                    Teilnehmer

                                                                      Hi Klaus,

                                                                      mein Kommentar ar bezogen auf die Fehlermeldung „(Chunk: can’t find background)“ und die erscheint immer, wenn man etwas mit einer Group machen will, die nicht existiert. Meine Anregung bezog sich darauf, dass diese Fehlermeldung korrigiert werden sollte, nämlich in „can’t find group“.

                                                                      Einverstanden?

                                                                      Liebe Grüße
                                                                      Torsten

                                                                    • #32532
                                                                      Klaus Major
                                                                      Administrator

                                                                        Nein. 😀

                                                                        BACKGROUND ist der Sammelbegriff für Gruppen im Stack.
                                                                        Daher ist die Fehlermeldung korrekt, wenn man das Prinzip
                                                                        (oben erklärt) verstanden hat.

                                                                        Aber ich gebe zu, das ist hier nicht so einfach…

                                                                      • #32536
                                                                        Torsten
                                                                        Teilnehmer

                                                                          Aber es gibt keine Backgrounds als eigene Objekte, sondern nur Groups, deren backgroundBehavior als true gesetzt ist, oder?

                                                                          Das meine ich, die Terminologie aus HC ist aus Kompatibilität übernommen worden, aber das Konzept hat sich geändert. Du kannst ja auch mehrere „Hintergründe“ (Groups mit Backgroundbehavior) auf einer Karte haben, was aber missverständlich ist. Ich finden den Begriff Background in der jetzigen Form eher verwirrend.

                                                                        • #32538
                                                                          Klaus Major
                                                                          Administrator

                                                                            Touché! 😀

                                                                          • #32540
                                                                            Torsten
                                                                            Teilnehmer

                                                                              Gab es im englischen Forum zu diesem Thema eigentlich schon Diskussionen?
                                                                              Im Hinblick auf Benutzerfreundlichkeit finde ich, ist das eine der Schwachstellen.

                                                                            • #32542
                                                                              Klaus Major
                                                                              Administrator

                                                                                Gab es im englischen Forum zu diesem Thema eigentlich schon Diskussionen?

                                                                                Nein, gibt es nicht.
                                                                                Denke auch nicht, daß dort so etwas auftauchen wird.

                                                                              • #32546
                                                                                akrages
                                                                                Teilnehmer

                                                                                  Hi.
                                                                                  Hab jetzt eine Lösung gefunden, damit der Turm immer das nächstglegene Ziel anvisiert.

                                                                                  Mit diesem Code in der Card „Welle_001“

                                                                                  on detectEnemyLocs
                                                                                     
                                                                                     put line 1 of gTankList into gTank1
                                                                                     put line 2 of gTankList into gTank2
                                                                                     put line 3 of gTankList into gTank3
                                                                                     put line 4 of gTankList into gTank4
                                                                                     put line 5 of gTankList into gTank5
                                                                                     
                                                                                     if gTank1 <> empty then \ ## \ ist ein Zeilenumbruch
                                                                                           put distance ((the loc of GROUP gTank1), the loc of grp "TowerOff1") & tab & gTank1 & cr into gDistanceList
                                                                                     if gTank2 <> empty then \
                                                                                           put distance ((the loc of GROUP gTank2), the loc of grp "TowerOff1") & tab & gTank2 & cr after gDistanceList
                                                                                     if gTank3 <> empty then \
                                                                                           put distance ((the loc of GROUP gTank3), the loc of grp "TowerOff1") & tab & gTank3 & cr after  gDistanceList
                                                                                     if gTank4 <> empty then \
                                                                                           put distance ((the loc of GROUP gTank4), the loc of grp "TowerOff1") & tab & gTank4 & cr after  gDistanceList
                                                                                     if gTank5 <> empty then \
                                                                                           put distance ((the loc of GROUP gTank5), the loc of grp "TowerOff1") & tab & gTank5 & cr after  gDistanceList
                                                                                     
                                                                                     sort lines of gDistanceList numeric ascending ## Die Liste numerisch aufsteigend sortieren.   
                                                                                     put gDistanceList into fld "DistanceList" ##Nur zur Kontrolle!
                                                                                     
                                                                                  end detectEnemyLocs

                                                                                  und dieser kleinen Änderung in der Group „TowerPlattform“

                                                                                  on checkLocation

                                                                                     set the itemdel to TAB
                                                                                     put word 2 of gDistanceList into tGruppe

                                                                                  funkts endlich.

                                                                                • #32547
                                                                                  Torsten
                                                                                  Teilnehmer

                                                                                    Gut so,
                                                                                    kleiner Wermutstropfen bei dieser Form ist, dass Du 1. nur einen Turm berücksichtigst und 2. alles nur für 5 Tanks geht. Besser wäre es, wenn Du die Distanzberechnung von jedem Turm selbst vorgenommen wird und er dabei alle sichtbaren (also noch existierenden) Tanks berücksichtigt (gTankList) und entsprechend auf SEINEN nächsten Tank feuert.

                                                                                    In der jetzigen Form schiesst wieder nur Turm1, oder?

                                                                                    Happy Coding
                                                                                    Torsten

                                                                                  • #32549
                                                                                    akrages
                                                                                    Teilnehmer

                                                                                      Stimmt leider. 🙁

                                                                                    • #32571
                                                                                      akrages
                                                                                      Teilnehmer

                                                                                        Es ist zum Verzweifeln!
                                                                                        Hab das jetzt in der Turmvorlage:

                                                                                        Global lCloneTowerOff, lCloneTowerOn, gRadar, gFeuerFrei, gTanklist, tGruppe, gDistance, gDistanceList
                                                                                        global i, x, z, tMaxTanks, gTank

                                                                                        on detectEnemyLocs
                                                                                           
                                                                                           if gTanklist = empty then
                                                                                              exit detectEnemyLocs
                                                                                           end if   
                                                                                         
                                                                                           put line 1 of gTankList into gTank1
                                                                                           put line 2 of gTankList into gTank2
                                                                                           put line 3 of gTankList into gTank3
                                                                                           put line 4 of gTankList into gTank4
                                                                                           put line 5 of gTankList into gTank5
                                                                                           
                                                                                           put distance ((the loc of GROUP gTank1), the loc of me) & tab & gTank1 & cr into gDistanceList
                                                                                           put distance ((the loc of GROUP gTank2), the loc of me) & tab & gTank2 & cr after gDistanceList
                                                                                           put distance ((the loc of GROUP gTank3), the loc of me) & tab & gTank3 & cr after  gDistanceList
                                                                                           put distance ((the loc of GROUP gTank4), the loc of me) & tab & gTank4 & cr after  gDistanceList
                                                                                           put distance ((the loc of GROUP gTank5), the loc of me) & tab & gTank5 & cr after  gDistanceList
                                                                                           
                                                                                           sort lines of gDistanceList numeric ascending ## Die Liste numerisch aufsteigend sortieren.   
                                                                                           put gDistanceList into fld "DistanceList" ##Nur zur Kontrolle!
                                                                                           
                                                                                        end detectEnemyLocs
                                                                                        
                                                                                        --------------------------------------------------------------------------------------------------------------------------
                                                                                        
                                                                                        --------------------------------------------------------------------------------------------------------------------------
                                                                                        
                                                                                        on checkLocation 
                                                                                           
                                                                                           set the itemdel to TAB
                                                                                           put word 2 of gDistanceList into tGruppe
                                                                                        
                                                                                           --> Wer modifiziert die globale Variable i? damit werden 5 Feinde --TankA 1-5 (i)-- erstellt.
                                                                                           ##answer tGruppe ##ist OK
                                                                                           if there is no grp tGruppe then
                                                                                              exit checkLocation
                                                                                           end if
                                                                                           --> wenn kein TankA & i existiert, braucht der Rest nicht ausgeführt zu werden
                                                                                           
                                                                                           if the visible of grp tGruppe is false then
                                                                                              exit checkLocation
                                                                                           end if
                                                                                           --> wenn der Tank unsichtbar ist, braucht der Rest nicht ausgeführt zu werden
                                                                                           ---------------------------------------------------------------------------------------------------------
                                                                                           
                                                                                           
                                                                                           ---------------------------------------------------------------------------------------------------------
                                                                                           ## Wenn der Feind sich im Erfassungsbereich des Radars des Turms befindet,
                                                                                           ## dann wird der Turm "ausgefahren" (sichtbar).
                                                                                           
                                                                                           if distance ((the loc of GROUP tGruppe), the loc of me) > gRadar then ##Hier neuen Befehl einfügen!
                                                                                              exit checkLocation
                                                                                           end if
                                                                                           --> ist der Tank nicht im Range, braucht der Rest nicht ausgeführt zu werden
                                                                                           
                                                                                           set the visible of img ("TowerOn" & lCloneTowerOn) to true
                                                                                           
                                                                                           TankATarget  --> ??? Was soll dieser Befehl bedeuten ??? Bedeutet, der Turm folgt dem anvisierten Ziel.
                                                                                           ---------------------------------------------------------------------------------------------------------
                                                                                           
                                                                                           
                                                                                           ---------------------------------------------------------------------------------------------------------
                                                                                           ## Wenn der Feind sich im Feuerbereich der Türme befindet, dann Feuer frei auf den
                                                                                           ## nächstgelegenen sichtbaren Feind.
                                                                                           if distance ((the loc of GROUP tGruppe), the loc of me) > gFeuerFrei then ##Hier neuen Befehl einfügen!
                                                                                              exit checkLocation
                                                                                           end if
                                                                                           
                                                                                           moveBeam1u2
                                                                                           --> seltsamer Befehl, was passiert da? ##Es wird der anvisierte Feind beschossen!
                                                                                           
                                                                                        end checkLocation

                                                                                        Und trotzdem funktioniert es nicht mit 2 oder mehr Türmen.

                                                                                        Es schießt immer nur der letzte der geclonten Türme.

                                                                                        Was mache ich falsch?

                                                                                      • #32578
                                                                                        Torsten
                                                                                        Teilnehmer

                                                                                          Soweit ich in deinem Stack sehen kann, sind die Handler TankATarget und moveBeam1u2 auch noch nicht umgeschrieben. Ich glaube, am besten ist es, wenn auch diese Funktionen für jeden Turm extra sind ODER parametrisiert werden, so dass der Zielende Turm und das Ziel explizit als Parameter angegeben werden:

                                                                                          TankATarget me, tTarget oder so…

                                                                                          Happy Coding
                                                                                          Torsten

                                                                                      Ansicht von 40 Antwort-Themen
                                                                                      • Du musst angemeldet sein, um auf dieses Thema antworten zu können.