I am having trouble with connecting my player to a jump button in SpriteKit. I have created the game through the Swift file. This is what I have so far:
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() {
}
So far, the //self.player
in the handlejumpButtonClick
is supposed to allow the character to jump up and then gravity would bring him back down. However, as of right now, when the jump button is pressed the game crashes and gives a thread 1 exc error.
Would anyone know of a way to get the button to work with the character? And if possible, is there a shorter way of doing this without having to rebuild the game?
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)
}
This may also be something people need to see(this is also code from 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
}