有没有一种方法可以在 SpriteKit 中全局添加多个精灵?
Is there a way I can add more than one sprite in SpriteKit globally?
我正在努力解决一个问题。我的 sprite 的全局声明,以便我可以与之交互。在这个游戏中,我创建了一个名为 enemy 的本地精灵,如下所示:
func spawnEnemy() {
let enemy = SKSpriteNode(imageNamed: "as")
let yPosition = CGFloat(frame.maxY - enemy.size.height)
let getXvalue = GKRandomDistribution(lowestValue: Int(frame.minX + enemy.size.width), highestValue: Int(frame.maxX - enemy.size.width))
let xPosition = CGFloat(getXvalue.nextInt())
enemy.position = CGPoint(x: xPosition, y: yPosition)
enemy.name = "asteroid"
enemy.zPosition = 100
addChild(enemy)
let animationDuration:TimeInterval = 6
var actionArray = [SKAction]()
actionArray.append(SKAction.move(to: CGPoint(x: xPosition, y: 0), duration: animationDuration))
actionArray.append(SKAction.self.removeFromParent())
enemy.run(SKAction.sequence(actionArray))
}
我想点击敌人让它从屏幕上消失。该变量是在本地而不是全局声明的,因此 touchesBegan 函数不会 "see" 敌人。但是,当我移动语句时:
let enemy = SKSpriteNode(imageNamed: "as")
在局部声明之外并进入全局。它一直有效,直到代码试图在另一个敌人中产生并且我收到错误 "Tried to add an SKNode who already has a parent" 这是我认为 运行 确实加载的代码:
run(SKAction.repeatForever(SKAction.sequence([SKAction.run{self.spawnEnemy()
}, SKAction.wait(forDuration: 1.0)])))
每次它产生一个新的敌人时它都会崩溃并说 SKNode 已经有一个父节点,我明白这一点。但是,为了让我的游戏正常运行,我需要玩家能够触摸该敌人的单个实例并将其移除。因此我的
代码
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in:self) {
let nodesArray = self.nodes(at:location)
if nodesArray.first?.name == "asteroid" {
print("Test")
enemy.removeFromParent()
print("Test Completed")
}
}
}
现在错误提示未解决 "enemy" 的使用,因为敌人不是全球性的。我在这个问题上来回反复了很长一段时间。如果有人有任何潜在的解决方案或解决方法,我将不胜感激,并感谢您的帮助。
将你的敌人移动到他们自己的 class 并处理他们自己 class 中每个敌人的触摸。这会清理您的 GameScene 并使您的代码更有条理。您现在可以根据需要添加任意数量的敌人实例。
仅供参考,与这个问题无关,但在你开始工作后需要考虑一些事情
- 当游戏结束、关卡改变或获胜时,确保你有清除所有敌人的功能
- 你应该认真考虑回收你的对象而不是动态创建它们......更好的性能
尽量将尽可能多的代码分离到您的对象class
class enemy: SKSpriteNode {
init() {
super.init(texture: nil, color: .clear, size: CGSize.zero)
setup()
}
func setup() {
isUserInteractionEnabled = true
name = "asteroid"
zPosition = 100
let image = SKSpriteNode(imageNamed: "as")
imagine.zPosition = 1
addChild(image)
self.size = image.size
animate()
}
func animate() {
let animationDuration: TimeInterval = 6
let move = SKAction.move(to: CGPoint(x: xPosition, y: 0), duration: animationDuration)
let remover = SKAction.self.removeFromParent()
run(SKAction.sequence(move, remover))
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
removeFromParent()
}
}
class GameScene: SKScene {
override func didMove(to view: SKView) {
let sequence = SKAction.sequence([SKAction.run{ self.spawnEnemy()
}, SKAction.wait(forDuration: 1.0)])
run(SKAction.repeatForever(sequence))
}
func spawnEnemy() {
let enemy = Enemy()
let yPosition = CGFloat(frame.maxY - enemy.size.height)
let getXvalue = GKRandomDistribution(lowestValue: Int(frame.minX + enemy.size.width), highestValue: Int(frame.maxX - enemy.size.width))
let xPosition = CGFloat(getXvalue.nextInt())
enemy.position = CGPoint(x: xPosition, y: yPosition)
addChild(enemy)
}
}
我正在努力解决一个问题。我的 sprite 的全局声明,以便我可以与之交互。在这个游戏中,我创建了一个名为 enemy 的本地精灵,如下所示:
func spawnEnemy() {
let enemy = SKSpriteNode(imageNamed: "as")
let yPosition = CGFloat(frame.maxY - enemy.size.height)
let getXvalue = GKRandomDistribution(lowestValue: Int(frame.minX + enemy.size.width), highestValue: Int(frame.maxX - enemy.size.width))
let xPosition = CGFloat(getXvalue.nextInt())
enemy.position = CGPoint(x: xPosition, y: yPosition)
enemy.name = "asteroid"
enemy.zPosition = 100
addChild(enemy)
let animationDuration:TimeInterval = 6
var actionArray = [SKAction]()
actionArray.append(SKAction.move(to: CGPoint(x: xPosition, y: 0), duration: animationDuration))
actionArray.append(SKAction.self.removeFromParent())
enemy.run(SKAction.sequence(actionArray))
}
我想点击敌人让它从屏幕上消失。该变量是在本地而不是全局声明的,因此 touchesBegan 函数不会 "see" 敌人。但是,当我移动语句时:
let enemy = SKSpriteNode(imageNamed: "as")
在局部声明之外并进入全局。它一直有效,直到代码试图在另一个敌人中产生并且我收到错误 "Tried to add an SKNode who already has a parent" 这是我认为 运行 确实加载的代码:
run(SKAction.repeatForever(SKAction.sequence([SKAction.run{self.spawnEnemy()
}, SKAction.wait(forDuration: 1.0)])))
每次它产生一个新的敌人时它都会崩溃并说 SKNode 已经有一个父节点,我明白这一点。但是,为了让我的游戏正常运行,我需要玩家能够触摸该敌人的单个实例并将其移除。因此我的
代码override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in:self) {
let nodesArray = self.nodes(at:location)
if nodesArray.first?.name == "asteroid" {
print("Test")
enemy.removeFromParent()
print("Test Completed")
}
}
}
现在错误提示未解决 "enemy" 的使用,因为敌人不是全球性的。我在这个问题上来回反复了很长一段时间。如果有人有任何潜在的解决方案或解决方法,我将不胜感激,并感谢您的帮助。
将你的敌人移动到他们自己的 class 并处理他们自己 class 中每个敌人的触摸。这会清理您的 GameScene 并使您的代码更有条理。您现在可以根据需要添加任意数量的敌人实例。
仅供参考,与这个问题无关,但在你开始工作后需要考虑一些事情
- 当游戏结束、关卡改变或获胜时,确保你有清除所有敌人的功能
- 你应该认真考虑回收你的对象而不是动态创建它们......更好的性能
尽量将尽可能多的代码分离到您的对象class
class enemy: SKSpriteNode {
init() {
super.init(texture: nil, color: .clear, size: CGSize.zero)
setup()
}
func setup() {
isUserInteractionEnabled = true
name = "asteroid"
zPosition = 100
let image = SKSpriteNode(imageNamed: "as")
imagine.zPosition = 1
addChild(image)
self.size = image.size
animate()
}
func animate() {
let animationDuration: TimeInterval = 6
let move = SKAction.move(to: CGPoint(x: xPosition, y: 0), duration: animationDuration)
let remover = SKAction.self.removeFromParent()
run(SKAction.sequence(move, remover))
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
removeFromParent()
}
}
class GameScene: SKScene {
override func didMove(to view: SKView) {
let sequence = SKAction.sequence([SKAction.run{ self.spawnEnemy()
}, SKAction.wait(forDuration: 1.0)])
run(SKAction.repeatForever(sequence))
}
func spawnEnemy() {
let enemy = Enemy()
let yPosition = CGFloat(frame.maxY - enemy.size.height)
let getXvalue = GKRandomDistribution(lowestValue: Int(frame.minX + enemy.size.width), highestValue: Int(frame.maxX - enemy.size.width))
let xPosition = CGFloat(getXvalue.nextInt())
enemy.position = CGPoint(x: xPosition, y: yPosition)
addChild(enemy)
}
}