我正在开发基于玩家背景的简单游戏。在左右角有一些按钮,可以将字符向左或向右移动。我已经实现了这一点(角色正在移动,背后的左侧是背景),但是添加另一个圆圈fps的速度非常快。对此有什么解决方案吗?
import SpriteKit
class GameScene: SKScene {
var playerDot:PlayerDot = PlayerDot(imageNamed:"player")
var isTurningLeft:Bool = false
var isTurningRight:Bool = false
var lastLocation:CGPoint = CGPoint()
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let myLabel = SKLabelNode(fontNamed:"Helvetica")
myLabel.name = "left"
myLabel.text = "Left"
myLabel.fontSize = 30
myLabel.horizontalAlignmentMode = .Left
myLabel.position = CGPoint(x:CGRectGetMinX(self.frame), y:CGRectGetMinY(self.frame))
self.addChild(myLabel)
let myLabel2 = SKLabelNode(fontNamed:"Helvetica")
myLabel2.name = "right"
myLabel2.text = "Right"
myLabel2.fontSize = 30
myLabel2.horizontalAlignmentMode = .Right
myLabel2.position = CGPoint(x:CGRectGetMaxX(self.frame), y:CGRectGetMinY(self.frame))
self.addChild(myLabel2)
playerDot.position = CGPoint(x:CGRectGetMaxX(self.frame)/2, y:CGRectGetMinY(self.frame))
self.addChild(playerDot)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
if let theName = self.nodeAtPoint(location).name {
if theName == "left" {
isTurningLeft = true
isTurningRight = false
}
else if theName == "right" {
isTurningRight = true
isTurningLeft = false
}
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
if let theName = self.nodeAtPoint(location).name {
if theName == "left" {
isTurningLeft = false
}
else if theName == "right" {
isTurningRight = false
}
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
if let theName = self.nodeAtPoint(location).name {
if theName == "left" {
isTurningLeft = false
}
else if theName == "right" {
isTurningRight = false
}
}
}
}
override func update(currentTime: CFTimeInterval) {
if(isTurningLeft){
playerDot.increaseAngle()
} else if (isTurningRight){
playerDot.decreaseAngle()
}
//calculates new character position based on angle of movement changed
playerDot.updatePosition()
drawCircle()
}
func drawCircle(){
if(distanceFromCGPoints(lastLocation, b: playerDot.position)>2){
let circle = SKShapeNode(circleOfRadius: 10 )
circle.position = playerDot.position
circle.fillColor = SKColor.orangeColor()
circle.strokeColor = SKColor.orangeColor()
self.addChild(circle)
lastLocation = playerDot.position
}
}
func distanceFromCGPoints(a:CGPoint,b:CGPoint)->CGFloat{
return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
}
编辑: 将SKShapeNode的drawCircle替换为SKSpriteNote
func drawCircle(){
if(distanceFromCGPoints(lastLocation, b: playerDot.position)>2){
let playerDot2 = SKSpriteNode(imageNamed:"player")
playerDot2.position = playerDot.position
self.addChild(playerDot2)
lastLocation = playerDot.position
}
}
答案 0 :(得分:0)
如果您的帧速率下降,那么代码的某些部分会降低执行速度。您需要优化代码。使用仪器(Time Profiler)快速找出导致问题的线路/功能。如果您在阅读之前从未使用它并使用它几次以获得要点,那么我建议您观看WWDC视频Profiling In-Depth
答案 1 :(得分:0)
根据您的编辑(切换到SKSpriteNode
),您可以这样做:
将纹理声明为场景的属性。这样,您可以加载一次并在以后重复使用它:
let yourTexture = SKTextureAtlas(named: "yourAtlas").textureNamed("yourTexture")
然后在您的drawCircle
方法中:
func drawCircle(){
if(distanceFromCGPoints(lastLocation, b: playerDot.position)>2){
let playerDot2 = SKSpriteNode(texture: yourTexture)
playerDot2.position = playerDot.position
self.addChild(playerDot2)
lastLocation = playerDot.position
}
}
通过这种方式(使用SKSpriteNode
代替SKShapeNode
),您减少了渲染所有这些圈子所需的绘制调用次数。另外,因为您重复使用相同的纹理,而不是每次使用imageNamed
分配它时,您已经大大减少了应用程序消耗的内存量。现在,如果批量渲染这些节点,SpriteKit可以渲染数百个节点@ 60 fps。在fps开始下降之前仍有一个限制。这取决于设备。