Ios 在没有Cocos2d的情况下,如何在Xcode中设置精灵工作表的动画?
我正在开发一个简单的应用程序,当用户移动滑块时,该应用程序可以为图像设置动画。这可以很容易地用单个图像来完成,但由于明显的原因,这种方法效率低下 目前,我已经将动画分解为14张精灵图片,每张图片16张。我创建了一个方法,该方法使用CGImageCreateWithImageInRect查找由滑块指定的当前图像,并使用该图像更新图像视图。这是可行的,但不是流畅的。我想我明白为什么,但我不知道该怎么办。虽然我可以使用Cocos2d或OpenGL ES,但我很固执,相信没有它们这是可能的。我只是想知道怎么做 下面是一些示例代码:Ios 在没有Cocos2d的情况下,如何在Xcode中设置精灵工作表的动画?,ios,xcode,animation,sprite,Ios,Xcode,Animation,Sprite,我正在开发一个简单的应用程序,当用户移动滑块时,该应用程序可以为图像设置动画。这可以很容易地用单个图像来完成,但由于明显的原因,这种方法效率低下 目前,我已经将动画分解为14张精灵图片,每张图片16张。我创建了一个方法,该方法使用CGImageCreateWithImageInRect查找由滑块指定的当前图像,并使用该图像更新图像视图。这是可行的,但不是流畅的。我想我明白为什么,但我不知道该怎么办。虽然我可以使用Cocos2d或OpenGL ES,但我很固执,相信没有它们这是可能的。我只是想知道
- (void)setUp{
NSString *string;
NSString *bundleString = [[NSBundle mainBundle] bundlePath];
dsRedPathArray = [[NSMutableArray alloc] initWithCapacity:15];
for (int i = 0; i < 14; i++)
{
string = [bundleString stringByAppendingFormat:@"/dsRedAni_%d.png", i];
[dsRedPathArray addObject:string];
}
//initial image starts at (0, 1) of image dsRedAni_9
currentImage = [UIImage imageWithContentsOfFile:[dsRedPathArray objectAtIndex:9]];
currentRef = CGImageCreateWithImageInRect(currentImage.CGImage, CGRectMake(495, 0, kModelWidth, kModelHeight));
modelView.image = [UIImage imageWithCGImage:currentRef];
}
- (IBAction)sliderMoved:(UISlider*)sender
{
[self animateModel:sender.value];
}
- (void)animateModel:(int)index
{
index += 1;
imageIndex = (index / 16) + 9;
if (imageIndex > 13)
{
imageIndex = -14 + imageIndex;
}
currentX = kModelWidth * (index % 4);
currentY = kModelHeight * ((index / 4) % 4);
currentRect = CGRectMake(currentX, currentY, kModelWidth, kModelHeight);
currentImage = [UIImage imageWithContentsOfFile:[dsRedPathArray objectAtIndex: (imageIndex)]];
currentRef = CGImageCreateWithImageInRect(currentImage.CGImage, currentRect);
modelView.image = [UIImage imageWithCGImage:currentRef];
}
-(无效)设置{
NSString*字符串;
NSString*bundleString=[[NSBundle mainBundle]bundlePath];
dsRedPathArray=[[NSMutableArray alloc]initWithCapacity:15];
对于(int i=0;i<14;i++)
{
字符串=[BundleStringStringByAppendingFormat:@”/dsRedAni_u%d.png“,i];
[dsRedPathArray addObject:string];
}
//初始图像从图像dsRedAni_9的(0,1)处开始
currentImage=[UIImage imageWithContentsOfFile:[dsRedPathArray objectAtIndex:9]];
currentRef=CGImageCreateWithImageInRect(currentImage.CGImage,CGRectMake(495,0,kModelWidth,kModelHeight));
modelView.image=[UIImage imageWithCGImage:currentRef];
}
-(iAction)滑块移动:(UISlider*)发送器
{
[self-animateModel:sender.value];
}
-(void)animateModel:(int)索引
{
指数+=1;
imageIndex=(指数/16)+9;
如果(图像索引>13)
{
imageIndex=-14+imageIndex;
}
currentX=kModelWidth*(索引%4);
当前Y=K模型高度*((指数/4)%4);
currentRect=CGRectMake(currentX、currentY、kModelWidth、kModelHeight);
currentImage=[UIImage imageWithContentsOfFile:[dsRedPathArray objectAtIndex:(imageIndex)];
currentRef=CGImageCreateWithImageInRect(currentImage.CGImage,currentRect);
modelView.image=[UIImage imageWithCGImage:currentRef];
}
提前感谢您的帮助。一种方法是使用CGImageCreateWithImageInRect切割图像,就像您上面开始的那样。然后,将它们添加到数组中:
myArray addObject:[UIImage imageWithCGImage:currentRef];
接下来将UIImageView与setAnimationImages一起使用,如下所示:
UIImageView *myAnimationImageView;
[myAnimationImageView setAnimationImages:myArray];
然后可以启动动画
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setUp];
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
}
return self;
}
- (void)setUp
{
//assign |lastImageIndex| a number not equal to |imageIndex|
lastImageIndex = -1;
modelImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1924, 1708)];
NSString *string;
NSString *bundleString = [[NSBundle mainBundle] bundlePath];
UIImage *image;
if (!imageArray)
{
imageArray = [[NSMutableArray alloc] init];
NSLog(@"Init egfp |imageArray|");
}
for (int i = 0; i < 10; i++)
{
string = [bundleString stringByAppendingFormat:@"/moleculeAni_%d.png", i];
image = [UIImage imageWithContentsOfFile:string];
[imageArray addObject:image];
if (i == 9)
{
NSLog(@"Filled egfp |imageCache|");
}
}
[self addSubview:modelImageView];
}
- (void)animateModel:(int)index
{
if (index != 1)
{
index -= 1;
}
imageIndex = (index / 16);
if (imageIndex < 9)
{
currentX = 962 - (481 * (index % 4));
currentY = 854 - (427 * ((index / 4) % 4));
}
else
{
currentX = 962 - (481 * (index % 4));
currentY = 427 - (427 * ((index / 4) % 4));
}
if (imageIndex != lastImageIndex)
{
if (imageIndex < 9 && onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 1708);
onLastFrame = NO;
}
else if (imageIndex == 9 && !onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 854);
onLastFrame = YES;
}
NSLog(@"Image: %d", imageIndex);
tempImage = [imageArray objectAtIndex:imageIndex];
modelImageView.image = tempImage;
}
modelImageView.center = CGPointMake(currentX, currentY);
lastImageIndex = imageIndex;
}
这里有一个很好的项目可以做到这一点:一种方法是使用CGImageCreateWithImageInRect切割图像,就像上面开始的那样。然后,将它们添加到数组中:
myArray addObject:[UIImage imageWithCGImage:currentRef];
接下来将UIImageView与setAnimationImages一起使用,如下所示:
UIImageView *myAnimationImageView;
[myAnimationImageView setAnimationImages:myArray];
然后可以启动动画
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setUp];
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
}
return self;
}
- (void)setUp
{
//assign |lastImageIndex| a number not equal to |imageIndex|
lastImageIndex = -1;
modelImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1924, 1708)];
NSString *string;
NSString *bundleString = [[NSBundle mainBundle] bundlePath];
UIImage *image;
if (!imageArray)
{
imageArray = [[NSMutableArray alloc] init];
NSLog(@"Init egfp |imageArray|");
}
for (int i = 0; i < 10; i++)
{
string = [bundleString stringByAppendingFormat:@"/moleculeAni_%d.png", i];
image = [UIImage imageWithContentsOfFile:string];
[imageArray addObject:image];
if (i == 9)
{
NSLog(@"Filled egfp |imageCache|");
}
}
[self addSubview:modelImageView];
}
- (void)animateModel:(int)index
{
if (index != 1)
{
index -= 1;
}
imageIndex = (index / 16);
if (imageIndex < 9)
{
currentX = 962 - (481 * (index % 4));
currentY = 854 - (427 * ((index / 4) % 4));
}
else
{
currentX = 962 - (481 * (index % 4));
currentY = 427 - (427 * ((index / 4) % 4));
}
if (imageIndex != lastImageIndex)
{
if (imageIndex < 9 && onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 1708);
onLastFrame = NO;
}
else if (imageIndex == 9 && !onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 854);
onLastFrame = YES;
}
NSLog(@"Image: %d", imageIndex);
tempImage = [imageArray objectAtIndex:imageIndex];
modelImageView.image = tempImage;
}
modelImageView.center = CGPointMake(currentX, currentY);
lastImageIndex = imageIndex;
}
这里有一个很好的项目可以做到这一点:我终于找到了一种非常快速有效的方法,可以在没有API任何外部帮助的情况下循环浏览我的sprite表单的每一部分。我发现,创建一个与所需图像大小相同的UIView,然后将整个精灵工作表作为UIImageView添加到视图中,对我来说更有效,而不是花费时间和精力将图像分割成上下文或单个文件 将view.clipsToBounds设置为“是”时,该视图将用作我的精灵工作表的遮罩,将可见部分限制为我要在工作表上循环浏览的每个图像的大小。为了提供动画效果,我只需使用imageview.center将精灵工作表围绕视图移动到所需的图像坐标。所以,在一个有16个图像的精灵表中,我只需要调用一次来显示图像,然后在动画中每帧移动一次
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setUp];
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
}
return self;
}
- (void)setUp
{
//assign |lastImageIndex| a number not equal to |imageIndex|
lastImageIndex = -1;
modelImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1924, 1708)];
NSString *string;
NSString *bundleString = [[NSBundle mainBundle] bundlePath];
UIImage *image;
if (!imageArray)
{
imageArray = [[NSMutableArray alloc] init];
NSLog(@"Init egfp |imageArray|");
}
for (int i = 0; i < 10; i++)
{
string = [bundleString stringByAppendingFormat:@"/moleculeAni_%d.png", i];
image = [UIImage imageWithContentsOfFile:string];
[imageArray addObject:image];
if (i == 9)
{
NSLog(@"Filled egfp |imageCache|");
}
}
[self addSubview:modelImageView];
}
- (void)animateModel:(int)index
{
if (index != 1)
{
index -= 1;
}
imageIndex = (index / 16);
if (imageIndex < 9)
{
currentX = 962 - (481 * (index % 4));
currentY = 854 - (427 * ((index / 4) % 4));
}
else
{
currentX = 962 - (481 * (index % 4));
currentY = 427 - (427 * ((index / 4) % 4));
}
if (imageIndex != lastImageIndex)
{
if (imageIndex < 9 && onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 1708);
onLastFrame = NO;
}
else if (imageIndex == 9 && !onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 854);
onLastFrame = YES;
}
NSLog(@"Image: %d", imageIndex);
tempImage = [imageArray objectAtIndex:imageIndex];
modelImageView.image = tempImage;
}
modelImageView.center = CGPointMake(currentX, currentY);
lastImageIndex = imageIndex;
}
-(id)initWithFrame:(CGRect)frame
{
self=[super initWithFrame:frame];
如果(自我){
[自我设置];
self.backgroundColor=[UIColor clearColor];
self.clipstobunds=是;
}
回归自我;
}
-(无效)设置
{
//为| lastImageIndex |分配一个不等于| imageIndex的数字|
lastImageIndex=-1;
modelImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0,01241708)];
NSString*字符串;
NSString*bundleString=[[NSBundle mainBundle]bundlePath];
UIImage*图像;
如果(!imageArray)
{
imageArray=[[NSMutableArray alloc]init];
NSLog(@“Init egfp|imageArray|”);
}
对于(int i=0;i<10;i++)
{
字符串=[BundleStringByAppendingFormat:@”/molecleani_u%d.png“,i];
image=[UIImage-imageWithContentsOfFile:string];
[imageArray addObject:image];
如果(i==9)
{
NSLog(@“填充egfp |图像缓存”);
}
}
[自添加子视图:modelImageView];
}
-(void)animateModel:(int)索引
{
如果(索引!=1)
{
指数-=1;
}
imageIndex=(指数/16);
如果(图像索引<9)
{
currentX=962-(481*(索引%4));
电流y=854-(427*((指数/4)%4));
}
其他的
{
currentX=962-(481*(索引%4));
电流y=427-(427*((指数/4)%4));
}
如果(imageIndex!=lastImageIndex)
{
if(imageIndex<9&&onLastFrame)
{
modelImageView.frame=CGRectMake(0,019241708);
onLastFrame=否;
}
else if(imageIndex==9&&!onLastFrame)
{
modelImageView.frame=CGRectMake(0,0124854);
onLastFrame=是;
}
NSLog(@“图像:%d”,图像索引);
tempImage=[imageArray对象索引:imageIndex];
modelImageView.image=tempImage;
}
modelImageView.center=CGPointMake(currentX,currentY);
lastImageIndex=imageIndex;
}
这里的大部分代码用于确定imageview需要移动到哪里才能显示正确的图像。这是采用我上面解释的方法,并将其分布在10张sprite表单上,每个表单上均匀分布16张图像(最后一张有8张图像除外)。唯一的减速是程序每16帧交换一次图像。为了解决这个问题,我的控制器让视图在另一个视图(如窗帘)下的所有图像中快速循环,因此用户只知道加载屏幕。循环图像后,将删除幕墙视图并播放动画(由用户控制)