Sprite Kit:很多精灵 (1000+),带有位 Blitting
Posted
技术标签:
【中文标题】Sprite Kit:很多精灵 (1000+),带有位 Blitting【英文标题】:Sprite Kit: A Lot of sprites (1000+) with Bit Blitting 【发布时间】:2015-08-14 13:46:44 【问题描述】:我正在尝试使用 SpriteKit 创建一个场景,其中包含数千个精灵(~500 - 2000)。每个精灵只是一个 1x1 的白色像素 - 甚至不需要为它们使用纹理。
一次直接将这么多精灵添加到场景中是不可能的(或者至少我认为是这样)。在 iPhone 6 上,我最终添加了大约 200 个精灵,然后系统由于内存问题结束了添加过程,其余的精灵没有添加。
我找到了一个名为Bit Blitting 的巧妙解决方案,其中所有精灵都添加到一个节点,然后使用textureFromNode:
方法将其“转换”为纹理,然后从该纹理创建一个单独的精灵,它将最终被添加到屏幕上。它工作得很好,我可以一次创建超过 10 000 个精灵,而且 fps 很好。
我的问题是之后我无法移动这些精灵(= 更改位置)。无论我做什么,质地总是保持不变。我错过了什么?
我的代码:
override func didMoveToView(view: SKView)
self.generateRandomSprites()
func generateRandomSprites()
let texture = SKTexture(imageNamed: "whitePixel")
self.canvasNode = SKNode()
log("started generating all sprites")
for var i = 0;i < 1000;i++
let width = self.scene!.frame.size.width
let height = self.scene!.frame.size.height
let x: CGFloat = CGFloat(arc4random_uniform(UInt32(width)))
let y: CGFloat = CGFloat(arc4random_uniform(UInt32(height)))
let cell = SKSpriteNode(texture: texture)
cell.position = CGPointMake(x, y)
self.arrCells.append(cell)
self.canvasNode.addChild(cell)
self.canvasTexture = self.view!.textureFromNode(self.canvasNode)
self.canvasSprite = SKSpriteNode(texture: self.canvasTexture, size: self.frame.size)
self.canvasSprite.anchorPoint = ccp(0,0)
self.addChild(self.canvasSprite)
override func update(currentTime: CFTimeInterval)
for oneCell in self.arrCells
oneCell.position = CGPointMake(oneCell.position.x + 1, oneCell.position.y)
self.canvasTexture = self.view!.textureFromNode(self.canvasNode)
self.canvasSprite.texture = self.canvasTexture
来自应用程序的屏幕截图(这是静态的,没有任何反应):
【问题讨论】:
你的屏幕截图是黑色的,你说你的纹理是白色的。你怎么知道你的精灵在屏幕的可见侧。我在你的屏幕截图中看到的是黑色 截图中有白点...只是1px所以必须放大/有好的分辨率...点击图片就可以看到...跨度> 你是对的,点击图片后,我可以看到它们。 节点被写入纹理 - 图像。在重新渲染图像之前,移动节点将不起作用。您必须再次调用 generateRandomSprites,但不要再次添加孩子。 @Chris 不正确!从问题中阅读文章。 ...您是否尝试过循环使用self.canvasNode.children
而不是您的阵列?我无法测试它atm。所以这只是一个建议。
【参考方案1】:
这不是答案,而是我尝试过的东西的集合。
我真的很好奇那个代码。我试过了,但没有用。我将更新方法更改为仅将点放在随机位置并且它可以工作:
所以我有一个问题。为什么代码不能从它的当前位置更新,或者这是一个红鲱鱼?
override func update(currentTime: CFTimeInterval)
let width = self.scene!.frame.size.width
let height = self.scene!.frame.size.height
for oneCell in self.canvasNode.children as! [SKSpriteNode]
let x: CGFloat = CGFloat(arc4random_uniform(UInt32(width)))
let y: CGFloat = CGFloat(arc4random_uniform(UInt32(height)))
oneCell.position = CGPointMake(x, y)
self.canvasTexture = self.view!.textureFromNode(self.canvasNode)
self.canvasSprite.texture = self.canvasTexture
好的,我一直在玩这个,这很有效,只是获取一个随机值并将其添加到位置......
override func update(currentTime: CFTimeInterval)
let width = self.scene!.frame.size.width
let height = self.scene!.frame.size.height
for oneCell in self.canvasNode.children as! [SKSpriteNode]
let x2: CGFloat = CGFloat(arc4random_uniform(UInt32(10)))
let y2: CGFloat = CGFloat(arc4random_uniform(UInt32(10)))
let x:CGFloat = oneCell.position.x - x2
let y:CGFloat = oneCell.position.y - y2
let point = CGPointMake(x, y)
oneCell.position = point
self.canvasTexture = self.view!.textureFromNode(self.canvasNode)
self.canvasSprite.texture = self.canvasTexture
现在我认为这与编译器有关:
override func update(currentTime: CFTimeInterval)
let width = self.scene!.frame.size.width
let height = self.scene!.frame.size.height
var x3:CGFloat = 10.0
var y3:CGFloat = 10.0
for oneCell in self.canvasNode.children as! [SKSpriteNode]
let x:CGFloat = oneCell.position.x - x3
let y:CGFloat = oneCell.position.y - y3
let point = CGPointMake(x, y)
oneCell.position = point
x3 += 0.01
self.canvasTexture = self.view!.textureFromNode(self.canvasNode)
self.canvasSprite.texture = self.canvasTexture
更多调查,有趣,如果您使用值 1.3 并运行代码,您可以看到点移动一次。 (http://llvm.org/docs/LangRef.html#simple-constants)
override func update(currentTime: CFTimeInterval)
let width = self.scene!.frame.size.width
let height = self.scene!.frame.size.height
for oneCell in self.canvasNode.children as! [SKSpriteNode]
let x:CGFloat = oneCell.position.x - 1.3
let y:CGFloat = oneCell.position.y - 1.3
let point = CGPointMake(x, y)
oneCell.position = point
self.canvasTexture = self.view!.textureFromNode(self.canvasNode)
self.canvasSprite.texture = self.canvasTexture
像 50.3333333333 这样的数字显示出明显的抖动,但随后似乎停止了。
【讨论】:
感谢您的回答,您完全正确! ......我得到了和你一样的结果,尝试了所有的选择......这真的很奇怪。就像...真的很奇怪:) 我会花一些时间在上面,如果我想出什么办法会告诉你... 很遗憾,没有。两周前我尝试了几件事(主要基于您的观察),但没有取得任何值得一提的进展。我完全同意这与编译器有关,因为它真的很奇怪,我无法以任何其他方式解释它......如果我将来发现一些东西,我会告诉你(这是一个附带项目,我只是有时在研究它)。【参考方案2】:老实说,我认为您建议的方法效果不佳,而且看起来真的很复杂,无缘无故。例如,使用 SpriteKit,您可以只创建一个具有背景纹理颜色的节点并将其设置为 1x1,而无需执行任何 blit 操作。像这样:
SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor]
size:CGSizeMake(1,1)];
【讨论】:
以上是关于Sprite Kit:很多精灵 (1000+),带有位 Blitting的主要内容,如果未能解决你的问题,请参考以下文章