Wie überprüfe ich in Cocos2D Kollisionen mit einer beliebigen vom Benutzer gezeichneten Form?

10

Ich möchte eine Kollision zwischen einem Sprite und einer vom Benutzer generierten Form erkennen.

Zum Beispiel. Es gibt 3 Objekte auf dem Bildschirm. Der Benutzer nimmt seinen Finger und zeichnet eine abnormale Form um 2 der Objekte. Ich muss diese 2 Objekte erkennen.

Benutzerform in lila, Spielobjekte in grün und rot

Wie gehe ich mit Cocos2D effizient damit um?

David McGraw
quelle

Antworten:

10

Für dieses Beispiel gibt es eine sehr einfache Lösung.

Ich gehe davon aus, dass Ihre willkürliche Form nur eine Reihe von Punkten ist.

Zeichnen Sie einen Strahl von jedem Ihrer Objekte in eine beliebige Richtung. Wenn die Häufigkeit, mit der ein Liniensegment in Ihrer Form geschnitten wird, gerade ist (einschließlich Null), befinden Sie sich außerhalb der Form.

Wenn die Häufigkeit, mit der Sie sich schneiden, ungerade ist, befinden Sie sich innerhalb des Objekts.

Die Kollision zwischen Strahl und Liniensegment ist ein ziemlich einfach zu findender / zu implementierender Algorithmus.

Tetrad
quelle
3

Klar, das musste ich für mein Spiel Star Catch herausfinden. Es gibt vielleicht bessere Möglichkeiten, aber so habe ich es gemacht. Ich habe den Algorithmus tatsächlich online gefunden (sorry, ich kann mich nicht an die Quelle erinnern). Ich habe nach einem Punkt innerhalb eines Polygons gesucht.

Ich habe ein NSMutableArray erstellt, um meinen Standpunkt zu vertreten. Ich füge die Punkte in meinen Touchevents hinzu.

- (BOOL) testNodeInLoop:(CCNode *)node {

    CGPoint prev;

    // This is more accurate point for the node
    CGPoint absPoint = [node convertToWorldSpace:CGPointZero];

    float x = absPoint.x;
    float y = absPoint.y;

    BOOL isIn = NO;

    CGPoint cp;

    for(int i = 0, j = [points count] - 1; i < [points count]; j = i++) {
        [[points objectAtIndex:i] getValue:&cp];
        [[points objectAtIndex:j] getValue:&prev];

        if( ((cp.y > y) != (prev.y > y)) && (x < (prev.x -cp.x) * (y - cp.y) / (prev.y - cp.y) + cp.x)) {
            isIn = !isIn;
        }
    }
    return isIn;
}

Lassen Sie mich wissen, ob dies hilfreich ist.

Ton
quelle
2

Das Buch "Echtzeit-Kollisionserkennung" enthält einen Abschnitt zur Linien- / Segmentkollisionserkennung. Beispiel über Google Books: http://ow.ly/2gjQf

AlfredBaudisch
quelle
0

Für pixelweise Kollisionsprüfungen gibt es auf der XNA-Entwicklerseite eine nette Tutorialserie.
http://creators.xna.com/en-US/tutorial/collision2dperpixeltransformed

Eine Optimierung, die Sie verwenden können und die in diesen Tutorials nicht verwendet wurde (seltsamerweise), besteht darin, dass in den meisten Fällen nur die Gliederung überprüft werden muss, wodurch wertvolle Zyklen gespart werden .

Bearbeitet, um hinzuzufügen: Miese Antwort, die Frage falsch verstanden. Die Tutorials sind immer noch recht anständig, wenn Sie sich über die Kälte pro Pixel informieren möchten.

Kaj
quelle