Ergebnis 1 bis 5 von 5

Thema: [RMXP] Kollisionsabfrage => Denkfehler

  1. #1

    [RMXP] Kollisionsabfrage => Denkfehler

    Hoi, ich werkele immer noch am dir8-Script, und habe wohl den einen oder anderen Denkfehler.








    Kann dort jemand helfen und mir vielleicht sagen, wo ich was falsch mache?

    Zusatzfrage: Wie kann ich mir die Speicheradresse einer Instanz von einem Objekt besorgen? (vgl. Pointer C++)

    EDIT:

    Bis auf die Zusatzfrage hat sich die Anfrage erledigt (:


    Code:
      def self.get_range_characters(my_key)
        in_range = []
        my_char = @@characters[my_key]
        
        my_x = my_char.x
        my_y = my_char.y
        
        my_length = my_char.src_x
        my_height = my_char.src_y
        
        @@characters.each_pair { |key, figure_char|
          next if key == my_key
          
          diff_x = my_x - figure_char.x
          diff_y = my_y - figure_char.y
          
          if (diff_x.betrag <= my_length) && (diff_y.betrag <= my_height)
            in_range.push key
          end
        }
        
        in_range
      end
    
    # Zusätzlich:
    
    class Integer
      
      def betrag
        return (self >= 0) ? self : (self * (-1))
      end
      
    end
    Mapping.rar

    Geändert von Kagurame (05.11.2012 um 14:59 Uhr)

  2. #2
    wenn du eine kollission zweier gleichgroßer rechtecke abfragen möchtest, brauchst du eigentlich nur 2 abfragen.
    also praktisch:

    Code:
    if (x1begin >= x2begin && y1begin >= y2begin && x1begin <= x2end && y1begin <= y2end)
    damit schaust du, ob sich die obere linke ecke des ersten rechtecks innerhalb des 2. rechtecks befindet. wenn ja, findet logischerweise eine kollission statt.
    wenn das nicht zutrifft

    Code:
    if (x1end >= x2begin && y1end >= y2begin && x1end <= x2end && y1end <= y2end)
    das betrifft die untere rechte ecke.
    sollte diese auch nicht innerhalb des rechtecks sein, findet keine kollission statt.

    alternativ kannst du auch einfach:
    Code:
    if (x1end < x2begin)
    das würde zum beispiel heißen, das der x endpunkt des 1. rechtecks kleiner als der x startpunkt des 2. rechtecks ist, und somit gar keine kollission stattfinden kann.
    entsprechend das ganze noch für die anderen seiten.

    Code:
    if (x1end < x2begin || x1begin > x2end || y1end < y2begin || y1begin > y2end)
    wenn eine der bedingungen zutrifft ist eine kollission ausgeschlossen. da ich leider auch nicht mehr ganz konfirm darin bin, und es ein wenig her ist, das ich das bei mir eingebaut habe, und ich jetzt wenig zeit habe, darüber nachzudenken kann ich gerade leider nur die paar fetzen schreiben. ich hoffe, ich konnte weiter helfen

    mfg

    Geändert von DNKpp (05.11.2012 um 15:29 Uhr)

  3. #3
    Zitat Zitat
    wenn du eine kollission zweier gleichgroßer rechtecke abfragen möchtest, brauchst du eigentlich nur 2 abfragen.
    also praktisch:

    Code:
    if (x1begin >= x2begin && y1begin >= y2begin && x1begin <= x2end && y1begin <= y2end) damit schaust du, ob sich die obere linke ecke des ersten rechtecks innerhalb des 2. rechtecks befindet. wenn ja, findet logischerweise eine kollission statt.
    wenn das nicht zutrifft

    Code:
    if (x1end >= x2begin && y1end >= y2begin && x1end <= x2end && y1end <= y2end) das betrifft die untere rechte ecke.
    sollte diese auch nicht innerhalb des rechtecks sein, findet keine kollission statt.
    Was du sagst stimmt leider so nicht, schaue auf das Bild im Anhang.

    Die korrekte Lösung ist folgende:
    Ein Rechteck liegt teilweise innerhalb eines anderen genau dann wenn die beiden nicht vollständig disjunkt sind.
    Das wäre als Code:
    Code:
    public boolean overlap(Rechteck r1, Rechteck r2)
    return !(r1.startX > r2.endX || r1.startY > r2.endY || r1.endX < r2.startX || r1.endY < r2.startY)
    Denn falls eine der folgenden Bedingungen erfüllt ist:
    r1.startX > r2.endX
    r1.startY > r2.endY
    r1.endX < r2.startX
    r1.endY < r2.startY
    berühren sich die beiden Rechtecke überhaupt nicht, und die Negation der Aussage ist dann die Bedingung falls beide Rechtecke einander überschneiden.

    Geändert von Cornix (05.11.2012 um 16:21 Uhr)

  4. #4
    stimmt, du hast recht. wie gesagt war nur kurz auf der arbeit drüber nachgedacht
    aber bei dem letzten punkt sind wir uns ja einig.

  5. #5
    Zitat Zitat
    Zusatzfrage: Wie kann ich mir die Speicheradresse einer Instanz von einem Objekt besorgen? (vgl. Pointer C++)
    Mit Object#object_id kommst du an die Objekt-ID eines Objekts. Per ObjectSpace._id2ref kannst du eine Objekt-ID wieder in ein Objekt umwandeln. Auf diese Weise kannst du z.B. weak Pointer umsetzen. Aus der Objekt-ID kannst du auch die reale Speicheradresse ausrechnen, in dem du sie um ein Bit shiftest:
    Code:
    objekt = "Foo"
    memory_adress = objekt.object_id << 1

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •