Как мне оживить спрайт лист в Xcode без Cocos2d? - PullRequest
1 голос
/ 08 февраля 2012

Я разрабатываю простое приложение, которое анимирует изображение, когда пользователь перемещает ползунок. Это легко сделать с помощью отдельных изображений, но по понятным причинам этот метод неэффективен.

В настоящее время у меня анимация разбита на 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];
}

Заранее спасибо за любую помощь.

Ответы [ 2 ]

4 голосов
/ 16 февраля 2012

Я наконец нашел довольно быстрый и эффективный, хотя и нетрадиционный, способ циклически проходить по каждому разделу моих листов спрайтов без какой-либо внешней помощи от API. Вместо того, чтобы тратить время и силы на разделение изображения на контексты или отдельные файлы, я обнаружил, что для меня более эффективно создать UIView с размером нужного мне изображения, а затем добавить весь спрайт-лист в представление как UIImageView. ,

Если для view.clipsToBounds задано значение YES, представление действует как маска для моего листа спрайта, ограничивая видимую часть размером каждого изображения, которое я хочу циклически перемещать на листе. Чтобы придать эффект анимации, я просто использую 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;
}

Большая часть кода здесь тратится на определение того, куда необходимо переместить изображение, чтобы отобразить правильное изображение. Для этого используется метод, который я объяснил выше, и он распределяется по 10 листам спрайтов, каждый из которых равномерно распределяется по 16 изображениям (кроме последнего с 8). Единственное замедление произошло, когда программа менялась между изображениями каждый 16-й кадр. Чтобы обойти это, мой контроллер имеет представление, быстро циклически перебирающее все изображения под другим видом (например, шторкой), поэтому пользователь имеет доступ только к экрану загрузки. Как только изображения циклически повторяются, вид шторки удаляется, и анимация (управляемая пользователем с помощью ползунка) движется как масло.

2 голосов
/ 09 февраля 2012

Один из способов сделать это - разрезать изображения с помощью CGImageCreateWithImageInRect, как вы начали выше.Затем добавьте их в массив:

myArray addObject:[UIImage imageWithCGImage:currentRef];

Далее используйте UIImageView с setAnimationImages, например так:

UIImageView *myAnimationImageView;
[myAnimationImageView setAnimationImages:myArray];

Затем Вы можете запустить анимацию.

Тамхороший проект, делающий это здесь: https://github.com/r3econ/UIImage-Sprite-Additions

...