问题
I have a virtual control pad in my game. If I tap and hold on one of the direction buttons, the player moves in the correct direction and shows the proper images and animation. However, if I slide my finger from one control to another one (say right to down), the player moves down but the image and animation don't change until I lift my finger. Below is my code for handling the touches:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches as! Set<UITouch>) {
let location = touch.location(in: cameraNode)
if upRect.contains(location) {
moveXDirection = 0
moveYDirection = 1
isIdle = false
playerSprite.walkUpPlayer()
} else if rightRect.contains(location) {
moveXDirection = 1
moveYDirection = 0
isIdle = false
playerSprite.walkLRPlayer()
} else if downRect.contains(location) {
moveXDirection = 0
moveYDirection = -1
isIdle = false
playerSprite.walkDownPlayer()
} else if leftRect.contains(location) {
moveXDirection = -1
moveYDirection = 0
isIdle = false
playerSprite.walkLRPlayer()
}
if !isIdle && moveXDirection != 0 {
playerSprite.xScale = moveXDirection
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches as! Set<UITouch>) {
let location = touch.location(in: cameraNode)
if upRect.contains(location) {
moveXDirection = 0
moveYDirection = 1
isIdle = false
} else if rightRect.contains(location) {
moveXDirection = 1
moveYDirection = 0
isIdle = false
} else if downRect.contains(location) {
moveXDirection = 0
moveYDirection = -1
isIdle = false
} else if leftRect.contains(location) {
moveXDirection = -1
moveYDirection = 0
isIdle = false
}
if !isIdle && moveXDirection != 0 {
playerSprite.xScale = moveXDirection
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
idlePlayer()
}
My code for changing the player animation is:
func idlePlayer() {
removeAllActions()
}
func walkLRPlayer() {
removeAllActions()
run(SKAction.repeatForever(walkLRAnimation!))
}
func walkUpPlayer() {
removeAllActions()
run(SKAction.repeatForever(walkUpAnimation!))
}
func walkDownPlayer() {
removeAllActions()
run(SKAction.repeatForever(walkDownAnimation!))
}
Any suggestions would be greatly appreciated.
回答1:
Your player starts with a direction in touchesBegan
and stops it on touchesEnded
. The problem is that you don't handle the direction changes on touchesMoves
.
Lets create a global variable that will tell us if we changed the direction.
var previous_direction : Int = -1 // idle state
On the touches functions, add the previous_direction
behaviour.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches as! Set<UITouch>) {
// we start with previous_direction being the start direction
if upRect.contains(location) {
previous_direction = 0 // up
} else if rightRect.contains(location) {
previous_direction = 1 // right
} else if downRect.contains(location) {
previous_direction = 2 // down
} else if leftRect.contains(location) {
previous_direction = 3 // left
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches as! Set<UITouch>) {
// we create a current_direction also
var current_direction : Int = -1
// get current_direction
if upRect.contains(location) {
current_direction = 0 // up
} else if rightRect.contains(location) {
current_direction = 1 // right
} else if downRect.contains(location) {
current_direction = 2 // down
} else if leftRect.contains(location) {
current_direction = 0 // left
}
// now we compare if the current_direction is different from previous_direction
if current_direction != previous_direction
{
player.removeAllActions()
// attribute new direction
if current_direction == 0 {
playerSprite.walkUpPlayer()
} else if current_direction == 1 {
walkLRPlayer.walkLRPlayer()
} else if current_direction == 2 {
walkLRPlayer.walkDownPlayer()
} else if current_direction == 3 {
walkLRPlayer.walkLRPlayer() }
// we prepare previous_direction for the next time he enters this function
previous_direction = current_direction
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// reset previous_direction
previous_direction = - 1 // idle state
}
来源:https://stackoverflow.com/questions/54227703/spritekit-animation-not-changing