如何在 swift 中使用物理设置地面位置,并使用 applyImpulse 仅跳跃一次
How to set where the ground in using physics in swift, and jumping only once with applyImpulse
我正在尝试在 Swift 中进行跳跃和 运行 游戏,我有 运行 两个主要问题。
首先是我将重力应用到 GameScene,但每次我跳跃时,玩家都会穿过地板而不是停在原来的位置。我尝试在跳跃前设置dynamic = false,然后在跳跃后将其设置为true,但它仍然从地板上掉下来。
我遇到的另一个问题是,当点击时,播放器会应用并推动每次点击,因此会跳跃、二段跳、三段跳等。我似乎无法弄清楚如何让它只在点击时跳跃位于地面层。
这是代码。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//basically my tap to start feature. i set the player's dynamic to false at the play screen, then on the first tap it runs the game, then every other tap it normally jumps
if player.physicsBody!.dynamic {
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 5.0))
} else {
spawnBarrels()
addTimer()
runScore()
startLabel.removeFromParent()
player.physicsBody?.dynamic = true
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 4.0))
}
}
func addGround(){
//adds the ground
addChild(ground)
ground.size = CGSize(width: size.width * 1, height: size.height * 0.1)
ground.position = CGPoint(x: size.width * 0.5, y: size.height * 0.05)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: size.height, height: size.height * 0.1))
ground.physicsBody?.dynamic = false
}
var canJump = true
//change
func didBeginContactGround(contact: SKPhysicsContact){
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask){
case PhysicsCategory.Player | PhysicsCategory.Ground:
canJump = true
default:
return
}
}
对于你问题的第一部分:
您混淆了碰撞、接触和类别位掩码。这些是他们的 Definitions/Uses:
- 类别:它是什么类型的对象(
PhysicsCategory.Player
)
- Collision: 它与什么物体发生碰撞(
PhysicsCategory.Ground
)
- Contact: 游戏应该测试什么碰撞。然后,您可以在以下位置引用两个对象的碰撞:
func didBeginContact(contact: SKPhysicsContact){}
现在你告诉你的玩家检查它和其他玩家之间的碰撞,并且没有碰撞(如果这没有意义,我建议进一步研究这些位掩码)。如果您希望您的玩家在接触到障碍物时死亡,您可以将其 Contact 设置为 PhysicsCategory.Obstacle
.
对于第二部分:你可以设置接触位掩码为PhysicsCategory.Ground
,如果你也想要障碍物,可以是:PhysicsCategory.Ground | PhysicsCategory.Obstacle
.然后你可以创建一个名为 canJump 的布尔值,并且只允许在 true
.
时跳转
然后你会在你的代码中的某个地方写这个:
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask) {
case PhysicsCategory.Player | PhysicsCategory.Ground:
canJump = true;
default:
return
}
}
然后每当你的玩家跳跃时,将 canJump 设置为 false
。这样一来,当玩家撞到地面时,他们就可以再次跳跃。如果你想更精确,不是在跳跃后将 canJump 设置为 false
,而是在玩家不再与地面接触后将其设置为 false
,方法是制作另一个相同的函数,但将名称更改为 didEndContact
,并将其设置为 false
而不是 true
。
此外,播放器的动态应始终为 true
。如果您不理解不同的位掩码,这里有一个 link 应该对您有所帮助:
我正在尝试在 Swift 中进行跳跃和 运行 游戏,我有 运行 两个主要问题。
首先是我将重力应用到 GameScene,但每次我跳跃时,玩家都会穿过地板而不是停在原来的位置。我尝试在跳跃前设置dynamic = false,然后在跳跃后将其设置为true,但它仍然从地板上掉下来。
我遇到的另一个问题是,当点击时,播放器会应用并推动每次点击,因此会跳跃、二段跳、三段跳等。我似乎无法弄清楚如何让它只在点击时跳跃位于地面层。
这是代码。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//basically my tap to start feature. i set the player's dynamic to false at the play screen, then on the first tap it runs the game, then every other tap it normally jumps
if player.physicsBody!.dynamic {
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 5.0))
} else {
spawnBarrels()
addTimer()
runScore()
startLabel.removeFromParent()
player.physicsBody?.dynamic = true
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 4.0))
}
}
func addGround(){
//adds the ground
addChild(ground)
ground.size = CGSize(width: size.width * 1, height: size.height * 0.1)
ground.position = CGPoint(x: size.width * 0.5, y: size.height * 0.05)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: size.height, height: size.height * 0.1))
ground.physicsBody?.dynamic = false
}
var canJump = true
//change
func didBeginContactGround(contact: SKPhysicsContact){
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask){
case PhysicsCategory.Player | PhysicsCategory.Ground:
canJump = true
default:
return
}
}
对于你问题的第一部分: 您混淆了碰撞、接触和类别位掩码。这些是他们的 Definitions/Uses:
- 类别:它是什么类型的对象(
PhysicsCategory.Player
) - Collision: 它与什么物体发生碰撞(
PhysicsCategory.Ground
) - Contact: 游戏应该测试什么碰撞。然后,您可以在以下位置引用两个对象的碰撞:
func didBeginContact(contact: SKPhysicsContact){}
现在你告诉你的玩家检查它和其他玩家之间的碰撞,并且没有碰撞(如果这没有意义,我建议进一步研究这些位掩码)。如果您希望您的玩家在接触到障碍物时死亡,您可以将其 Contact 设置为 PhysicsCategory.Obstacle
.
对于第二部分:你可以设置接触位掩码为PhysicsCategory.Ground
,如果你也想要障碍物,可以是:PhysicsCategory.Ground | PhysicsCategory.Obstacle
.然后你可以创建一个名为 canJump 的布尔值,并且只允许在 true
.
然后你会在你的代码中的某个地方写这个:
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask) {
case PhysicsCategory.Player | PhysicsCategory.Ground:
canJump = true;
default:
return
}
}
然后每当你的玩家跳跃时,将 canJump 设置为 false
。这样一来,当玩家撞到地面时,他们就可以再次跳跃。如果你想更精确,不是在跳跃后将 canJump 设置为 false
,而是在玩家不再与地面接触后将其设置为 false
,方法是制作另一个相同的函数,但将名称更改为 didEndContact
,并将其设置为 false
而不是 true
。
此外,播放器的动态应始终为 true
。如果您不理解不同的位掩码,这里有一个 link 应该对您有所帮助: