我正在使用Sprite Kit制作游戏,并且当您按住向左/向右移动按钮时,我希望角色在屏幕上移动。问题在于他仅在轻按按钮时才移动,而没有保持住。我到处都在寻找解决方案,但似乎无济于事!
这是我的代码;
class Button: SKNode { var defaultButton: SKSpriteNode // defualt state var activeButton: SKSpriteNode // active state var timer = Timer() var action: () -> Void //default constructor init(defaultButtonImage: String, activeButtonImage: String, buttonAction: @escaping () -> Void ) { //get the images for both button states defaultButton = SKSpriteNode(imageNamed: defaultButtonImage) activeButton = SKSpriteNode(imageNamed: activeButtonImage) //hide it while not in use activeButton.isHidden = true action = buttonAction super.init() isUserInteractionEnabled = true addChild(defaultButton) addChild(activeButton) } //When user touches button override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { action() //using timer to repeatedly call action, doesnt seem to work... self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(getter: Button.action), userInfo: nil, repeats: true) //swtich the image of our button activeButton.isHidden = false defaultButton.isHidden = true } code..........
在我的游戏场景中…
// *** RIGHT MOVEMENT *** let rightMovementbutton = Button(defaultButtonImage: "arrow", activeButtonImage: "arrowActive", buttonAction: { let moveAction = SKAction.moveBy(x: 15, y: 0, duration: 0.1) self.player.run(moveAction) })
您知道什么时候触摸了按钮,因为它touchesBegan被调用了。然后,您必须设置一个标志以指示按钮被按下。
touchesBegan
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { let touch = touches.first! if leftButton.containsPoint(touch.locationInNode(self)) { leftButtonIsPressed = true } if rightButton.containsPoint(touch.locationInNode(self)) { rightButtonIsPressed = true } }
在中update(),调用标记为true的函数:
update()
update() { if leftButtonIsPressed == true { moveLeft() } if rightButtonIsPressed == true { moveRight() } }
您可以在touchesEnded调用该按钮时将标志设置为false :
touchesEnded
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { let touch = touches.first! if leftButton.containsPoint(touch.locationInNode(self)) { leftButtonIsPressed = false } if rightButton.containsPoint(touch.locationInNode(self)) { rightButtonIsPressed = flase } }
编辑:
正如KoD所指出的那样,一种更干净的方法(用于移动按钮)SKAction可以消除对标志的需要:
SKAction
SKActions
moveTo x:0
moveTo x:frame.width
didMoveTo(View:)
您必须做一些数学运算来计算对象必须移动多少点,然后根据该距离和移动速度(以每秒点数为单位)设置SKAction的持续时间。
或者,(由于KnightOfDragons的帮助)创建了一个SKAction.MoveBy x:以较小的距离(基于您所需的移动速度)并且持续时间为1/60 秒的。SKAction.repeatForever触摸按钮时,请永久重复此操作(),并在释放按钮时删除重复的SKAction。
SKAction.MoveBy x:
SKAction.repeatForever