我正在尝试在Swift中使用Spritekit编写游戏。在这种情况下,目标是逃脱他的角色即将到来的矩形。现在,我使用ScheduledTimerWithTimeInterval()方法(或据我所相信的addRechteck()函数)犯了一个错误,因此游戏在出现前两个矩形后崩溃。错误在哪里?
import SpriteKit
class PlayScene: SKScene {
var timer = Timer()
let figur = SKSpriteNode(imageNamed: "Punkt.jpg")
var rechteckRechts = SKSpriteNode(imageNamed: "Rechteck.gif")
var rechteckLinks = SKSpriteNode(imageNamed: "Rechteck.gif")
func scheduledTimerWithTimeInterval(){
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.addRechteck), userInfo: nil, repeats: true)
}
@objc func addRechteck(){
let groesse = arc4random_uniform(5)+1
print(groesse)
switch groesse {
case 1:
rechteckLinks.xScale = 0.5
rechteckRechts.xScale = 1.5
case 2:
rechteckLinks.xScale = 1.5
rechteckRechts.xScale = 0.5
case 3:
rechteckLinks.xScale = 1
rechteckRechts.xScale = 1
case 4:
rechteckLinks.xScale = 1.25
rechteckRechts.xScale = 0.75
case 5:
rechteckLinks.xScale = 0.75
rechteckRechts.xScale = 1.25
default:
print("Fehler in der Wahrscheinlichkeit!!!")
}
rechteckRechts.position = CGPoint(x: frame.minX + (rechteckRechts.size.width / 2), y: frame.maxY / 1.25)
rechteckLinks.position = CGPoint(x: frame.maxX - (rechteckLinks.size.width / 2), y: frame.maxY / 1.25)
let moveDown = SKAction.moveBy(x: 0, y: -5000, duration: 20.0)
rechteckLinks.run(moveDown)
rechteckRechts.run(moveDown)
self.addChild(rechteckRechts)
self.addChild(rechteckLinks)
}
override func didMove(to view: SKView) {
figur.xScale = 0.4
figur.yScale = 0.4
figur.position = CGPoint(x: frame.midX, y: frame.maxY / 4)
self.backgroundColor = SKColor.white
self.addChild(figur)
scheduledTimerWithTimeInterval()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ){
let location = touch.location(in: self)
if figur.contains(location){
figur.position = location
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ) {
let location = touch.location(in: self)
if figur.contains(location){
figur.position = location
}
}
}
}
错误消息:
2018-08-02 11:48:50.636942+0200 Blocker[34730:2152598] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: name:'(null)' texture:[ 'Rechteck.gif' (320 x 206)] position:{200, 1067.199951171875} scale:{1.25, 1.00} size:{400, 206} anchor:{0.5, 0.5} rotation:0.00' *** First throw call stack: ( 0 CoreFoundation 0x000000010e9f41cb __exceptionPreprocess + 171 1 libobjc.A.dylib 0x000000010e356f41 objc_exception_throw + 48 2 CoreFoundation 0x000000010ea68b95 +[NSException raise:format:] + 197 3 SpriteKit 0x000000010f5c2550 -[SKNode insertChild:atIndex:] + 162 4 SpriteKit 0x000000010f5c248d -[SKNode addChild:] + 68 5 Blocker 0x000000010da3bd87 _T07Blocker9PlaySceneC11addRechteckyyF + 2919 6 Blocker 0x000000010da3be64 _T07Blocker9PlaySceneC11addRechteckyyFTo + 36 7 Foundation 0x000000010ddc21ee __NSFireTimer + 83 8 CoreFoundation 0x000000010e984374 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 9 CoreFoundation 0x000000010e984032 __CFRunLoopDoTimer + 1026 10 CoreFoundation 0x000000010e983bea __CFRunLoopDoTimers + 266 11 CoreFoundation 0x000000010e97b604 __CFRunLoopRun + 2308 12 CoreFoundation 0x000000010e97aa89 CFRunLoopRunSpecific + 409 13 GraphicsServices 0x000000011754b9c6 GSEventRunModal + 62 14 UIKit 0x000000010f7b0d30 UIApplicationMain + 159 15 Blocker 0x000000010da3e347 main + 55 16 libdyld.dylib 0x000000011383fd81 start + 1 17 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException
答案 0 :(得分:0)
您已经设置了一个计时器,该计时器重复调用方法addRechteck
。第一次调用addRechteck
时,会添加两个SKSpriteNodes
:
self.addChild(rechteckRechts)
self.addChild(rechteckLinks)
然后,再次调用此方法时,它将尝试第二次添加这两个SKSpriteNodes
。这会导致错误:
尝试添加已经具有父级的SKNode
基本上,如果SKSpriteNode
已经有一个父级,则不能在其上调用addChild
。您可能要检查SKSpriteNode
是否已经有一个父母,如果是,则不添加它。
答案 1 :(得分:0)
由于使用计时器多次调用了函数addRechteck,因此您试图将rechtechRechts
和rechteckLinks
添加到场景中。重新格式化该函数,如下所示:
@objc func addRechteck(){
// Added these variables here
var rechteckRechts = SKSpriteNode(imageNamed: "Rechteck.gif")
var rechteckLinks = SKSpriteNode(imageNamed: "Rechteck.gif")
let groesse = arc4random_uniform(5)+1
print(groesse)
switch groesse {
case 1:
rechteckLinks.xScale = 0.5
rechteckRechts.xScale = 1.5
case 2:
rechteckLinks.xScale = 1.5
rechteckRechts.xScale = 0.5
case 3:
rechteckLinks.xScale = 1
rechteckRechts.xScale = 1
case 4:
rechteckLinks.xScale = 1.25
rechteckRechts.xScale = 0.75
case 5:
rechteckLinks.xScale = 0.75
rechteckRechts.xScale = 1.25
default:
print("Fehler in der Wahrscheinlichkeit!!!")
}
rechteckRechts.position = CGPoint(x: frame.minX + (rechteckRechts.size.width / 2), y: frame.maxY / 1.25)
rechteckLinks.position = CGPoint(x: frame.maxX - (rechteckLinks.size.width / 2), y: frame.maxY / 1.25)
let moveDown = SKAction.moveBy(x: 0, y: -5000, duration: 20.0)
rechteckLinks.run(moveDown)
rechteckRechts.run(moveDown)
self.addChild(rechteckRechts)
self.addChild(rechteckLinks)
}
这样,您每次都添加新的。另外,删除
var rechteckRechts = SKSpriteNode(imageNamed: "Rechteck.gif")
var rechteckLinks = SKSpriteNode(imageNamed: "Rechteck.gif")
从文件顶部开始,因为它们已添加到函数中。我也强烈建议您使用SKAction
而不是Timer
,因为它可以与sprite-kit一起使用。我将用以下代码替换您的计时器代码:
let wait1 = SKAction.wait(forDuration: 1)
let timer = SKAction.repeatForever(SKAction.sequence([wait1, SKAction.run {
addRechteck()
}]))
self.run(timer, withKey: "addRect")