【问题标题】:SpriteKit player jump buttonSpriteKit 播放器跳转按钮
【发布时间】:2017-04-24 20:54:04
【问题描述】:

我在将播放器连接到 SpriteKit 中的跳转按钮时遇到问题。我通过 Swift 文件创建了游戏。这是我目前所拥有的:

override func sceneDidLoad() {
    //Setup start button
    jumpButton = SKSpriteNode(texture: jumpButtonTexture)
    jumpButton.position = CGPoint(x: 1850, y: 130)
    jumpButton.size = CGSize(width: 200, height: 200)
    jumpButton.zPosition = 20

    addChild(jumpButton)

    //Setup start button
    attackButton = SKSpriteNode(texture: attackButtonTexture)
    attackButton.position = CGPoint(x: 1550, y: 130)
    attackButton.size = CGSize(width: 200, height: 200)
    attackButton.zPosition = 20

    addChild(attackButton)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if selectedButton != nil {
            handleJumpButtonHover(isHovering: false)
            handleAttackButtonHover(isHovering: false)
        }

        if jumpButton.contains(touch.location(in: self)) {
            selectedButton = jumpButton
            handleJumpButtonHover(isHovering: true)
        } else if attackButton.contains(touch.location(in: self)) {
            selectedButton = attackButton
            handleAttackButtonHover(isHovering: true)
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if selectedButton == jumpButton {
            handleJumpButtonHover(isHovering: false)

            if (jumpButton.contains(touch.location(in: self))) {
                handleJumpButtonClick()
            }
        } else if selectedButton == attackButton {
            handleAttackButtonHover(isHovering: false)

            if (attackButton.contains(touch.location(in: self))) {
                handleAttackButtonClick()
            }
        }
    }
    selectedButton = nil
}

func handleJumpButtonHover(isHovering : Bool) {
    if isHovering {
        jumpButton.texture = jumpButtonPressedTexture
    } else {
        jumpButton.texture = jumpButtonTexture
    }
}

func handleAttackButtonHover(isHovering : Bool) {
    if isHovering {
        attackButton.texture = attackButtonPressedTexture
    } else {
        attackButton.texture = attackButtonTexture
    }
}

func handleJumpButtonClick() {
    //self.player.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
    //self.player.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 20))
}

func handleAttackButtonClick() {
}

到目前为止,handlejumpButtonClick 中的//self.player 应该允许角色跳起来,然后重力会将他拉下来。但是,截至目前,当按下跳转按钮时,游戏崩溃并给出线程 1 exc 错误。

有人知道让按钮与角色一起工作的方法吗?如果可能的话,有没有更短的方法可以做到这一点而无需重新构建游戏?

 func createPlayer(_ position: CGPoint) { 

    //graphic stuff
    let playerTexture = SKTexture(imageNamed: "Ttam1") //create variable with graphic assigned to it
    let player = SKSpriteNode(texture: playerTexture) //give player the graphic
    player.size = CGSize(width: 125, height: 200) //player sprite size
    player.zPosition = 20
    //physics stuff
    player.physicsBody = SKPhysicsBody(texture: playerTexture, size: player.size) //Set up pixel-perfect collision mesh for the player
    player.physicsBody?.isDynamic = true
    player.physicsBody!.affectedByGravity = true //Stop the player from being affected by gravity
    player.physicsBody?.allowsRotation = false

    //spawny stuff
    insertChild(player, at: 0) //spawn player
    player.position = position //move player to position passed into this method
    playerNode = player //Create a node where the player is, filled by the player itself... Like a D.Va ult! The call mech one, not the self-destruct one.

    let frame2 = SKTexture(imageNamed: "Ttam2")
    let frame3 = SKTexture(imageNamed: "Ttam3")
    let frame4 = SKTexture(imageNamed: "Ttam4")
    let animation = SKAction.animate(with: [playerTexture, frame2, frame3, frame4], timePerFrame: 0.2)
    let runForever = SKAction.repeatForever(animation)

    player.run(runForever)
}

