Ios 如何在使用物理中设置场地在swift中,并且只使用applyImpulse跳跃一次

Ios 如何在使用物理中设置场地在swift中,并且只使用applyImpulse跳跃一次,ios,swift,game-physics,Ios,Swift,Game Physics,我正在尝试用Swift做一个跳跃和奔跑的游戏,我遇到了两个主要问题 首先,我将重力应用于游戏场景,但每次我跳跃时,玩家都会穿过地板,而不是停留在其原始位置。我尝试在跳跃前设置dynamic=false,然后在跳跃后将其设置为true,但它仍然会掉落在地板上 我遇到的另一个问题是,当点击时,玩家应用并推动每一次点击,因此跳跃、双跳、三跳等。我似乎不知道如何使它只在地面水平时跳跃 这是代码 override func touchesBegan(touches: Set<UITouch&g

我正在尝试用Swift做一个跳跃和奔跑的游戏,我遇到了两个主要问题

首先,我将重力应用于游戏场景,但每次我跳跃时,玩家都会穿过地板,而不是停留在其原始位置。我尝试在跳跃前设置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
    }
}
覆盖函数触摸开始(触摸:设置,withEvent事件:UIEvent?){
//基本上是我的点击开始功能。我在游戏屏幕上将玩家的动态设置为false,然后在第一次点击时它运行游戏,然后每隔一次点击它就会正常跳转
如果玩家.physicsBody!.dynamic{
player.physicsBody?.applyImpulse(CGVector(dx:0.0,dy:5.0))
}否则{
产卵桶()
addTimer()
runScore()
startAbel.removeFromParent()
player.physicsBody?.dynamic=true
player.physicsBody?.applyImpulse(CGVector(dx:0.0,dy:4.0))
}
}
func addGround(){
//增加了基础
addChild(地面)
ground.size=CGSize(宽度:size.width*1,高度:size.height*0.1)
ground.position=CGPoint(x:size.width*0.5,y:size.height*0.05)
ground.physicsBody=SKPhysicsBody(矩形尺寸:CGSize(宽度:size.height,高度:size.height*0.1))
地面。physicsBody?动态=假
}
var canJump=true
//改变
func didBeginContactGround(联系人:SKPhysicsContact){
让contactMask=contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
开关(触点屏蔽){
案例物理分类。玩家|物理分类。背景:
canJump=true
违约:
返回
}
}

关于问题的第一部分: 碰撞、接触和类别位掩码混淆。以下是它们的定义/用途:

  • 类别:它是什么类型的对象(
    physiccategory.Player
  • 碰撞:它与哪些对象碰撞(
    physiccategory.Ground
  • 接触:游戏应该测试碰撞的原因。然后,可以在中引用两个对象的碰撞:
    func-didBeginContact(联系人:skphysiccontact){}
现在,你告诉你的玩家检查它和其他玩家之间的碰撞,并且什么都不碰撞(如果这没有意义,我建议进一步研究这些位掩码)。如果您希望玩家在遇到障碍物时死亡,您可以将其接触设置为
physiccategory.barriend

对于第二部分:您可以将联系人位掩码设置为
physiccategory.Ground
,如果您还需要障碍物,则可以设置为:
physiccategory.Ground | physiccategory.blounder
。然后,您可以创建一个名为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
。如果您不了解不同的位掩码,以下链接应该会有所帮助:


制作另一个与玩家一样的SpriteKitNode。乱动不同的设置,让它像一个静止的物体一样(例如,将dynamic设置为
false
,等等)。如果你想让它不可见,只需沿屏幕底部将它稍微偏离屏幕1像素。我已经做了一段时间了,但我似乎真的无法理解它。你能给我什么解释吗?当然可以-让我看看你有什么,这样我就知道你遇到了什么问题。我在我的问题中添加了代码。基本上我设定了重力,但我需要球员在落地时停止摔倒。我还需要球员只有在触地时才能跳。