我正在学习Swift,我正在跟随我工作过的另一个项目。但是,我收到了这个错误:
我收到错误:
Thread 1: Fatal error: Index out of range
我的所有代码:
import SpriteKit
import GameplayKit
class GameScene: SKScene {
var scoreLabel : SKLabelNode?
var player : SKSpriteNode?
var track : Int = 0
var trackArray : [SKSpriteNode]? = [SKSpriteNode]()
var ballDirection = Int(arc4random_uniform(2))
var velocityArray = [Int]()
var playerVelocity : Int = GKRandomSource.sharedRandom().nextInt(upperBound: 100)
var currentScore : Int = 0 {
didSet {
self.scoreLabel?.text = "SCORE: \(self.currentScore)"
}
}
func createHUD() {
scoreLabel = self.childNode(withName: "score") as? SKLabelNode
currentScore = 0
}
//I think the problem is coming from this function, however I more-or-less copied it from a tutorial project that works so I don't know what the problem is.
func setupTracks() {
for i in {
if let track = self.childNode(withName: "\(i)") as? SKSpriteNode {
trackArray?.append(track)
print(track)
}
}
}
func createBall() {
player = SKSpriteNode(imageNamed: "ball1")
player?.physicsBody = SKPhysicsBody(circleOfRadius: player!.size.width / 2)
player?.physicsBody?.linearDamping = 0
//This line throws the error
let ballPosition = trackArray?[track].position
print(track)
player?.position = CGPoint(x: (ballPosition?.x)!, y: (ballPosition?.y)!)
player?.position.x = (ballPosition!.x)
player?.position.y = (ballPosition!.y)
self.addChild(player!)
}
override func didMove(to view: SKView) {
createHUD()
createBall()
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
我有8个Color Sprite对象,我通过GameScene.sks输入,每个对象名为0 - 9,
我认为它正在寻找尚未分配的数组中的值?但我有一部分(我认为)正在分配这个价值。它也适用于其他项目,所以我很迷失。
答案 0 :(得分:0)
如果没有上下文,有些内容对我没有任何意义,但基于我可以推断的情况,似乎更好的解决方案是使用单个字典来访问SKSpriteNode
以及方向和速度。要实现这一点,您可以创建一个自定义对象,或者只使用一个简单的元组。
初始化字典并用对象填充后,您可以访问字典中的单个值,以获取createEnemy
函数所需的所有数据。它可能看起来像这样:
var tracks = [Int : (node: SKSpriteNode, direction: CGFloat, velocity: CGFloat)]()
func setupTrack() {
for i in 0 ... 9 {
if let track = self.childNode(withName: "\(i)") as? SKSpriteNode {
//Get direction and velocity here, if initial value is known
//Setting to 0 for now
tracks[i] = (node: track, direction: 0, velocity: 0)
}
}
}
func createEnemy(forTrack track: Int) -> SKShapeNode? {
guard let thisTrack = tracks[track] else { return nil }
let enemySprite = SKShapeNode()
enemySprite.name = "ENEMY"
enemySprite.path = CGPath(roundedRect: CGRect(x: 0, y: -10, width: 20, height: 20), cornerWidth: 10, cornerHeight: 10, transform: nil)
let enemyPosition = thisTrack.node.position
let left = thisTrack.direction
enemySprite.position.x = left ? -50 : self.size.height + 50
enemySprite.position.y = enemyPosition.y
enemySprite.physicsBody?.velocity = left ? CGVector(dx: thisTrack.velocity, dy: 0) : CGVector(dx: 0, dy: -thisTrack.velocity)
return enemySprite
}
这将阻止您越过阵列的界限。请注意:由于您循环遍历硬编码的0 ... 9范围,但您可选将项目附加到Array
(如果您的if let track
失败)您无法保证名称为“7”的“track”项对应于数组中的第7个索引。这是Dictionary
更安全的另一个原因。此外,您似乎正在维护3个独立的数组(track,directionArray和velocityArray),由于我刚才描述的原因,它似乎容易出错。