【问题标题】:SpriteKit: moving sprite infinitely cause the frame sometimes incontinuousSpriteKit:无限移动精灵导致帧有时不连续
【发布时间】:2014-07-11 11:21:34
【问题描述】:

全部。 我现在正在使用 sprite kit 开发一个 ios 游戏。游戏机制包括:从上到下无限滚动 sprite。

我的游戏场景只有 3 个精灵,上、中、下。 我有几十个精灵图像,所以我的解决方案是动态创建3个精灵(这样精灵可以填满整个屏幕),当底部精灵离开屏幕时,然后销毁它;当顶部精灵 向下顶帧,创建一个新的精灵节点,然后交换底部,中间,顶部精灵。

伪代码: 在接口文件中:

 - GameScene:SKScene
 {
      ...
      SKSpriteNode *_topSprite;
      SKSpriteNode *_middleSprite;
      SKSpriteNode *_bottomSprite;
      ...
 }

在实现文件中:

- (void)update:(CFTimeInterval)currentTime 
{
   // 1 compute time interval


   // 2 update sprite node
    _topSprite.position move down  100*timeInterval
   _middleSprite.position move down  100*timeInterval  
   _bottomSprite.position move down    100*timeInterval 

   // 3 crop the off-screen bottom sprite node
   if (_bottomSprite is offScreen)
   {
       [_bottomSprite removeFromParent]
   }

   // 4 check the highest sprite position visible
   // if the highest position is below the frame top,then create new sprite
   _bottomSprite = _middleSprite;  
   _middleSprite = _topSprite;
   _topSprite    = [self createNewNode]; // random a sprite image 
}

游戏帧数为60,节点数没有增加。 一切似乎都很好,但我发现有时游戏突然有一个非常严重的阻塞,导致移动帧不连续。 在我的直觉中,我认为主要原因是由第 4 步引起的。 但我没有任何想法来解决它。 任何建议将不胜感激。

这里是 createNewNode 方法:

- (SKSpriteNode *)createNewNode {
    NSString *blockName = [self randomImageName];

    SKSpriteNode *sprite = [[SKSpriteNode alloc] initWithImageNamed:blockName];
    sprite.position = _highestPosition;
    sprite.anchorPoint = CGPointMake(0.5, 0);
    NSLog(@"putAnotherNodeOnTop %@", blockName);
    [self addChild:sprite];
    return sprite;
}

【问题讨论】:

  • 您的精灵图像的大小是多少?它们是从 sprites.atlas 加载的吗?
  • 我的 sprite 图片都是一样的大小:390*512。我不使用 sprites.atlas。
  • 很奇怪。不应该有这样的问题。你能发布你的 createNode 吗?
  • 我把代码贴在帖子里。
  • 使用 Time Profiler 确定哪一行代码最昂贵

标签: objective-c sprite-kit frame-rate skspritenode sknode


【解决方案1】:

一些建议。

由于您使用的是相同的三张图片,因此您无需每次都重新创建精灵。将隐藏值设置为 YES,将精灵移动到某处,设置纹理,然后将其再次显示,隐藏为 NO 应该更便宜。 SpriteKit 不会绘制隐藏节点或屏幕外的节点。

当调用 createNewNode: 时,您的代码基本上要求更新的每一帧都在磁盘上保存一个 PNG。将纹理加载到内存中并根据需要将它们分配给精灵应该会更高效。如果你只有几个,让它们成为 SKTexture 实例变量将是一种简单的方法。

使用 spritesheets(纹理图集),在映射坐标处从内存中绘制图像比每次从磁盘加载图像要快得多。例如,对于 spritesheet 中的三个图像,这可以是单个绘图调用。从磁盘来看,这是三个独立的绘图调用。

您正在返回一个精灵并将其添加到 createNewNode: 方法中的场景中。也许出于某种原因,这就是您想要的。它作为可能的重复工作脱颖而出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 2019-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多