所以我创造了一个游戏,你可以点击它让它们跳起来。你得到每个点击点。当我达到10分时,为什么我的精灵会开始闪烁。我认为它与update(timeInterval)
方法有关。这可能是一个错误或错误的编码。
import SpriteKit
class GameScene: SKScene {
let backgroundNode = SKSpriteNode(imageNamed: "redbackground")
override func didMoveToView(view: SKView) {
backgroundNode.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
self.addChild(backgroundNode)
//=======Ball 1=======//
let ball = Ball()
ball.position = CGPoint(x:self.frame.midX, y:440)
addChild(ball)
ball.physicsBody = SKPhysicsBody(circleOfRadius: 90)
ball.physicsBody?.dynamic = true
ball.physicsBody?.allowsRotation = false
ball.physicsBody?.friction = 0
ball.physicsBody?.angularDamping = 0
ball.physicsBody?.linearDamping = 0
ball.physicsBody?.usesPreciseCollisionDetection = true
ball.physicsBody!.categoryBitMask = 0
}
class Ball: SKSpriteNode {
init() {
let texture = SKTexture(imageNamed: "Ball")
super.init(texture: texture, color: .clearColor(), size: texture.size())
userInteractionEnabled = true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let scene = self.scene as! GameScene
scene.score += 1
physicsBody?.velocity = CGVectorMake(0, 100)
physicsBody?.applyImpulse(CGVectorMake(0, 900))
}
override func update(currentTime: CFTimeInterval) {
if (score >= 10){
self.backgroundNode.texture = SKTexture(imageNamed: "orangebackground")
}
if (score >= 20){
self.backgroundNode.texture = SKTexture(imageNamed: "yellowbackground")
}
if (score >= 30) {
self.backgroundNode.texture = SKTexture(imageNamed: "greenbackground")
}
}
看到这个,看看我的意思。(点击或点击链接)
This shows the sprites flashing at 10 points
提前感谢,乔丹
答案 0 :(得分:4)
您可以向update
添加属性观察器,而不是更改score
中的背景图像,只有在分数达到特定值时才会更改背景。例如:
let backgroundNames = ["orangebackground","yellowbackground","greenbackground"]
// The didSet observer is called when the score is updated
var score:Int = 0 {
didSet {
// Check if score is divisible by 10
if score % 10 == 0 {
// Determine the array index
let index = score / 10
// Wrap to avoid index out of range
let name = backgroundNames[index % backgroundNames.count]
print (name)
}
}
}
也就是说,闪烁可能是由渲染节点的顺序引起的。来自Apple的文档,
...用[ignoresSiblingOrder = true],你无法预测 渲染共享相同高度的节点的顺序。渲染 每次渲染新帧时,顺序可能会改变。
您可以通过将背景的zPosition
设置为负值来解决此问题,例如
self.backgroundNode.zPosition = -100
因此总是在游戏节点之前绘制背景。
答案 1 :(得分:3)
因为这个而闪烁
override func update(currentTime: CFTimeInterval) {
if (score >= 10){
self.backgroundNode.texture = SKTexture(imageNamed: "orangebackground")
}
if (score >= 20){
self.backgroundNode.texture = SKTexture(imageNamed: "yellowbackground")
}
if (score >= 30) {
self.backgroundNode.texture = SKTexture(imageNamed: "greenbackground")
}
}
在更新方法中,当分数变为>= 10
时,您正在更新纹理 EVERY FRAME 。
这绝对是错误的。
如果您想更新纹理,只需在需要更改纹理时(例如,当分数从9到10,或从19到20或从29到30时)。
但是当纹理从10变为11时保持10时没有任何意义,因为你将用另一个相同的纹理更新纹理。
只需创建shouldUpdateTexture: Bool = false
属性,然后每次更新score
时,如果score
从9到10或19到20或29到30,那么转{{1}转到shouldUpdateTexture
。
最后在true
方法内检查update
是否为真,在这种情况下将其设置回shouldUpdateTexture
并更新纹理。
false
那就是它。
正如 @ Knight0fDragon 指出的那样,将我放入class GameScene: SKScene {
private var score = 0 {
didSet {
shouldUpdateTexture = oldValue < 10 && score >= 10 || oldValue < 20 && score >= 20 || oldValue < 30 && score >= 30
}
}
private var shouldUpdateTexture = false
private var backgroundNode = SKSpriteNode(imageNamed: "defaultbackground")
override func update(currentTime: CFTimeInterval) {
if shouldUpdateTexture {
shouldUpdateTexture = false
switch score {
case 10...19: backgroundNode.texture = SKTexture(imageNamed: "orangebackground")
case 20...29: backgroundNode.texture = SKTexture(imageNamed: "yellowbackground")
case 30...Int.max: backgroundNode.texture = SKTexture(imageNamed: "yellowbackground")
default: break
}
}
}
}
方法的代码移动到update
可能会更快。
优点:这样您就不需要每帧都执行布尔等式检查
缺点:如果您在同一帧内多次更改
didSet
值,则会执行多次纹理加载。
答案 2 :(得分:2)
只是一种替代方案,允许在分数中发生多项更改,而不会使用不必要的代码充斥更新功能
class GameScene: SKScene {
private var score = 0 {
didSet {
///if a change in the 10s happen, then update texture
if(score/10 > oldValue/10)
{
switch score{
case 10...19: backgroundNode.texture = SKTexture(imageNamed: "orangebackground")
case 20...29: backgroundNode.texture = SKTexture(imageNamed: "yellowbackground")
case 30...Int.max: backgroundNode.texture = SKTexture(imageNamed: "greenbackground")
default: break
}
}
}
}
private var shouldUpdateTexture = false
private var backgroundNode = SKSpriteNode(imageNamed: "defaultbackground")
}
然后进行优化:(不是真的需要,但可能有助于你如何思考代码)
class GameScene: SKScene {
let bgTextures = [SKTexture(imageNamed: "orangebackground"),SKTexture(imageNamed: "yellowbackground"),SKTexture(imageNamed: "greenbackground")]
private var score = 0 {
didSet {
///if a change in the 10s happen, then update texture
let bgIndex = score / 10
if((bgIndex > oldValue/10) && score < bgTextures.count * 10)
{
backgroundNode.texture = bgTextures[bgIndex - 1]
}
else
{
backgroundNode.texture = bgTextures[bgTextures.count - 1]
}
}
}
private var shouldUpdateTexture = false
private var backgroundNode = SKSpriteNode(imageNamed: "defaultbackground")
}