我正在尝试在我的播放器底部添加一个hitbox,以便只检测平台。经过多次反复试验,我发现有一个附加的物理体作为一个孩子固定的位置连接到另一个物理体,我需要使用一个SKPhysicsJoint。我做了这件事,结果似乎出乎意料。当我以这种方式将hitbox添加到播放器时,它会稍微改变播放器碰撞/接触位掩码。
在我的游戏中,你可以轻触屏幕进行跳跃,它可以无缝地工作,没有延迟,就像这样:
Player jumping
但是,当我添加这个带有关节的hitbox时,我必须用手指按住屏幕,最终播放器会跳转,但大多数情况下,输入被忽略。几乎好像在读取输入时有严重的延迟。在这个gif中,我不断地点击屏幕,试图让我的播放器跳跃,许多输入被忽略或阻止:
Player hitbox not behaving
此函数用于在my gamescope.swift中设置播放器,并通过一个固定的skphysicjoint将hitbox添加到播放器:
func playerSetup(){
//setups player
addChild(player)
player.addChild(playerPlatformHitbox)
let myCGPoint = player.position // sets joint position
let myJoint = SKPhysicsJointFixed.joint(withBodyA: playerPlatformHitbox.physicsBody!, bodyB: player.physicsBody!, anchor: myCGPoint)
scene?.physicsWorld.add(myJoint)
}
这是我制作的hitbox类,只为玩家检测平台。您将看到它应该忽略位掩码所期望的平台。出于某种原因,它不允许玩家接受与它的位掩码的接触,即使这个hitbox和玩家没有接触:
import Foundation
import SpriteKit
class PlayerPlatformHitbox: SKSpriteNode{
init() {
super.init(texture: nil, color: SKColor.blue, size: CGSize(width: playerTexture.size().width, height: 10))
physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width, height: self.size.height))
position = CGPoint(x:0, y: (-playerTexture.size().height * 0.6))
physicsBody?.categoryBitMask = CollisionTypes.jumpHitBox.rawValue
physicsBody?.contactTestBitMask = CollisionTypes.platform.rawValue
physicsBody?.collisionBitMask = CollisionTypes.platform.rawValue
physicsBody?.restitution = 0.0
physicsBody?.friction = 0.0
zPosition = 20
physicsBody?.linearDamping = 0.0
physicsBody?.angularDamping = 0.0
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)}
}
这是我的球员课
class Player: SKSpriteNode {
init() {
super.init(texture: nil, color: SKColor.clear, size: playerTexture.size())
//starts accelerameter
motionManager = CMMotionManager()
motionManager.startAccelerometerUpdates()
physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: playerTexture.size().width,
height: playerTexture.size().height))
physicsBody?.categoryBitMask = CollisionTypes.player.rawValue
physicsBody?.contactTestBitMask = CollisionTypes.memoryModule.rawValue | CollisionTypes.spikes.rawValue | CollisionTypes.finish.rawValue | CollisionTypes.enemy.rawValue | CollisionTypes.ground.rawValue
physicsBody?.collisionBitMask = CollisionTypes.ground.rawValue | CollisionTypes.sceneEdge.rawValue
physicsBody?.affectedByGravity = true
physicsBody?.restitution = 0.0
physicsBody?.friction = 0.3
physicsBody?.isDynamic = true
//physicsBody?.friction = 0.0
physicsBody?.allowsRotation = false
setScale(0.65)
zPosition = 1
physicsBody?.linearDamping = 0.0
physicsBody?.angularDamping = 0.0
animateWalk()
}
所有这一切的目标是使用hitbox来检测平台,而不是我在更新方法中使用的这个函数中的播放器:
//jump through platform check
if let body = player.physicsBody {
let dy = body.velocity.dy
if dy > 0{
// Prevent collisions if the hero is jumping
body.collisionBitMask &= ~CollisionTypes.platform.rawValue
body.contactTestBitMask &= ~CollisionTypes.platform.rawValue
}
else {
// Allow collisions if the hero is falling
body.collisionBitMask |= CollisionTypes.platform.rawValue
body.contactTestBitMask |= CollisionTypes.platform.rawValue
}
}
我需要这样做的唯一原因是,当球员摔倒时,如果他摔倒并撞到了平台的侧面,他会停下来滑下去,因为碰撞又回来了,球员的身体是一个正方形。
如果我可以使用平台检测hitbox来检测平台,而不是玩家笨重的hitbox,它将解决这个问题。
谢谢你的建议。
编辑:这是一个物理体,没有关节的孩子的行为:
Odd behavior
最佳答案
我找到了解决办法。
似乎有一些固定关节的缺陷,答案是使用“销”关节代替。This StackO question详细介绍了一个带有固定关节的旋转错误。一时兴起,我决定把固定的关节换成别针,现在孩子的行为和你想象的一样,不管怎样,都是按位置说话。
所以看来固定关节有一些缺陷需要解决。
关于swift - 使用固定的SKPhysicsJoint将平台检测对象框作为 child 附加到玩家 Sprite 时,会更改玩家的碰撞和检测位掩码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47948551/