Ios PhysicsBody使用SpriteKit和Swift时为零
我正在构建一个SpriteKit游戏,我正在从多维数组加载一个关卡。loadlevel函数第一次起作用。如果我在Ios PhysicsBody使用SpriteKit和Swift时为零,ios,swift,sprite-kit,skspritenode,Ios,Swift,Sprite Kit,Skspritenode,我正在构建一个SpriteKit游戏,我正在从多维数组加载一个关卡。loadlevel函数第一次起作用。如果我在physicsBody赋值上方对physicsBody执行println操作,则会失败(在physicBody初始化之后)。当我第二次运行load level时,用removeChildrenInArray删除所有平铺时,它会抛出一个错误,说致命错误:在展开可选的时意外地发现了nil,并指向下面的println正下方的行。而println表示physicsBody为nil。在我看来,一
physicsBody
赋值上方对physicsBody
执行println
操作,则会失败(在physicBody初始化之后)。当我第二次运行load level时,用removeChildrenInArray
删除所有平铺时,它会抛出一个错误,说致命错误:在展开可选的时意外地发现了nil,并指向下面的println
正下方的行。而println
表示physicsBody
为nil
。在我看来,一个新初始化的PhysicsBody
没有理由是nil
。println
打印physicsBody nil
。我不知道为什么physicsBody
会是nil
。我只是试图通过删除所有块节点并根据标高贴图在原始位置添加新节点来重置标高
func loadLevel() {
var levels = Levels().data
var frameSize = view.frame.size
var thisLevel = levels[currentLevel]
println("running load level")
for (rowIndex,row) in enumerate(thisLevel) {
for (colIndex,col) in enumerate(row) {
if col == 4 {
continue
}
println("COL: \(col)")
var tile = SKSpriteNode(texture: SKTexture(imageNamed: "brick_\(tileMap[col])"))
tile.name = "tile_\(rowIndex)_\(colIndex)"
tile.position.y = frameSize.height - (tile.size.height * CGFloat(rowIndex)) - (tile.size.height/2)
tile.position.x = tile.size.width * CGFloat(colIndex) + (tile.size.width/2)
var physicsBody = SKPhysicsBody(rectangleOfSize: tile.size)
tile.physicsBody = physicsBody
tile.physicsBody.affectedByGravity = false
tile.physicsBody.categoryBitMask = ColliderType.Block.toRaw()
tile.physicsBody.contactTestBitMask = ColliderType.Ball.toRaw()
tile.physicsBody.collisionBitMask = ColliderType.Ball.toRaw()
scene.addChild(tile)
tileCount++
}
}
}
这是我的碰撞类型
enum ColliderType:UInt32 {
case Paddle = 1
case Block = 2
case Wall = 3
case Ball = 4
}
这是我的重置功能内容:
func reset() {
tileCount = 0
var removeTiles = [SKSpriteNode]()
// remove all the tiles
for child in scene.children {
var a_tile = child as SKSpriteNode
if a_tile.name.hasPrefix("tile_") {
a_tile.removeFromParent()
a_tile.name = ""
removeTiles.append(a_tile)
}
}
removeTiles.removeAll(keepCapacity: false)
ball!.position = CGPoint(x: 200, y: 200)
ballVel = CGPoint(x: 0, y: -5)
currentLevel++
loadLevel()
lost = false
won = false
}
这是我的级别
结构
struct Tile {
let map = ["blue","green","purple","red"]
}
struct Levels {
let data = [
[
[4,4,0,4,0,4,0,4,0,4,0,4,0,0,4,4],
[4,4,1,4,1,4,1,4,1,4,1,4,1,1,4,4],
[4,4,2,4,2,4,2,4,2,4,2,4,2,2,4,4],
[4,4,3,4,3,4,3,4,3,4,3,4,3,3,4,4]
],
[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[2,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2],
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
]
]
}
如果这是Swift中的一个bug,我正在试图找到一种解决方法,这样我就可以让它正常工作 看起来像是用空大小实例化了SKPhysicsBody
。尝试创建具有显式大小的物理实体对象,如下所示:
var physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(100, 100))
或者,您可以直接在SKSpriteNode
上设置大小,或者使用它的一个构造函数,该构造函数采用CGSize构造,如initWithTexture:color:size:
您为什么要先将主体指定给var而不是直接指定给tile.physicsBody?@LearnCos2D只是尝试从这个错误中解决问题。前几次我是按照你说的做的。事实上,对于初学者来说,你不应该在swift中使用内置的物理引擎作为平台。它的强度太大,无法为每个瓷砖制作一个物理实体,可能会导致故障。阅读这里的更多内容:第二,您的remove函数可以简化为scene.removeAllChildren()我尝试了您的代码,但无法重现这个问题。你能把它简化成一个仍然存在问题的小例子吗?顺便说一句,像这样使用enum
是错误的,因为Wall==Block&pable
它会与这两者发生冲突。您可能想使用。