Swift 3:沿着游戏杆||一致的玩家移动Spritekit

时间:2017-06-27 19:25:06

标签: swift3 sprite-kit sprite joystick

我的问题是如何将我的精灵与操纵杆一起连续运动?我希望玩家一直以一定的速度移动,然后每当用户将操纵杆移动一定角度时,玩家就会跟随它。

ex:Sprite自动移动一定的速度,ex;速度= CGFloat(100),然后它会以这个速度继续,速度精灵只是自动向一个方向移动,我不知道如何实现它,以便我的玩家在一个恒定的移动速度,以及如何改变方向是随着操纵杆移动。

目前,我的代码可以旋转精灵。

我感谢你们给予的所有帮助,谢谢你们。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {


    for touch in touches {
        touchLocation = touch.location(in: self)

        if (ball.frame.contains(touchLocation)) {

            stickActive = true

        } else {
            stickActive = false
        }
    }



}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        touchLocation = touch.location(in: self)

        if isAlive == true{ 
            joyStickMoved()

        }
        if isAlive == false{
            player.position.x = -300
        }

    }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if (stickActive == true) {
            let move: SKAction = SKAction.move(to: base.position, duration: 0.2)
            move.timingMode = .easeOut
            ball.run(move)
    }
}

func joyStickMoved() {

    if (stickActive == true) {



        let v = CGVector(dx: touchLocation.x - base.position.x, dy: touchLocation.y - base.position.y)
        let angle = atan2(v.dy, v.dx)

        // let degree = angle * CGFloat( 180 / Double.pi)

        let length: CGFloat = base.frame.size.height / 2

        let xDist: CGFloat = sin(angle - 1.57079633) * length
        let yDist: CGFloat = cos(angle - 1.57079633) * length
        //   TODO   // xJoystick = touchLocation.x - base.position.x
        // yJoystick = touchLocation.y - base.position.y

        if (base.frame.contains(touchLocation)) {
            ball.position = touchLocation

        } else {
            ball.position = CGPoint(x: base.position.x - xDist, y: base.position.y + yDist)

        }

        player.zRotation = angle - 1.57079633

    }


}

override func update(_ currentTime: TimeInterval) {



    if isAlive == false && stickActive == false {
        lblMain.text = "Game Over"
        player.position.x = -300
        waitThenResetTheGame()
    }

    if stickActive == true {
        moveNodeToLocation()
    }
}

func spawnPlayer(){
    player = SKSpriteNode(color: offWhiteColor, size: playerSize)
    player.position = CGPoint(x: self.frame.midX, y: 130)

    player.physicsBody = SKPhysicsBody(rectangleOf: (player.size))
    player.physicsBody?.affectedByGravity = false
    player.physicsBody?.categoryBitMask = physicsCategory.player
    player.physicsBody?.contactTestBitMask = physicsCategory.fallingBlock
    player.physicsBody?.isDynamic = false
    player.physicsBody?.allowsRotation = false
    player.physicsBody?.angularVelocity = 5
    player.physicsBody?.angularDamping = 0

    player.name = "player"


    self.addChild(player)
    setupFollower()
}

2 个答案:

答案 0 :(得分:1)

好吧如果你正在使用物理学,那么你不想做的一件事是不断地施加冲动,你想直接设定速度你的家伙正在移动的速度。

我打算写伪代码,因为我现在正在打电话:

基本上你想做这样的事情:

velocity =(0,0)

On update

    dir = GetDirection()
    switch(dir)
    Case up:  velocity = (0,200/150) // because 1 newton = 150points. Physics uses newtons
    Case down: velocity = (0,-200/150)
    Case left: velocity = (-200/150,0)
    Case right: velocity = (200/150,0)
    end switch

Sprite.physicsbody.velocity= velocity


End update

仅限触摸屏控件:

velocity =(0,0)

On touch

    dir = GetDirection()
    switch(dir)
    Case up:  velocity = (0,200/150) // because 1 newton = 150points. Physics uses newtons
    Case down: velocity = (0,-200/150)
    Case left: velocity = (-200/150,0)
    Case right: velocity = (200/150,0)
    end switch
End touch

On update

Sprite.physicsbody.velocity= velocity


End update

答案 1 :(得分:0)

为了实现连续移动,您需要跟踪玩家正在触摸的操纵杆的哪个部分;要么使用操纵杆位置的不同部分,要么只使用节点来跟踪触摸。然后在更新功能中使用force移动节点。所以我的想法是,当你触摸时,你将一些相应的BOOL设置为true,更新根据它们移动节点,然后在触摸端,BOOL返回false,这样你就停止了移动。

我已经半sudo编码了这个,但这应该让你知道你需要做什么:

//in your player class 
func walk(force: CGFloat) {
  self.physicsbody.applyForce(CGVector(dx: force, dy: 0.0))
}

//in your gamescene touchesBegan
if joystickRight.contains(touchlocation) {
  //declare all these BOOL's at the top of your gameScene class
        isTouching = true
        movingRight = true
        xVelocity = 200
}

//in your gamescene touchesEnded
  isTouching = false
  movingRight = false

//in your gamescene update
if isTouching && movingRight {
        thePlayer.walk(force: xVelocity)
}