真实设备上的 SKTileMap 物理错误
Posted
技术标签:
【中文标题】真实设备上的 SKTileMap 物理错误【英文标题】:SKTileMap physics bug on real devices 【发布时间】:2019-03-27 17:03:47 【问题描述】:我一直在开发一个使用平铺地图的 2D SpriteKit
游戏。我用这个函数给我的瓦片地图一个SKPhysicsBody
:
import SpriteKit
func giveTileMapPhysicsBody(map: SKTileMapNode)
let tileMap = map
let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height
for col in 0..<tileMap.numberOfColumns
for row in 0..<tileMap.numberOfRows
if let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
//let isEdgeTile = tileDefinition.userData?["AddBody"] as? Int //uncomment this if needed, see article notes
//if (isEdgeTile != 0)
let tileArray = tileDefinition.textures
let tileTexture = tileArray[0]
let x = CGFloat(col) * tileSize.width - halfWidth + (tileSize.width/8)
let y = CGFloat(row) * tileSize.height - halfHeight + (tileSize.height/8)
_ = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKNode()
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody(texture: tileTexture, size: CGSize(width: (tileTexture.size().width), height: (tileTexture.size().height)))
tileNode.physicsBody?.linearDamping = 0.8 //60.0
tileNode.physicsBody?.affectedByGravity = false
tileNode.physicsBody?.allowsRotation = false
tileNode.physicsBody?.restitution = 0.2
tileNode.physicsBody?.isDynamic = false
tileNode.physicsBody?.categoryBitMask = PhysicsCategory.tileMap
tileNode.physicsBody?.contactTestBitMask = PhysicsCategory.player
tileNode.physicsBody?.collisionBitMask = PhysicsCategory.player
tileNode.physicsBody?.friction = 0.8 // 3.0
tileMap.addChild(tileNode)
//
正如您在第一个屏幕截图中看到的那样,当我在模拟器上运行我的游戏时,一切正常,但是当我在我的真实 iPhone 或 iPad 上运行它时,瓷砖贴图物理(第二张图片)出现了一个错误。正如你在第二张图片上看到的那样,在我的真实设备上运行它时存在物理差距。 你知道它可能是什么吗?
编辑:
不幸的是,它不适用于我的项目。物理形状不会正确匹配地图。
【问题讨论】:
什么是物理差距? 感谢您的回复。看第二张图。你能看到瓦片贴图的物理体比它的纹理大吗?这只发生在真实设备上,而不是模拟器上(第一张图片)。 我猜你遇到了舍入问题。如果你在做瓷砖,我不建议使用纹理体 谢谢!你的意思是给我的图块分配一个方形物理体而不是基于图块纹理的物理体更好? 另外,每块瓷砖都有一个物理体会影响你的表现。通过在内置瓦片系统之上实施自己的瓦片系统,您实际上是在扼杀瓦片带来的所有效率。 【参考方案1】:尝试像这样实现它
typealias TileCoordinates = (column: Int, row: Int)
func giveTileMapPhysicsBody(map: SKTileMapNode)
let tileMap = map
var physicsBodies = [SKPhysicsBody]()
for row in 0..<tileMap.numberOfRows
for column in 0..<tileMap.numberOfColumns
guard let tile = tile(in: tileMap, at: (column, row)) else continue
let center = tileMap.centerOfTile(atColumn: column, row: row)
let body = SKPhysicsBody(rectangleOf: tile.size, center: center)
physicsBodies.append(body)
tileMap.physicsBody = SKPhysicsBody(bodies: physicsBodies)
tileMap.physicsBody?.categoryBitMask = PhysicsCategory.tileMap
tileMap.physicsBody?.contactTestBitMask = PhysicsCategory.player
tileMap.physicsBody?.collisionBitMask = PhysicsCategory.player
tileMap.physicsBody?.linearDamping = 0.8 //60.0
tileMap.physicsBody?.affectedByGravity = false
tileMap.physicsBody?.allowsRotation = false
tileMap.physicsBody?.restitution = 0.2
tileMap.physicsBody?.isDynamic = false
tileMap.physicsBody?.friction = 0.8 // 3.0
func tile(in tileMap: SKTileMapNode, at coordinates: TileCoordinates) -> SKTileDefinition?
return tileMap.tileDefinition(atColumn: coordinates.column, row: coordinates.row)
【讨论】:
非常感谢!我出现错误“使用未声明的类型'TileCoordinates'”。我该如何解决? 抱歉,忘记添加该变量,请检查顶部的已编辑答案。 嗯..在不知道您正在使用的瓷砖的情况下很难准确定位问题。 我使用的是 Xcode 提供的标准图块。你也可以试试。我的代码在模拟器上完美运行而不是在真实设备上运行,这并不奇怪吗? 确实很奇怪,但不幸的是我不知道为什么,尽力帮助,对不起,我不能做更多。以上是关于真实设备上的 SKTileMap 物理错误的主要内容,如果未能解决你的问题,请参考以下文章
Android Libgdx - 真实设备上的 Sigsegv 11 错误,但模拟器上没有崩溃
由于物理设备上的 XCApplicationStateRunningActive,Xcode UI 测试失败
React Native - 在真实设备上构建时出现 XCode 错误?