In meinem (Puzzle-)Spiel werden die Teile auf dem Bildschirm gezeichnet, indem ein CALayer
für jedes Stück. Es gibt 48 Teile (in einem 8x6-Raster), wobei jedes Teil 48x48 Pixel groß ist. Ich bin nicht sicher, ob dies nur zu viele Schichten ist, aber wenn dies nicht die beste Lösung ist, weiß ich nicht, was ist, weil neu zeichnen die gesamte Anzeige mit Quartz2D jedes Bild scheint nicht wie es wäre schneller.
Wie auch immer, die Bilder für die Stücke kommen aus einer großen PNG-Datei, die 24 Frames der Animation für 10 verschiedene Zustände hat (so misst 1152 x 480 Pixel) und die Animation wird durch die Einstellung der contentsRect
Eigenschaft eines jeden CALayer
wenn ich sie bewege.
Dies scheint tatsächlich ziemlich gut mit bis zu 7 Stücken zu funktionieren, die einen Berührungspunkt im Fenster verfolgen, aber die seltsame Sache ist, dass, wenn ich anfange, die Stücke zu bewegen, für die ersten 0,5 eine Sekunde oder so, es sehr ruckelig ist, wie die CPU etwas anderes tut, aber danach wird es verfolgen und den Bildschirm bei 40+ FPS (nach Instrumenten) aktualisieren.
Hat jemand eine Idee, was der Grund für diese anfängliche Ruckelei sein könnte?
Die einzige Theorie, die ich mit kommen konnte, ist es dekomprimieren Bits der PNG-Datei in einen temporären Speicherort und dann verwerfen Sie, nachdem die Animation gestoppt hat, in diesem Fall gibt es eine Möglichkeit, Core Animation tun, dass zu stoppen?
Ich könnte natürlich die PNG-Datei in 10 Teile aufteilen, aber ich bin nicht überzeugt, dass das helfen würde, da sie alle (potenziell) immer noch gleichzeitig im Speicher sein müssten.
EDIT : OK, wie im Kommentar zur ersten Antwort beschrieben, habe ich das Bild in zehn Teile aufgeteilt, die jetzt 576 x 96 groß sind, damit es in die Beschränkungen der Hardware passt. Es ist aber immer noch nicht so glatt, wie es sein sollte, also habe ich ein Kopfgeld darauf ausgesetzt.
EDIT2: Ich habe eines der Bilder unten verlinkt. Im Wesentlichen wird die Berührung des Benutzers verfolgt, der Versatz vom Beginn der Verfolgung wird berechnet (sie können sich nur horizontal oder vertikal und nur an einer Stelle gleichzeitig bewegen). Dann wird eines der Bilder als Inhalt der Ebene ausgewählt (je nachdem, um welche Art von Teil es sich handelt und ob es sich horizontal oder vertikal bewegt). Dann wird die contentsRect
ist so eingestellt, dass ein 48x48-Bild aus dem größeren Bild ausgewählt wird, etwa so:-
layer.position = newPos;
layer.contents = (id)BallImg[imgNum];
layer.contentsRect = CGRectMake((1.0/12.0)*(float)(frame % 12),
0.5 * (float)(frame / 12),
1.0/12.0, 0.5);
btw. Meine Theorie, dass das Quellbild jedes Mal neu dekomprimiert wird, war nicht richtig. Ich habe einen Code geschrieben, der die rohen Pixel aus der dekodierten PNG-Datei in eine neue Datei kopiert. CGImage
wenn die App geladen wird, und es hat keinen Unterschied gemacht.
Als Nächstes werde ich versuchen, jedes Einzelbild in eine separate Datei zu kopieren. CGImage
die die hässlichen contentsRect
zumindest die Berechnung.
EDIT3: Weitere Untersuchungen haben ergeben, dass es sich um ein Problem mit dem Touch-Tracking handelt und nicht um ein Problem mit Core Animation. Ich habe eine einfache Beispielanwendung gefunden, die Berührungen verfolgt und den Code auskommentiert, der das Neuzeichnen des Bildschirms und die NSLog()
zeigt genau das gleiche Problem, das auch bei mir auftritt: Eine längere Verzögerung zwischen dem touchesBegin
und erste touchesMoved
Veranstaltungen.
2009-06-05 01:22:37.209 TouchDemo[234:207] Begin Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.432 TouchDemo[234:207] Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.448 TouchDemo[234:207] Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.464 TouchDemo[234:207] Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.480 TouchDemo[234:207] Touch ID 0 Tracking with image 2
Typische Lücke zwischen touchesMoved
Ereignisse beträgt 20ms. Der Abstand zwischen den touchesBegin
und erste touchesMoved
ist zehnmal so hoch. Und das ganz ohne Berechnungen oder Bildschirmaktualisierung, nur mit der NSLog
rufen. Seufz. Ich schätze, ich werde das als separate Frage aufmachen.