gpt4 book ai didi

ios - 当我只创建一个时,为什么会有多个 SKSpriteNode 和 SKAudioNode 对象?

转载 作者:行者123 更新时间:2023-11-28 13:40:34 25 4
gpt4 key购买 nike

我创建了一个 SKSpriteNode 对象,但是创建了多个对象,显示为它们的字符串。来自 SKAudioNode 对象的声音也被复制多次以产生回响效果。

这是下面的代码。当我在 didBegin 回调方法中添加代码以将 physicsBody 对象的固定属性设置为 true 时,我注意到它这样做了。

这是截图。注意有多个爆炸 SKSpriteNode 对象。我只为爆炸创建了一个 SKSpriteNode 对象。

multiple car explosions

我怀疑我可以更改某处的设置以禁用此效果。

import UIKit
import SpriteKit

class GameScene: SKScene {

let player = SKSpriteNode(imageNamed: "player")
var moveRate: CGFloat!

override func didMove(to view: SKView) {

physicsWorld.contactDelegate = self

if UIDevice.current.userInterfaceIdiom == .phone {
moveRate = 5
} else {
moveRate = 15
}

player.physicsBody = SKPhysicsBody(rectangleOf: player.size)
player.physicsBody?.isDynamic = true
player.physicsBody?.affectedByGravity = false
player.physicsBody?.categoryBitMask = 0b00001
// player.physicsBody?.collisionBitMask = 0b00001
player.physicsBody?.contactTestBitMask = 0b00001

player.position = CGPoint(x: 20 + player.size.width/2, y: view.frame.height / 2)

addChild(player)

let carEngineStart = SKAudioNode(fileNamed: "car_engine_running")

addChild(carEngineStart)

run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(addCompetitor),
SKAction.wait(forDuration: 4)
])
))

}

override func update(_ currentTime: TimeInterval) {

let internalRollSign = TrialSpriteKit.sign(internalRoll)

switch internalRollSign {
case .zero:
break
case .positive:
if player.position.y < self.size.height {
player.position.y += moveRate
}
case .negative:
if player.position.y > 0 {
player.position.y -= moveRate
}
}

}

enum Car: String, CaseIterable {

case blue = "blue"
case green = "green"
case orange = "orange"
case purple = "purple"
case utili = "utili"
case white = "white"
case yellow = "yellow"

static func random<G: RandomNumberGenerator>(using generator: inout G) -> Car {
return Car.allCases.randomElement(using: &generator)!
}

static func random() -> Car {
var g = SystemRandomNumberGenerator()
return Car.random(using: &g)
}

}

func random() -> CGFloat {
return CGFloat(Float(arc4random()) / /* 0xFFFFFFFF */ 4294967296)
}

func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}

func addCompetitor() {

// Create sprite
let carString = Car.random().rawValue
let car = SKSpriteNode(imageNamed: carString)

car.physicsBody = SKPhysicsBody(rectangleOf: car.size) // 1
car.physicsBody?.isDynamic = true
car.physicsBody?.affectedByGravity = false
// car.physicsBody?.categoryBitMask = 0b00001
car.physicsBody?.collisionBitMask = 0b00001
car.physicsBody?.contactTestBitMask = 0b00001

// Determine where to spawn the car along the Y axis
let actualY = random(min: car.size.height/2, max: size.height - car.size.height/2)

// Position the car slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
car.position = CGPoint(x: size.width + car.size.width/2, y: actualY)

// Add the car to the scene
addChild(car)

// Determine speed of the car
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))

// Create the actions
let actionMove = SKAction.move(to: CGPoint(x: -car.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
car.run(SKAction.sequence([actionMove, actionMoveDone]))

}

}

extension GameScene: SKPhysicsContactDelegate {

func didBegin(_ contact: SKPhysicsContact) {

contact.bodyA.pinned = true
player.physicsBody?.pinned = true

let explosion = SKSpriteNode(imageNamed: "explosion")

explosion.position = contact.contactPoint

addChild(explosion)

run(
SKAction.sequence(
[
SKAction.playSoundFileNamed("car_explosion", waitForCompletion: true),
SKAction.run({
explosion.removeFromParent()
contact.bodyB.node?.removeFromParent()
}),
SKAction.wait(forDuration: 1),
SKAction.run({
self.player.zRotation = 0
self.player.position = CGPoint(x: 20 + self.player.size.width/2, y: self.view!.frame.height / 2)
self.player.physicsBody?.pinned = false
})
]
)
)

}

}

最佳答案

您的问题中有多个节点的原因。

I noticed it doing this when I added the code to set the pinned properties of the physicsBody objects to true in the didBegin callback method.

根据 SpriteKit 文档,当您将 pinned 属性设置为 true 并且父节点具有物理实体时,这两个实体将被视为通过销接头连接。

因为两个物体是相连的,即使没有碰撞,也会重复接触,导致重复调用 didBegin 函数。每次调用 didBegin 都会创建一个新的 Sprite 节点。您的游戏调用 didBegin 的次数比您预期的要多,因此您最终得到的 Sprite 节点比您预期的要多。

一般的解决方案是只有在发生碰撞时才创建爆炸 Sprite 节点,并且每次碰撞只创建一次 Sprite 节点。

关于ios - 当我只创建一个时,为什么会有多个 SKSpriteNode 和 SKAudioNode 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56089098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com