Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在没有Cocos2d的情况下,如何在Xcode中设置精灵工作表的动画?_Ios_Xcode_Animation_Sprite - Fatal编程技术网

Ios 在没有Cocos2d的情况下,如何在Xcode中设置精灵工作表的动画?

Ios 在没有Cocos2d的情况下,如何在Xcode中设置精灵工作表的动画?,ios,xcode,animation,sprite,Ios,Xcode,Animation,Sprite,我正在开发一个简单的应用程序,当用户移动滑块时,该应用程序可以为图像设置动画。这可以很容易地用单个图像来完成,但由于明显的原因,这种方法效率低下 目前,我已经将动画分解为14张精灵图片,每张图片16张。我创建了一个方法,该方法使用CGImageCreateWithImageInRect查找由滑块指定的当前图像,并使用该图像更新图像视图。这是可行的,但不是流畅的。我想我明白为什么,但我不知道该怎么办。虽然我可以使用Cocos2d或OpenGL ES,但我很固执,相信没有它们这是可能的。我只是想知道

我正在开发一个简单的应用程序,当用户移动滑块时,该应用程序可以为图像设置动画。这可以很容易地用单个图像来完成,但由于明显的原因,这种方法效率低下

目前,我已经将动画分解为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帧交换一次图像。为了解决这个问题,我的控制器让视图在另一个视图(如窗帘)下的所有图像中快速循环,因此用户只知道加载屏幕。循环图像后,将删除幕墙视图并播放动画(由用户控制)