2014-11-02 2 views
0

У меня есть javascript-игра, которую я хочу запустить на iOS. Javascript отправляет количество изображений, которые нужно нарисовать, и их позиции. Я использовал SpriteKit для рисования изображений, поэтому я создаю SKTexture из имени изображения и добавляю его в родительский узел.Какое максимальное количество текстур за кадр

Проблема в том, что я рисую 30 текстур/кадров. Частота кадров очень медленная на iPad3 (она хорошо работает на iPhone 5s). Я замечаю, что создание одной текстуры занимает 0.178 секунды, а загрузка ее из словаря занимает около 0.0036 секунды.

Так что для 30 текстур, обновление одного кадра займет 0,1 секунды, в то время как мне нужно, чтобы оно составляло 0,016, чтобы получить 60 кадров в секунду.

Есть 30 текстур в кадре, это слишком много? Какая альтернатива?

Есть ли спрайт правильной рамки для использования? Я хочу настроить iOS7, iOS8.

Edit: Вот как я получаю текстуры

func getTexture(imageNamed: String) -> SKTexture?{ 
    if let texture = cache.getObject(imageNamed) { 
     return texture 
    }else { 
     let texture = SKTexture(imageNamed) 
     cache.putObject(texture, forName: imageNamed) 
     return texture 
    } 
} 

Затем я добавляю его в узел SpriteKit в:

if let texture = getTexture(imageName) { 

    let imageNode = SKSpriteNode(texture:texture) 
    imageNode.anchorPoint=CGPointMake(0, 1) 
    imageNode.position = CGPoint(x:x, y:y) 

    parentNode!.addChild(imageNode) 
} 

Так выше код, будет создавать текстуру один раз и добавить его в кеш, и в следующий раз, когда это потребуется, оно будет доставлено из кеша. В настоящее время я не выпускаю текстуры из кеша, потому что у него небольшое количество текстур.

При следующем обновлении я удаляю всех детей из parentNode и снова добавляю текстуры на основе новых позиций.

Я не хочу добавлять действия Sprite, потому что у нас уже есть игра в javascript, и мы не хотим переписывать iOS, поэтому мы просто хотим добавить слой между js и iOS.

+1

Рисунок 30 SKSpriteNodes в кадре обычно не представляет проблемы. У меня есть игра в AppStore, которая рисует сотни SKSpriteNodes. Почему вы не загружаете свои 30 SKSpriteNodes один раз во время запуска вашего приложения и перемещаете узлы в каждом цикле обновления? И почему вы используете JavaScript для вычисления триплетов 30 (ImageNumber, xPosition, yPosition)? По крайней мере, так я это понял. – Nero

+1

Вы «создаете» эти текстуры в каждом кадре или просто «рисуете» их. Между ними существует значительная разница. Здесь недостаточно информации, чтобы помочь вам эффективно. Если вы создаете 30 изображений для каждого кадра, возможно, вам нужно подумать о пуле. Просто не совсем понятно, что вы на самом деле делаете, когда используете слова draw/create в разных точках. Возможно, добавьте код, чтобы указать, что вы на самом деле делаете. – prototypical

+0

Как сказал Нерон, рисунок 30 'SKSpriteNode' каждый кадр не является проблемой. Дьявол, скорее всего, в деталях. – prototypical

ответ

0

В вопросе все еще недостаточно информации, чтобы определить, где именно проблема, но вот несколько советов, в которых вы определенно можете улучшить свою концепцию.

При следующем обновлении я удаляю всех детей из parentNode и снова добавляю текстуры на основе новых позиций.

Я не уверен на 100%, но шансы высоки, что это одно из ваших узких мест. Это не то, как должна быть разработана игра на основе SpriteKit. Обычно один должен:

  • Добавить необходимые спрайты графа сцены, как только они должны стать видимыми
  • Перемещение объектов как-то, что, как предполагается переместить (не удалить и повторно добавить)
  • Удалить узлы, когда они должны исчезнуть ПОСТОЯННО
  • Скрыть узлы, если они только исчезают вскоре (есть флаг для этого)

Таким образом, вместо того, очищая весь граф сцены вы должны переместить свои объекты вокруг. Это не обязательно означает, что вам нужно использовать SKActions, но это рекомендуется делать, поскольку они оптимизированы для запуска анимаций, таких как перемещение материала вокруг. Вы также можете изменить атрибут position любого SKNode во время шага обновления.Возможно, этого уже достаточно, чтобы обеспечить 30 или даже 60 кадров в секунду. И, кстати, теперь всегда необходимо запустить игру со скоростью 60 кадров в секунду. Если все движется медленно, может быть достаточно 30 кадров в секунду.

Таким образом, приведенный выше код создаст текстуру один раз и добавит его в кэш, и в следующий раз, когда это потребуется, оно будет выведено из кеша. В настоящее время я не выпускаю текстуры из кеша, потому что у него небольшое количество текстур.

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

Я не хочу, чтобы добавить действия Sprite, потому что у нас уже есть игра в JavaScript, и мы не хотим, чтобы переписать для прошивки, так что мы просто хотим, чтобы добавить слой между JS и прошивкой.

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

JavaScript все еще может быть узким местом. Если вышеуказанных изменений недостаточно для достижения 30 или 60 кадров в секунду, возможно, проверьте, работает ли ваш JS достаточно быстро на iPad/iPhone. Вероятно, есть разница в скорости между запуском JS на Mac/PC и iPhone/iPad.

+0

Поддерживающие узлы не влияют на производительность. Теперь он не перерисовывает сцену при каждом вызове обновления и имеет 30 кадров в секунду. и игра выглядит хорошо на iOS8 для iPhone 5 и iPad 3, но не для iOS7. – Noura

+0

Мы использовали Ejecta, он делает то, что мы точно хотим, и производительность отличная. – Noura

+0

Я помечаю ваш ответ как принятый, потому что у него есть полезные советы разработчикам, использующим Sprite. благодаря – Noura

Смежные вопросы