这可能也是人们需要看到的(这也是来自AnalogJoystick.swift的代码):

let moveAnalogStick =  joystick(diameter: 240) //This is the size of the joystick on screen, probably in pixels


func createJoystick() {

    moveAnalogStick.position = CGPoint(x: moveAnalogStick.radius + 100, y: moveAnalogStick.radius + 5) //position of joystick on screen
    addChild(moveAnalogStick) //add joystick to screen

    moveAnalogStick.stick.color = UIColor.black //Joystick "stick" color
    //moveAnalogStick.stick.image = UIImage(named: "jStick") //Joystick "stick" graphic
    moveAnalogStick.substrate.color = UIColor.clear //Joystick "base" color
    moveAnalogStick.substrate.image = UIImage(named: "jSubstrate") //Joystick "base" graphic

    //MARK: Handlers begin
    moveAnalogStick.startHandler = { [unowned self] data in //These things happen only when the joystick is first pressed

        //CODE GOES HERE

    }

    moveAnalogStick.trackingHandler = { [unowned self] data in //These things happen while the joystick is being touched- regardless of movement. But honestly, this sucker is so sensitive, I'd give someone a medal if they can touch it without moving it at all

        //self.playerNode?.zRotation = (data.angular + 3.14159265359) //player rotation matches joystick, had to add in pi because of graphic facing wrong way- asked Jenny to fix this, but not a priority

        //these two lines are linked in a way I can't figure out how to untangle right now
        //They control movement though, I know that for a fact
        guard let pN = self.playerNode else { return }
        pN.position = CGPoint(x: pN.position.x + (data.velocity.x * 0.07), y: pN.position.y + (data.velocity.x * 0))

}

    moveAnalogStick.stopHandler = { [unowned self] data in //These things happen only when the joystick stops being pressed

        ///CODE GOES HERE

    }
    //MARK: Handlers end
}

【问题讨论】:

  • 请发布代码,显示您在哪里声明和初始化player
  • 我想这就是你的意思,我把它加到了帖子的底部
  • 另外,我把这个角色挂在了一个虚拟的操纵杆上,为什么它不起作用?如果有必要,我也可以发布该代码
  • 当点击该按钮时,没有什么会导致崩溃。调试器是否指向任何特定的调用或线路?还是有错误信息?
  • 当我有 //self.player.physicsBody?.velocity = CGVector(dx: 0, dy: 0) //self.player.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 20)) 未注释,它会出现线程 1 exc 错误。我将不得不等到明天才能回复,因为我不得不离开教室,因为另一个班级要来了。我会尽快回复。非常感谢你到目前为止试图帮助我。我已经被这个错误困住了 2 天了,因为我正在制作的游戏是为了上课,所以我必须尽快让它消失。 P.S 如果需要,我会上传我的整个代码,哈哈

标签: ios swift button sprite-kit


【解决方案1】:

我现在看到了问题。

您在 createPlayer() 函数中声明了一个局部变量 player,但将该播放器实例设置为全局变量 playerNode。但是,当您施加冲动时,您会尝试引用局部变量。将两行改为

self.playerNode.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
self.playerNode.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 20))

您可能收到THREAD 1 EXC_BAD_INSTRUCTION。这通常意味着编译器并不完全知道您要做什么。换句话说,它知道变量player 存在,但它不能使用它。该错误应该更具解释性。

【讨论】:

  • 哦,好吧,现在说得通了。我一到房间就试试看
  • 另外,您介意我再问一个围绕我的另一个按钮的问题吗?
  • 您需要发布一个单独的问题,但我很乐意看看它。发布后,请随时返回此处并发布新链接,以便我找到它。
  • 所以我现在才去教室。我将 self.player 更改为 self.playerNode。更改它时,它出现了一条错误消息“可选类型'SKSpriteNode的值?'没有打开;你是不是要使用“!”或者 '?'?”我应该这样做还是会影响它?
  • 您没有显示您声明playerNode 的位置,但显然它是可选的。所以是的,使用self.playerNode?.physicsBody?....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-29
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多