【问题标题】:Swift 3: Consistent player movement along Joystick || SpritekitSwift 3:沿操纵杆的一致玩家移动 ||精灵包
【发布时间】:2017-11-30 23:32:03
【问题描述】:

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

ex:Sprite 自动移动一定的速度,例如; speed = 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()
}

【问题讨论】:

  • 信息太少,无法确定如何解决这个问题,并将您的来源发布到问题中,不要使用 png。 SO 用于在格式正确时处理代码。
  • @Knight0fDragon 嘿,感谢骑士的快速响应,我按照你的建议格式化了文本,现在看起来更干净了,谢谢。

标签: swift3 sprite-kit sprite joystick


【解决方案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

【讨论】:

  • 那么我会将速度声明为 CGPoint 吗?还有“GetDirection()”是什么?
  • 获取方向是您获得控制器输入(我将假设是触摸屏),我认为速度是 CGVector,请查看苹果文档
  • 所以,我使用了“touchLocation”,因为我认为使用它是正确的,我想我可以使用“v”或“angle”但我不确定,并且对于 switch 语句,我是否必须将这些 case 变量声明为“向上”,因为它不允许我使用它们。抱歉所有问题。
  • 那你找错地方了,你需要找一些教程和访问一些论坛群,堆栈溢出是针对特定问答问题设计的,你需要学习如何编程。
  • 我知道如何编程,我没有在我的任何项目中使用过 switch 语句,只是想了解如何以最有效的方式正确使用它。
【解决方案2】:

为了实现连续移动,您需要跟踪您的玩家正在触摸操纵杆的哪个部分;要么使用操纵杆位置的不同部分,要么只使用节点来跟踪触摸。然后在更新功能中使用力移动您的节点。所以想法是,当您触摸时,您将一些相应的 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)
}

【讨论】:

  • 很好的第一次尝试,但我们甚至不知道他们是否使用内置物理,尝试让您的答案更通用或使用伪代码
  • 为建议喝彩,下次会采纳!
  • @Knight0fDragon 我正在使用内置物理。
  • 如果有帮助的话,我还包括了我的播放器类。
  • 所以在这种情况下,我的猜测是在游戏场景更新中使用冲动或力量来根据操纵杆的移动位置继续移动玩家!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
相关资源
最近更新 更多