我目前正在开发iPhone游戏,需要动态创建一些动画。动画基于几个图像,由于图像组合的范围太大而无法预先创建所有序列,我希望每次情况发生变化时都能重新计算一组图像。 / p>
该函数创建一系列图像,用作动画序列。我需要帮助两件事:
代码:
(void) updateImages:(int) smallPicID
{
CGRect smallPicRect;
smallPicRect.size = CGSizeMake(25.0f, 25.0f);
//TODO: add smallPic location for every image. Currently the values only match the first image...
static const CGPoint smallPicLocation[11][SMALLPIC_LOCATION_COUNT] =
{
{ {126.0f, 153.0f},{105.0f, 176.0f}, {115.0f, 205.0f}, {145.0f, 211.0f}, {166.0f, 188.0f}, {156.0f, 159.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }
};
for(int i = 0; i < self.m_finalImages.count; ++i)
{
// start with base image
UIImage * baseImg = [self.m_finalImagesEmpty objectAtIndex:i];
CGImageRef baseImgCtx = baseImg.CGImage;
// Create the bitmap context that matches the baseImg parameters
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef newImgCtx = CGBitmapContextCreate(NULL,
CGImageGetWidth(baseImgCtx),
CGImageGetHeight(baseImgCtx),
8, 0, colorSpace,
(kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
CGColorSpaceRelease(colorSpace);
if (newImgCtx == NULL)
{
// error creating context
assert(0);
return;
}
// Get empty drum image width, height.
size_t w = CGImageGetWidth(baseImgCtx);
size_t h = CGImageGetHeight(baseImgCtx);
CGRect rect = {{0,0},{w,h}};
// Draw the image to the bitmap context.
// newImgCtx now contains the full empty drum image.
CGContextDrawImage(newImgCtx, rect, baseImgCtx);
CGContextSaveGState(newImgCtx);
// translate & scale because of origin difference between UIKit and CG
CGContextTranslateCTM(newImgCtx, 0, h);
CGContextScaleCTM(newImgCtx, 1, -1);
int startLocation = 0;
int endLocation = SMALLPIC_LOCATION_COUNT;
// for each location
for(int j = startLocation; j < endLocation; j++)
{
// if its empty, nothing to do, move to next bullet
if (m_locationStatus[j] == CY_EMPTY)
continue;
UIImage * srcImg;
switch (m_locationStatus[j])
{
case CY_FULL: srcImg = [self.m_finalImagesLoaded objectAtIndex:i]; break;
case CY_USED: srcImg = [self.m_finalImagesSpent objectAtIndex:i]; break;
}
// create small image containing only the smallpic from the src img
smallPicRect.origin = smallPicLocation[i][j];
CGImageRef smallpicCGImg = CGImageCreateWithImageInRect(srcImg.CGImage, smallPicRect);
// draw the smallpic into the new context
CGContextDrawImage(newImgCtx, smallPicRect, smallpicCGImg);
CGImageRelease(smallpicCGImg);
}
CGContextRestoreGState(newImgCtx);
// update the image from the context
UIImage *baseImg = [self.m_finalImages objectAtIndex:i];
CGImageRef imgref = CGBitmapContextCreateImage(newImgCtx);
//[baseImg release];
[baseImg initWithCGImage:imgref];
CGContextRelease(newImgCtx);
}
}
答案 0 :(得分:2)
我跳出来的第一件事就是使用CGBitmapContextCreateImage()创建imgref,但没有匹配的CGImageRelease()和baseImg initWithCGImage:消息,除了咀嚼内存之外什么都不做。我想你想用以下内容替换以“从上下文更新图像”开头的部分:
CGImageRef imgref = CGBitmapContextCreateImage(newImgCtx);
UIImage *replacmentBaseImg = [[UIImage alloc] initWithCGImage:imgref];
CGImageRelease(imgref);
[self.m_finalImages replaceObjectAtIndex:i withObject:replacementBaseImg];
[replacementBaseImg release];
CGContextRelease(newImgCtx);
这假设m_finalImages是一个NSMutableArray,并且您已正确释放已插入该数组中的其他图像,因此当您替换它们时,它们将被取消分配。
在较大的结构注释中,您可能希望将较小的子图像绘制到单个CALayers中,然后将这些图层在各个位置交换进出屏幕以完成动画。 Quartz绘图很昂贵,而CALayers是缓存的图像,存储在GPU上作为纹理。其他人使用CALayers进行了这些基于精灵的动画,并取得了令人瞩目的成绩。