无法在操场的 spritekit 中移动我的头像

Posted

技术标签:

【中文标题】无法在操场的 spritekit 中移动我的头像【英文标题】:Cannot move my avatar in spritekit in playground 【发布时间】:2020-05-11 06:43:14 【问题描述】:

我最近正在尝试使用 spriteKit 构建游戏,我想将我的头像移动到我的触摸位置,并将所有其他敌人的移动到我头像的当前位置。但是我的头像并没有从它的位置移动,只是在旋转我触摸的方向。我想把它移到我的触摸位置。这是我的代码: "'

导入 SpriteKit

公共类GameScene:SKScene,SKPhysicsContactDelegate

let playerSpeed: CGFloat = 40.0
let coronaSpeed: CGFloat = 10.0

var mask: SKSpriteNode?
var player: SKSpriteNode?
var mcorona: [SKSpriteNode] = []

var lastTouch: CGPoint? = nil

override public func didMove(to view: SKView) 
    physicsWorld.contactDelegate = self

    // Animations
    player = childNode(withName: "player") as? SKSpriteNode

    mask = childNode(withName: "mask") as? SKSpriteNode
    mask!.run(SKAction.repeatForever(
        SKAction.sequence([
            SKAction.moveBy(x: 0, y: 10, duration: 0.45),
            SKAction.moveBy(x: 0, y: -10, duration: 0.45)
            ]
    )))

    for child in self.children 
        if child.name == "corona" 
            if let child = child as? SKSpriteNode 
                mcorona.append(child)
            
        
    
    // </> Animations

override public func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?)  handleTouches(touches) 

override public func touchesMoved(_ touches: Set<UITouch>,with event: UIEvent?)  handleTouches(touches) 

override public func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)  handleTouches(touches) 

fileprivate func handleTouches(_ touches: Set<UITouch>)  lastTouch = touches.first?.location(in: self) 

override public func didSimulatePhysics() 
    if player != nil 
        updatePlayer()
        updateZombies()
    

fileprivate func updatePosition(for sprite: SKSpriteNode, to target: CGPoint, speed: CGFloat) 

    let currentPosition = sprite.position
    let angle = CGFloat.pi + atan2(currentPosition.y - target.y, currentPosition.x - target.x)
    let rotateAction = SKAction.rotate(toAngle: angle + (CGFloat.pi*0.5), duration: 0)
    sprite.run(rotateAction)

    let velocityX = speed * cos(angle)
    let velocityY = speed * sin(angle)

    let newVelocity = CGVector(dx: velocityX, dy: velocityY)
    sprite.physicsBody?.velocity = newVelocity


fileprivate func gameOver(_ didWin: Bool) 
    let resultScene = MenuScene(size: size, didWin: didWin, levelToSend: 2)
    let transition = SKTransition.flipVertical(withDuration: 1.0)
    view?.presentScene(resultScene, transition: transition)



fileprivate func shouldMove(currentPosition: CGPoint,
                            touchPosition: CGPoint) -> Bool 
    guard let player = player else  return false 
    return abs(currentPosition.x - touchPosition.x) > player.frame.width / 2 ||
        abs(currentPosition.y - touchPosition.y) > player.frame.height / 2


fileprivate func updatePlayer() 
    guard let player = player,
        let touch = lastTouch
        else  return 
    let currentPosition = player.position
    if shouldMove(currentPosition: currentPosition,
                  touchPosition: touch) 
        updatePosition(for: player, to: touch, speed: playerSpeed)
     else 
        player.physicsBody?.isResting = true
    


func updateZombies() 
    guard let player = player else  return 
    let targetPosition = player.position

    for corona in mcorona 
        updatePosition(for: corona, to: targetPosition, speed: coronaSpeed)
    



public func didBegin(_ contact: SKPhysicsContact) 

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask 
        firstBody = contact.bodyA
        secondBody = contact.bodyB
     else 
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    

    // Check contact
    if firstBody.categoryBitMask == player?.physicsBody?.categoryBitMask &&
        secondBody.categoryBitMask == mcorona[0].physicsBody?.categoryBitMask 
        // Player & corona
        gameOver(false)
     else if firstBody.categoryBitMask == player?.physicsBody?.categoryBitMask &&
        secondBody.categoryBitMask == mask?.physicsBody?.categoryBitMask 
        // Player & mask
        gameOver(true)
    

"' Here is the GIF to the problem I faced

请帮忙! 提前致谢!

【问题讨论】:

【参考方案1】:

在您的代码中,您正在创建一个新的速度并将其分配给您的玩家,但是据我所知,您并没有更新您的代码中的玩家位置。尝试在 updatePosition 函数中添加一条实际更新玩家位置的行。

sprite.position += sprite.physicsBody.velocity

据我所知,这将通过函数 updatePosition 为每次迭代增加精灵位置,一直运行直到玩家位置到达其目的地。

另一种可能的解决方案:

您可以尝试使用 SKActions 移动精灵。将 updatePosition 函数中的最后一行替换为:

let moveToTouch = SKAction.move(to: CGPoint(x: target.x, y: target.y), duration: speed)

sprite.run(moveToTouch)

【讨论】:

我已经使用 shouldMove 函数来检测我的 touchPosition 作为我的最终位置。我也试过你的方法,但它不会运行 在上面添加了另一个可能的解决方案 我想这取得了一些进展,但还没有完全实现。无法达到玩家速度。敌人正在向玩家移动,但看起来他们只是以很小的速度移动。 这里是描述场景的 GIF-gph.is/g/aK5pnp6 找到了解决方案...***.com/questions/61744489/… ...谢谢

以上是关于无法在操场的 spritekit 中移动我的头像的主要内容,如果未能解决你的问题,请参考以下文章

无法在 SpriteKit 中正确移动入侵者

Sprite不会用手指/ SpriteKit / Swift 3移动

任何人都知道如何在 swift 操场上进行多项选择游戏? [关闭]

如何在 SpriteKit 中跟踪接触后的节点移动

CAShapeLayer 和 SpriteKit

使用 SKY SpriteKit 和 Swift 4 移动和旋转精灵