带有内容的核心动画 [英] Core Animation with contentsRect jerkiness

查看:69
本文介绍了带有内容的核心动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的益智游戏中,每件作品都在屏幕上使用 CALayer 绘制。有48个(在8x6网格中),每个像素为48x48像素。我不确定这是否是太多层,但是如果这不是最好的解决方案,我不知道这是什么,因为使用Quartz2D重绘整个显示器似乎并不会更快。

in my (puzzle) game the pieces are drawn on-screen using a CALayer for each piece. There are 48 pieces (in an 8x6 grid) with each piece being 48x48 pixels. I'm not sure if this is just too many layers, but if this isn't the best solution I don't know what is, because redrawing the whole display using Quartz2D every frame doesn't seem like it would be any faster.

无论如何,片段的图像来自一个大的PNG文件,该文件具有针对10个不同状态的24帧动画(因此尺寸为1152 x 480像素),并且动画为通过在移动时设置每个 CALayer contentsRect 属性来完成操作。

Anyway, the images for the pieces come from one big PNG file that has 24 frames of animation for 10 different states (so measures 1152 x 480 pixels) and the animation is done by setting the contentsRect property of each CALayer as I move it.

这实际上可以很好地工作,最多可以跟踪7个窗口中的接触点,但是很奇怪的是,当我最初开始移动这些部分时,前0.5秒左右,这非常像CPU一样干涩地做其他事情,但是之后它将以40 FPS以上的速度跟踪和更新屏幕(根据Instruments)。

This actually seems to work pretty well with up to 7 pieces tracking a touch point in the window, but the weird thing is that when I initially start moving the pieces, for the first 0.5 a second or so, it's very jerky like the CPU is doing something else, but after that it'll track and update the screen at 40+ FPS (according to Instruments).

那么,有没有人有什么想法可以解释这种最初的怪癖?

So does anyone have any ideas what could account for that initial jerkiness?

我能想到的唯一理论是将PNG文件的位解压缩到一个临时位置,然后在动画停止后丢弃它们,在这种情况下一种阻止Core Animation这样做的方法?

The only theory I could come up with is it's decompressing bits of the PNG file into a temporary location and then discarding them after the animation has stopped, in which case is there a way to stop Core Animation doing that?

我显然可以将PNG文件分成10个片段,但我不相信这会有所帮助,因为它们都会(可能)仍然需要一次存储在内存中。

I could obviously split the PNG file up into 10 pieces, but I'm not convinced that would help as they'd all (potentially) still need to be in memory at once.

编辑:好,如第一个答案的注释所述,我ve将图像分为十块,现在为576 x 96,以适应硬件的限制。它仍然还没有达到应有的水平,所以我对此进行了赏金。

OK, as described in the comment to the first answer, I've split the image up into ten pieces that are now 576 x 96, so as to fit in with the constraints of the hardware. It's still not as smooth as it should be though, so I've put a bounty on this.

EDIT2:下图。本质上是跟踪用户的触摸,计算从跟踪开始的偏移量(他们一次只能水平移动或垂直移动,一次只能移动一个位置)。然后,选择其中一张图片作为图层的内容(取决于图片的类型,以及图片是水平移动还是垂直移动)。然后将 contentsRect 属性设置为从较大图像中选择一个48x48帧,其内容如下:-

I've linked one of the images below. Essentially the user's touch is tracked, the offset from the start of the tracking is calculated (they can one move horizontal or vertical and only one place at a time). Then one of the images is selected as the content of the layer (depending on what type of piece it is and whether it's moving horizontally or vertically). Then the contentsRect property is set to chose one 48x48 frame from the larger image with something like this:-

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。我的理论是每次都重新压缩源图像是不正确的。我编写了一些代码,以在应用加载且没有任何区别的情况下,将解码后的PNG文件中的原始像素复制到新的 CGImage 中。

btw. My theory about it decompressing the source image a-fresh each time wasn't right. I wrote some code to copy the raw pixels from the decoded PNG file into a fresh CGImage when the app loads and it didn't make any difference.

接下来我要尝试的是将每个帧复制到单独的 CGImage 中,这将摆脱难看的 contentsRect至少计算。

Next thing I'll try is copying each frame into a separate CGImage which will get rid of the ugly contentsRect calculation at least.

EDIT3 :进一步的基础调查表明,这是触摸跟踪的问题,而不是Core的问题根本没有动画。我找到了一个基本的示例应用程序,该应用程序可以跟踪触摸并注释掉实际上导致屏幕重新绘制的代码,并且 NSLog()可以显示与我遇到的完全相同的问题:在 touchesBegin 和第一个 touchesMoved 事件之间存在较长的延迟。

Further back-to-basics investigation points to this being a problem with touch tracking and not a problem with Core Animation at all. I found a basic sample app that tracks touches and commented out the code that actually causes the screen to redraw and the NSLog() shows the exactly the same problem I've been experiencing: A long-ish delay between the touchesBegin and first touchesMoved events.

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

touchesMoved 事件之间的典型间隔为20ms。 touchesBegin 和第一个 touchesMoved 之间的差距是原来的十倍。而这完全不需要计算或屏幕更新,只需调用 NSLog 。叹。我想我将对此提出一个单独的问题。

Typical gap between touchesMoved events is 20ms. The gap between the touchesBegin and first touchesMoved is ten times that. And that's with no computation or screen updating at all, just the NSLog call. Sigh. I guess I'll open this up a separate question.

推荐答案

我不认为这是内存问题;我认为这与在Core Animation方面拥有这么大图像的效率低下有关。

I don't think it's a memory issue; I'm thinking that it has to do with the inefficiency of having that large of an image in terms of Core Animation.

Core Animation不能在本地使用它,因为它超过了GPU上的最大纹理大小(1024x1024)。 我会分解一些;单个图像可能会为您提供最佳性能,但是您必须进行测试才能找出答案。

Core Animation can't use it natively, as it exceeds the maximum texture size on the GPU (1024x1024). I would break it up some; individual images might give you the best performance, but you'll have to test to find out.

IIRC,UIImageView通过设置连续的单个图像来进行动画处理,因此对苹果足够好...。

IIRC, UIImageView does its animating by setting successive individual images, so if it's good enough for Apple….

这篇关于带有内容的核心动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