Я новичок в SpriteKit и пытаюсь смоделировать популяцию из 1000 движущихся особей, каждый из которых представлен простым кругом. У меня ужасная частота кадров (около 6/7 кадров в секунду), поэтому я уменьшил до 100 и достиг 35 кадров в секунду ...
Мои узлы самые простые в мире, я использую систему компонентов объектов из GameplayKit , но ничего особенного.
Так, что я могу сделать, чтобы улучшить и достигнуть 60 кадров в секунду?
Сначала моя сущность формы, позже в процессе меняются цвет и заполнение для некоторых людей, но здесь есть только простой круговой узел:
class ShapeComponent : GKComponent {
let node = SKShapeNode(ellipseOf: CGSize(width: 10, height: 10))
override func didAddToEntity() {
node.entity = entity
}
override func willRemoveFromEntity() {
node.entity = nil
}
}
Тогда мой компонент движения, имеющий только скорость и угол. Я даже сохранил синус и косинус для ограничения вычислений:
class MovementComponent : GKComponent {
var speed : CGFloat = 25
var direction : CGFloat = .random(in: 0...(2 * .pi)) {
didSet { updateSinCos() }
}
var sinDir : CGFloat = 0
var cosDir : CGFloat = 0
override init() {
super.init()
updateSinCos()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var shapeComponent: ShapeComponent {
guard let shapeComponent = entity?.component(ofType: ShapeComponent.self)
else { fatalError("A MovementComponent's entity must have a ShapeComponent") }
return shapeComponent
}
func updateSinCos() {
sinDir = sin(direction)
cosDir = cos(direction)
}
override func update(deltaTime: TimeInterval) {
super.update(deltaTime: deltaTime)
// Declare local versions of computed properties so we don't compute them multiple times.
let delta = speed * CGFloat(deltaTime)
let vector = CGVector(dx: delta * sinDir, dy: delta * cosDir)
let node = shapeComponent.node
let currentPosition = node.position
node.position = CGPoint(x: currentPosition.x + vector.dx, y: currentPosition.y + vector.dy)
}
}
И, наконец, моя сущность с компонентами движения и формы:
class IndividualEntity : GKEntity {
var shapeComponent: ShapeComponent {
guard let shapeComponent = component(ofType: ShapeComponent.self)
else { fatalError("A IndividualEntity must have a ShapeComponent") }
return shapeComponent
}
var movementComponent: MovementComponent {
guard let movementComponent = component(ofType: MovementComponent.self)
else { fatalError("A IndividualEntity must have a MovementComponent") }
return movementComponent
}
override init() {
super.init()
addComponent(ShapeComponent())
addComponent(MovementComponent())
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
В моей сцене:
func setUpScene() {
for _ in 1...100 {
let position = CGPoint(x: .random(in: 0..<size.width) - 0.5*size.width, y: .random(in: 0..<size.height) - 0.5*size.height)
addIndividual(at: position)
}
}
var componentSystem = GKComponentSystem(componentClass: MovementComponent.self)
var individuals = [IndividualEntity]()
func addIndividual(at pos: CGPoint) {
let individual = IndividualEntity()
individual.shapeComponent.node.position = pos
addChild(individual.shapeComponent.node)
componentSystem.addComponent(foundIn: individual)
individuals.append(individual)
}
var lastUpdateTimeInterval: TimeInterval = 0
let maximumUpdateDeltaTime: TimeInterval = 1.0 / 60.0
override func update(_ currentTime: TimeInterval) {
guard view != nil else { return }
var deltaTime = currentTime - lastUpdateTimeInterval
deltaTime = deltaTime > maximumUpdateDeltaTime ? maximumUpdateDeltaTime : deltaTime
lastUpdateTimeInterval = currentTime
componentSystem.update(deltaTime: deltaTime)
}
Так что, если кто-то может помочь мне с этой проблемой ... Я просто хочу, чтобы эти круги блуждали, а потом реагировали на столкновения, меняя направление и цвет.
Заранее спасибо.