Hi,
I am currently working on an iPhone game, and need to create some animation on the fly. The animation is based on several images, and as the range of image combinations is too large and it is impossible to pre-create all of sequences, I'd like to be able to recalculate a set of images every time the situation changes.
The function creates a series of images, to be used as an animation sequence. I need help with two things:
- There are several large memory leaks that I'm having trouble finding - I need help locating them
- Since I'm new to the iPhone, I want to know if there is a better way to do it, if you have a better suggestion on how to write it, please share...
Code:
(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);
}
}