Das setzt fort und schließt den vorherigen Posten der Schnellen mit dem Pixel vollkommenen Kollisionsentdeckung für Cocos2D mit dem Artikel Example Code (1/2).
Prüfung für die pixelMask Kollision mit einem Rechteck
Die Prüfung für einen individuellen Punkt ist einfach, für ein Rechteck wie der begrenzende Kasten eines anderen Knotens prüfend, verlangt mehr Arbeit. Nicht nur, den Code zu schreiben, sondern auch es zu führen. Und es wird auf Knoten beschränkt, die weder rotieren gelassen noch erklettert werden. And it is limited to nodes which are neither rotated nor scaled.
Leider ist Prüfung von Kollisionen mit rotieren gelassenen Rechtecken (orientierte begrenzende Kästen) nicht trivial, sogar ohne pixelMask Kollisionen zu denken. Hier ist ein C ++ OBB und ein C # OBB Durchführung für die OBB Kollisionsentdeckung. Und es ist gerade für die begrenzenden Kästen, jedes Pixel in einer orientierten Pixel-Maske prüfend, würde wahrscheinlich untersagend teuer sein. And that’s just for the bounding boxes, testing each pixel in an oriented pixel mask would likely be prohibitively expensive.
Sie wollen bestimmt eine Methode der rohen Gewalt vermeiden, die über die komplette PixelMask-Reihe wiederholt. Statt dessen schafft diese Durchführung zuerst das sich schneidende Rechteck des pixelMask Knotens und des anderen Knotens, dann nur wiederholt über die Kreuzung, um die Anzahl von Wiederholungen beträchtlich zu vermindern:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
- (BOOL) pixelMaskIntersectsRegularNode: (CCNode *) anderer
) pixelMaskIntersectsRegularNode:(CCNode*)other
{
CGRect intersectRect = [selbst intersectRectInPixels:self otherNode:other];
= [self intersectRectInPixels:self otherNode:other];
//überprüfen Sie, ob einige der Fahnen im pixelMask in der Kreuzung gesetzt wird NSUInteger maxX = intersectRect.origin.x + intersectRect.size.width;
= intersectRect.origin.x + intersectRect.size.width;
NSUInteger maxY = intersectRect.origin.y + intersectRect.size.height;
= intersectRect.origin.y + intersectRect.size.height;
für (NSUInteger y = intersectRect.origin.y; y <maxY; y ++)
NSUInteger y = intersectRect.origin.y; y < maxY; y++)
{
für (NSUInteger x = intersectRect.origin.x; x <maxX; x ++)
NSUInteger x = intersectRect.origin.x; x < maxX; x++)
{
NSUInteger Index = y * pixelMaskWidth + x;
= y * pixelMaskWidth + x;
geben Sie pixelMask [Index] zurück;
[index];
}
}
kehren Sie NEIN zurück;
;
} |
Es sollte bemerkt werden, dass wir nur finden müssen, dass ein pixelMask biss, der gesetzt wird. Das bedeutet, dass diese Methode weiter in einer Vielfalt von Wegen optimiert werden konnte, die sicherstellen, dass ein Pixel mit größerer Wahrscheinlichkeit früher gefunden wird.
Zum Beispiel kann es behauptet werden, dass näher am Zentrum des pixelMask die Wahrscheinlichkeit eines pixelMask setzende Zunahmen biss. Das bedeutet abhängig von der Position des intersectionRect, den die Wiederholung über den pixelMask gezwickt werden konnte, um näher am Zentrum des pixelMask und der Arbeit sein Weg nach außen anzufangen. Aber diese Optimierung hängt schwer von den Images ab, die verwenden werden, und zu einigen strecken sich aus, wie sich die Gegenstände bewegen. But this optimization depends heavily on the images being used and to some extend how the objects move.
Der größte anzunehmende Unfall ist, dass es keinen Bohrersatz im pixelMask für den gegebenen intersectRect gibt. Wissend, dass man denken könnte, über den pixelMask nicht BOOL durch BOOL zu wiederholen, aber einen vollen 32-Bit-NSUInteger (4 BOOL sofort) vom pixelMask nachzuschlagen. Wenn dieser 32-Bit-Wert 0 ist, dann kann keines der 4 Kollisionsbit vielleicht gesetzt werden, die Anzahl von Tests und Wiederholungen von 4 bis 1 vermindernd. Nur wenn der Wert größer ist als 0, würden Sie überprüfen müssen, dass jeder individuelle pixelMask biss. Einen BitArray verwendend, konnten Sie bis zu 32 Bit sofort auf eine ähnliche Mode prüfen. If that 32-Bit value is 0, then none of the 4 collision bits can possibly be set, reducing the number of tests and iterations from 4 to 1. Only if the value is greater than 0 you would have to check each individual pixelMask bit. Using a BitArray you could test up to 32 bits at once in a similar fashion.
Ein schneller Blick auf die intersectRectInPixels Methode offenbart, dass es das sich schneidende Rechteck der springenden Kästen der zwei kollidierenden Knoten schafft. Wichtig, um zu bemerken, ist hier, dass der Ursprung des sich schneidenden Rechtecks zum nodeSpace des ersten Knotens umgewandelt und dann zu Pixeln umgewandelt werden muss, um sicherzustellen, dass es mit HD Images arbeitet.
|
1 2 3 4 5 6 7 8 9 10 |
- (CGRect) intersectRectInPixels: (CCNode *) Knoten otherNode: (CCNode *) anderer
) intersectRectInPixels:(CCNode*)node otherNode:(CCNode*)other
{
CGRect myBBox = [Knoten boundingBox];
= [node boundingBox];
CGRect otherBBox = [anderer boundingBox];
= [other boundingBox];
CGRect intersectRect = CGRectIntersection (myBBox, otherBBox);
= CGRectIntersection(myBBox, otherBBox);
//gestalten Sie den rect in den Raum der Elfe um, und Bekehrter weist zu Pixeln hin intersectRect.origin = [Knoten convertToNodeSpace:intersectRect.origin];
= [node convertToNodeSpace:intersectRect.origin];
geben Sie CC_RECT_POINTS_TO_PIXELS (intersectRect) zurück;
(intersectRect);
} |
Das Imstandesein, zwei Knoten zu dieser Methode zu passieren, erlaubt dem durchschneiden Rechteck, für beide kollidierenden Knoten berechnet zu werden. Das ist als nächstes erforderlich, wenn wir die Kollision von zwei möglichem Schneiden KKPixelMaskSprite bestimmen.
Das Ermitteln der Kollision von zwei KKPixelMaskSprites
Es ist nur ein relativ kleine Schritt, der von pixelMask mit der Rechteck-Kreuzung zur Prüfung von zwei pixelMasks für die Kreuzung geht (Übergreifen kann ein besseres Wort hier sein). Wieder müssen Sie nicht rohe Gewalt verwenden - es ist genügend, die Überschneidung (das Schneiden) Rechteck der zwei Elfen zu überprüfen. Wieder arbeitet dieser Test mit rotieren gelassenen oder schuppigen Rechtecken nicht, aber es ist ein Nachteil, der der Leistung des Tests nützt. Again this test doesn’t work with rotated or scaled rectangles but it’s a drawback that benefits the performance of the test.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
- (BOOL) pixelMaskIntersectsPixelMaskSprite: (KKPixelMaskSprite *) anderer
) pixelMaskIntersectsPixelMaskSprite:(KKPixelMaskSprite*)other
{
CGRect intersectSelf = [selbst intersectRectInPixels:self otherNode:other];
= [self intersectRectInPixels:self otherNode:other];
CGRect intersectOther = [selbst intersectRectInPixels:other otherNode:self];
= [self intersectRectInPixels:other otherNode:self];
NSUInteger originOffsetX = intersectOther.origin.x - intersectSelf.origin.x;
= intersectOther.origin.x - intersectSelf.origin.x;
NSUInteger originOffsetY = intersectOther.origin.y - intersectSelf.origin.y;
= intersectOther.origin.y - intersectSelf.origin.y;
NSUInteger otherPixelMaskWidth = other.pixelMaskWidth;
= other.pixelMaskWidth;
BOOL* otherPixelMask = other.pixelMask;
otherPixelMask = other.pixelMask;
//überprüfen Sie, ob einige der Fahnen im pixelMask im Kreuzungsgebiet gesetzt wird NSUInteger maxX = intersectSelf.origin.x + intersectSelf.size.width;
= intersectSelf.origin.x + intersectSelf.size.width;
NSUInteger maxY = intersectSelf.origin.y + intersectSelf.size.height;
= intersectSelf.origin.y + intersectSelf.size.height;
für (NSUInteger y = intersectSelf.origin.y; y <maxY; y ++)
NSUInteger y = intersectSelf.origin.y; y < maxY; y++)
{
für (NSUInteger x = intersectSelf.origin.x; x <maxX; x ++)
NSUInteger x = intersectSelf.origin.x; x < maxX; x++)
{
NSUInteger Index = y * pixelMaskWidth + x;
= y * pixelMaskWidth + x;
wenn (pixelMask [Index])
pixelMask[index])
{
//überprüfen Sie, ob es einen Pixel-Satz an derselben Position gibt //im pixelMask der anderen Elfe NSUInteger otherX = x + originOffsetX;
= x + originOffsetX;
NSUInteger otherY = y + originOffsetY;
= y + originOffsetY;
NSUInteger otherIndex = otherY * otherPixelMaskWidth + otherX;
= otherY * otherPixelMaskWidth + otherX;
wenn (otherPixelMask [otherIndex])
otherPixelMask[otherIndex])
{
geben Sie JA zurück;
;
}
}
}
}
kehren Sie NEIN zurück;
;
} |
Im Vergleich zum vorherigen Rechteck-Test dem sich schneidenden Rechteck des anderen Kollidierens wurde KKPixelMaskSprite hinzugefügt und eine Verweisung auf otherPixelMask zusammen mit anderen versteckten Werten in Linien 4-9. Der Hauptinhalt der Funktion führt noch denselben Test herauf bis die Linie 22 durch. Anstatt das erste Bit zurückzugeben, das im pixelMask gesetzt wird, müssen wir sicherstellen, dass dieses Bit auch im otherPixelMask gesetzt wird. Instead of returning the first bit that is set in the pixelMask, we have to make sure that this bit is also set in the otherPixelMask.
Da der Index in den otherPixelMask leicht berechnet werden kann, es mit dem Ursprung des intersectOther Rechtecks ausgleichend, müssen wir nur einen neuen Index für denselben x, y Koordinaten, aber hinsichtlich des Koordinatensystems des anderen KKPIXELMASKSPRITE erzeugen. Linien 26 und 27 führen diese Operation durch, den vorberechneten originOffset von Linien 6 und 7 verwendend. Hauptsächlich gleicht das den x, y Koordinaten zu derselben Position innerhalb des Kreuzungsrechtecks der anderen Elfe aus. Was bleibt, wandelt die Koordinaten zum Index um und prüft, wenn das OtherPixelMask-Bit an diesem Index auch gesetzt wird. Wenn so, wir haben eine Kollision. In essence this offsets the x,y coordinates to the same location within the other sprite’s intersection rectangle. What remains is converting the coordinates to the index and testing if the otherPixelMask bit at that index is also set. If so, we have a collision.
Das Zusammenstellen der Kreuzungstests
Es gibt eine Methode, die ich bis jetzt ausließ. Es ist die öffentliche Schnittstelle-Methode, die Benutzer von KKPixelMaskSprite nennen werden. Es leistet mehrere früh prüfen und picken auch den richtigen Test auf, um basiert auf die Klasse des anderen Knotens zu leisten. It performs several early out tests and also picks the right test to perform based on the class of the other node.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
- (BOOL) pixelMaskIntersectsNode: (CCNode *) anderer
) pixelMaskIntersectsNode:(CCNode*)other
{
wenn (rotation_! = 0.0f || other.rotation! = 0.0f ||
rotation_ != 0.0f || other.rotation != 0.0f ||
self.scale! = 1.0f || other.scale! = 1.0f)
!= 1.0f || other.scale != 1.0f)
{
CCLOG ("entweder oder beide Knoten werden rotieren gelassen und/oder erklettert, NEIN zurückkehrend!");
");
kehren Sie NEIN zurück;
;
}
wenn ([selbst intersectsNode:other])
[self intersectsNode:other])
{
wenn ([anderer isKindOfClass:PixelMaskSpriteClass])
[other isKindOfClass:PixelMaskSpriteClass])
{
KKPixelMaskSprite* maskSprite = (KKPixelMaskSprite *) anderer;
= (KKPixelMaskSprite*)other;
kehren Sie [selbst pixelMaskIntersectsPixelMaskSprite:maskSprite] zurück;
self pixelMaskIntersectsPixelMaskSprite:maskSprite];
}
sonst
{
kehren Sie [selbst pixelMaskIntersectsRegularNode:other] zurück;
self pixelMaskIntersectsRegularNode:other];
}
}
kehren Sie NEIN zurück;
;
} |
Ich erwähnte vorher, der die Kreuzungstests mit rotieren gelassenen oder schuppigen Knoten nicht arbeiten. In diesem Fall kehrt die Methode sofort NICHT zurück und loggt das, um jemanden zu vermeiden, vereitelt werdend, weil die Tests "nicht immer arbeiten". Auch mich viele solche Fragen zu verschonen.
Also to spare me many such questions. ![]()
Natürlich prüft die Kreuzung nur haben Sinn, wenn sich die begrenzenden Kästen schneiden. Die intersectsNode Methode ist eine Bequemlichkeitsfunktion, dass Sie in Kobold2D, und in der CCNodeExtensions zum Projekt hinzugefügten Klasse finden werden.
Der pixelMask gegen den PixelMask-Test wird nur durchgeführt, wenn der andere Knoten auch ein KKPixelMaskSprite in allen anderen Fällen ist, wird das Rechteck, das sich pixelMask Test schneidet, stattdessen durchgeführt. Die PixelMaskSpriteClass Variable ist eine statische Variable, die in der init Methode als [selbst Klasse] einfach initialisiert ist, weil, die Klassennachricht sendend, jedes Mal ein bisschen im Vergleich zu den 4 Bytes des zusätzlichen Gedächtnisses für die PixelMaskSpriteClass Variable verschwenderisch ist.
Prüfung der Kreuzung von zwei Elfen, entweder KKPixelMaskSprite oder nicht, ist ebenso einfach wie das Schreiben:
|
1 |
wenn ([spriteA pixelMaskIntersectsNode:spriteB])...[spriteA pixelMaskIntersectsNode:spriteB]) ... |
Pixel-Maske-Leistung:
BitArray dagegen. BOOL Reihe BOOL arrayJetzt zu einer interessanten Frage: Wenn der BitArray im Stande ist, Speichergebrauch zu 1/8. (12.5 %) zu reduzieren, ist es auch schneller? Lassen Sie mich das offenbaren, weil eine erhaltene Grafik, den pixelMask gegen pixelMask durchführend, mehrere hunderttausend Male wiederholt überprüft, und die Gesamtlaufzeit messend: Let me reveal this as a graphic obtained by performing the pixelMask vs pixelMask check several hundred thousand times repeatedly, and measuring the total running time:
Mit anderen Worten: Es ist ein Umtausch zwischen Speichergebrauch und Zeitverhalten. Pixel-Maske-Kreuzungstests sind auf einem iPod 4, und um 18 % langsamer auf einem I-Phone 3G um 27 % langsamer, den BitArray verwendend. Und nur für den Fall fragen Sie sich: Wenn Sie einen UInt16 oder sogar UInt32 Reihe statt der BOOL-Reihe verwenden sollten, werden Sie eine sehr geringe Abnahme in der Leistung (weniger als 5 %) sehen, aber beziehungsweise viermal den Speichergebrauch verdoppeln. Pixel mask intersection tests are 27% slower on an iPod 4, and 18% slower on an iPhone 3G when using the BitArray. And just in case you’re wondering: if you were to use a UInt16 or even UInt32 array instead of the BOOL array you’ll see a very minor decrease in performance (less than 5%) but double respectively four times the memory usage.
Zimmer für die Verbesserung
Indem ich die KKPixelMaskSprite Klasse schrieb, entdeckte ich viel Zimmer für die Verbesserung. Ich will nicht Sie die Liste verschonen, weil sie auch einige Mängel der Klasse offenbart, dass ich denke, dass Sie dessen bewusst sein sollten. Wenn Sie wirklich eine dieser Verbesserungen durchführen, teilen Sie sie bitte, und wenn möglich sie laut einer permissiven Lizenz wie MIT teilen. If you do implement one of these improvements please share them, and if possible share them under a permissive license such as MIT.
Vielleicht nützliche Verbesserungen, in der Größenordnung von der Nützlichkeit
- geheimes Lager pixelMasks, zum Beispiel in einem CCPixelMaskCache Singleton, oder fügt sie zu CCTexture2D hinzu
- erlauben Sie Pixel-Maske-Entwicklung von spriteframes oder Spriteframe-Namen
- erlauben Sie Kollisionstests, wenn Elfe zu genau 90, 180 oder 270 Grade rotieren gelassen wird
- erlauben Sie Gebrauch der Nichtmacht von zwei Images für pixelMasks auf 1./2. Generationsgeräten
- erlauben Sie Kollisionen zwischen SD und HD Bildelfen
Potenzielle Optimierungen in der Größenordnung von der erwarteten Wirksamkeit
- reduzieren Sie pixelMask Größe, sich 2×2, 3×3, 4×4, usw. Pixel in ein einzelnes Bit verbindend
- ODER: Verwenden Sie nur SD Images für pixelMask, Kollisionen auf Netzhaut-Geräten zwingend, Grenzen anzuspitzen
- optimieren Sie Wiederholungen, UInt32 (4x BOOL) oder vielfache Bit sofort für den Wert> 0 prüfend
- optimieren Sie Wiederholungen anfangend, von der Ecke zu wiederholen, die am nächsten ist, um im Mittelpunkt zu stehen
Insbesondere sollte sich die Optimierung, um die pixelMask Größe zu reduzieren, vielfache Pixel verbindend, erweisen, sehr effizient zu sein, und ist relativ leicht durchzuführen. Die meisten mit dem Pixel vollkommenen Kollisionen brauchen nicht, ein Ende wirklich mit dem Pixel vollkommen zu sein, das genug Annäherung mehr ist als genug für die meisten Anwendungen. Insbesondere auf Netzhaut-Geräten wird kein Spieler im Stande sein auszumachen, ob nicht so Pixel vollkommene Kollisionen nur innerhalb zwei, drei, oder vielleicht sogar mehr Pixel genau sind. Die einfachste Annäherung würde gerade nur die SD Images für Pixel-Masken sogar auf Netzhaut-Geräten denken sollen. Der zusätzliche Vorteil, der ist, dass ein kleinerer pixelMask weniger Wiederholungen und so schnelleren Kollisionstests gleichkommt. In particular on Retina devices no player will be able to make out if the not-so-pixel-perfect collisions are accurate only within two, three, or possibly even more pixels. The simplest approach would be to just consider only the SD images for pixel masks, even on Retina devices. The added advantage being that a smaller pixelMask equals fewer iterations and thus quicker collision tests.
Laden Sie das Beispiel-Projekt mit KKPixelMaskSprite herunter
Laden Sie das KKPixelMaskSprite Demoprojekt herunter!
Dieses Projekt ist auch auf meinem github Behältnis verfügbar, wo ich den ganzen iDevBlogADay Quellcode veranstalte.
Fröhlicher piXmas!
Das ist mein letzter IDevBlogADay-Posten vor dem Weihnachten. Es ist groß, zusätzlich knusperig, bedeckt in Schokolade, Gerüchen wie Zimt, Geschmäcken wie Äpfel und Walnüsse und Soße und Plätzchen und Truthahn Extra-, und wird in den USA verboten, weil es ungenießbare Pixel enthält und eine erstickende Gefahr für jeden ist, der vorhat, es darin zu lesen, geht man.
In diesem Sinn, Fröhliches Weihnachten jeder! ![]()
| Folgen Sie @gaminghorror | Folgen Sie @kobold2d |
|










[...] LearnCocosTV - Episode 1: Wie ich maed Ihr Kobold Schnell mit dem Pixel vollkommene Kollisionsentdeckung für Cocos2D mit dem Beispiel-Code (2/2) [...]
Haben Sie Leistung hinsichtlich Physik-Bibliotheken wie Box2d oder Backenhörnchen geprüft? Ich würde mich interessieren zu wissen - ich stelle mir vor, dass viele Leute sie nur für ihre Kollisionsentdeckungsfunktionalität verwenden.
Das kann nicht vernünftig verglichen werden, weil Physik-Motoren mit dem Pixel vollkommene Kollisionstests nicht tun, verlassen sie sich auf Vielecke (Gestalten), um die Kollisionsprüfung zu tun. Und die Zahl von Scheitelpunkten in jeder Gestalt wird häufig zum Beispiel streng beschränkt Box2D erlaubt höchstens 8 Scheitelpunkte pro Gestalt.
Wirklich denke ich, dass sie vernünftig verglichen werden können.
Spielentwicklungstechniken sind häufig ein Umtausch dazwischen, was "gut" ist, und was "gut genug ist".
Pixel hinzufügend, machen vollkommene Kollisionen Ihr Spiel besser, um zu spielen, aber schneiden den framerate entzwei, viele Entwickler werden höher framerate wählen und Kollisionsgenauigkeit senken.
Als solcher, die Leistung über die Kollisionsentdeckung für Box2D wissend, würde einem Entwickler helfen, eine informierte Wahl zu machen. Natürlich sollten Sie versuchen, die Vergleiche als nahe wie möglich zu machen, und möchten, alle jene 8 Scheitelpunkte zu verwenden.
Sie sind im Prinzip richtig. Aber in diesem Beispiel würde ich sagen, dass die Entscheidung durch das Design getroffen werden muss. Leistung ist gerade für diese Entscheidung nicht entscheidend. Performance just isn’t crucial to this decision.
Zum Beispiel sind mit dem Pixel vollkommene Kollisionen sehr genau, aber arbeiten in keiner der Elfen wird rotieren gelassen oder erklettert. Wohingegen, wenn Sie Kollisionsentdeckung mit einem Physik-Motor denken, Ihre Elfen rotieren gelassen oder erklettert werden können. Und Chancen bestehen darin, dass, wenn Sie wollen oder einen Physik-Motor irgendwie verwenden müssen, Physik verwendend, um alle Kollisionen zu entdecken, einfach eine Voraussetzung ist. And chances are that if you want or have to be using a physics engine anyway, using physics to detect all collisions is simply a requirement.
Steffen, ich freue mich Sie bauten auf meinen Posten der Vieljahre alt. In meiner Verteidigung stellte ich wirklich fest, dass ich Pseudocode anschlug.
Ich bin codeklug spezifisch oftmals vorsätzlich vage, weil, was wirklich Sachen das Grundkonzept ist, und ich gern Leute es zu Ende denke und ihre eigenen Lösungen und Durchführungen präsentiere.
So weit die Brauchbarkeit des Codes dagegen, ein Physik-Motor sagt, hängt es wirklich davon ab, was Sie tun. Ich rufe zurück, dass, als ich diese Idee anschlug, ich an einem Lemming-Typ des Klons für das EIN/AUSGABE-STEUERSYSTEM (nie veröffentlicht) arbeitete, und das Echtzeitdeformierung des Terrains in halbkreisförmigen Gestalten zur Folge hatte, die in einigen Scheitelpunkten endeten, die sowohl Backenhörnchen als auch OpenGL ES veranlassten, ganz schnell zu ersticken (wir reden 1. Informationsgeräte hier).
Diese Methode statt dessen ich einfach abgehackt die "Terrain"-Textur mit einem Kreis verwendend, aktualisieren Sie die Kollisionskarte, und die einzige minimale Verlangsamung lud die Textur von der Zentraleinheit bis den GPU wieder (welcher nur geschah, als das Terrain wirklich, nicht dass üblich eines Ereignisses modifiziert wurde).
BTW, den Code regulierend, um an rotieren gelassenen oder schuppigen Knoten zu arbeiten, ist nicht das komplizierte. Sie würden einfach den Eingangspunkt vor dem Tun des lookup umgestalten müssen.
Ich setzte fort zu denken, dass der folgende logische Schritt eine mit den Lemmingen artige Terrain-Deformierung sein würde.
Bezüglich des Umwandelns des Eingangspunkts tat ich das im ersten Beispiel. Prüfung, wenn ein Punkt innerhalb einer schuppigen und rotieren gelassenen Kollisionskarte ist, ist eine Sache, den Punkt zum Knotenraum umzuwandeln. Aber das scheitert, wenn Sie zwei Kollisionskarten gegen einander prüfen wollen, und beide erklettert oder rotieren gelassen werden können. Vielleicht ist es möglich, obwohl man zuerst den zurzeit analysierten Punkt von einem Knoten bis Weltraum, und dann zum Raum des anderen Knotens, nicht sicher umgestaltet, wenn das das richtige Ergebnis geben wird. But this fails if you want to test two collision maps against each other, and both may be scaled or rotated. Maybe it’s possible though to first transform the currently analyzed point from one node to world space, and then to the other node’s space, not sure if that will give the correct result.
Sie würden sich vielfach wenden müssen verwandelt sich. Es ist alles von Bedürfnissen wirklich abhängig.
Wenn an einem Punkt Sie genaue Richtung, Schwung, Trägheit oder einigen jener Vektoren als ein Teil der Kollision wissen müssen, dann sind Sie wahrscheinlich aus mit dem Physik-Motor besser.
Hallo Steffen
Und wenn die zwei Elfen, um für die Kollision zu überprüfen, auf verschiedenem CCLayers sind, konnte Ihr Code aktualisiert werden, um das auch zu behandeln? So dass die Position der Maske-Elfen zum Weltraum oder etwas in der Kollisionskontrolle umgewandelt wird?
Mit besten Grüßen
Søren
Haben Sie nachgeprüft, dass der Code scheitert, die Kollisionen richtig in diesem Fall zu melden? Weil, so weit ich verstehe, es, Koordinaten zu einem Raum eines Knotens (Koordinatensystem) umwandelnd, in Betracht ziehen wird (oder es einfach egal ist), dass der Knoten ein Kind von einem oder mehreren anderen Knoten sein kann.
Hm ist scheiterte wirklich, aber er beklagte sich über rotieren gelassene Knoten, und ich sah zuerst das jetzt.. Ich lasse meine Elfen sehr traurig rotieren
Hallo Steffen
Ich habe KKPixelMaskSprite erfolgreich mit meinem Spiel verwendet (es ist groß!), aber habe ich meine Elfen zu spriteWithSpriteFrameName … geändert, und jetzt begreife ich, dass er mit Elfe-Rahmen nicht arbeitet
Ich bin dabei zu versuchen, KKPixelMaskSprite anzupassen, um mit Elfe-Rahmen zu arbeiten (Ich nehme an, dass er nicht getan worden ist). Irgendein Hinweis, um damit anzufangen?
Dank!!
JARV
Schließlich bekomme ich es, mit einem kleinen workaround … arbeitend, der zu meinem Zweck in Ordnung ist (couse, kann es verbessert werden)
1. - Schaffen einen CCRenderTexture mit der Größe der Elfe.
2. - Änderungselfe-Position zu 0,0, um den CCRenderTexture zu besuchen und dann seine ursprüngliche Position wieder herzustellen:
sprite.anchorPoint = ccp (0,0);
sprite.position = ccp (sprite.offsetPositionInPixels.x * (-1)
, sprite.offsetPositionInPixels.y * (-1));
3. - Schaffen einen UIImage mit dem CCRenderTexture:
UIImage *image = [rt getUIImageFromBuffer];
Jetzt haben wir einen UIImage, und wir können den Code von KKPixelMaskSprite (initWithFile) wiederverwenden.
Gerade eine Endrücksicht vor dem Anruf pixelMaskContainsPoint müssen wir den Punkt wegen des Ausgleichs regulieren:
CGPoint weisen = ccp (point.x-sprite.offsetPositionInPixels.x, point.y-sprite.offsetPositionInPixels.y) hin;
Es arbeitet groß!!