如何使用已创建的 SKSpriteNode 创建与 SpriteKit 的冲突?

Posted

技术标签:

【中文标题】如何使用已创建的 SKSpriteNode 创建与 SpriteKit 的冲突?【英文标题】:How do I create a collision with SpriteKit with an already created SKSpriteNode? 【发布时间】:2017-04-02 21:07:55 【问题描述】:

我希望吃豆人在与正在移动的眨眼碰撞时从其原始位置重新启动。

考虑到我已经声明了它们,我怎样才能让它们发生碰撞?

你移动吃豆子,但眨眼一个人移动。我希望它像吃豆人游戏一样工作。

  public class PacmanScene: SKScene 

let playerSpeed: CGFloat = 40.0
var pacman: SKSpriteNode?
var playerTextures: [SKTexture] = []
var lastTouch: CGPoint? = nil
var blinky: SKSpriteNode?
var clyde: SKSpriteNode?
var inky: SKSpriteNode?
var pinky: SKSpriteNode?
override public init(size: CGSize) 
let pacmanTexture = SKTexture(imageNamed: "pacman01.png")
    pacman = SKSpriteNode(texture: pacmanTexture)
    pacman?.name = "pacman"

    pacman?.position = CGPoint(x:30, y:30)
    pacman?.zPosition = 1.0
    pacman?.physicsBody = SKPhysicsBody(texture: pacmanTexture, size: CGSize(width: (pacman?.size.width)!, height: (pacman?.size.height)!))
    pacman?.physicsBody?.allowsRotation = true
    pacman?.physicsBody?.affectedByGravity = false
    pacman?.physicsBody?.mass = 2
 let blinkyTexture = SKTexture(imageNamed: "blinky.png")
    blinky = SKSpriteNode(texture: blinkyTexture)
    blinky?.name = "blinky"

    blinky?.position = CGPoint(x: 15, y: 60)
    blinky?.zPosition = 1.0
    blinky?.physicsBody = SKPhysicsBody(texture: pacmanTexture, size: CGSize(width: (blinky?.size.width)!, height: (blinky?.size.height)!))
    blinky?.physicsBody?.allowsRotation = false
    blinky?.physicsBody?.affectedByGravity = false
    blinky?.physicsBody?.mass = 1000

    super.init(size: size)
    addChild(pacman!)
    addChild(blinky!)

   override public func didMove(to view: SKView) 

    let bmoveUp = SKAction.moveBy(x: 0, y: 450, duration: 4.0)

    let bmoveRight = SKAction.moveBy(x:20, y:0, duration: 1.0)

    let bmoveDown = SKAction.moveBy(x:0, y: -450, duration: 4.0)

   let bmoveLeft = SKAction.moveBy(x:-20, y:0, duration: 1.0)


    let bsequence = SKAction.sequence([bmoveUp, bmoveRight, bmoveDown, bmoveLeft])

    let bendlessAction = SKAction.repeatForever(bsequence)
    blinky?.run(bendlessAction)
 

【问题讨论】:

【参考方案1】:

如果 iv 做对了,您希望您的“blinky”跟随您的“pacman”执行此操作,您必须计算出 pacman 的位置,然后将 SKAction 添加到您的 blinky 以移动到该位置。

试试这样的

//Speed blinky moves
let blinkySpeed = 100

override func update(_ currentTime: TimeInterval) 
    // Called before each frame is rendered
    updateBlinky()


func updateBlinky() 
    //Set the point that blinky moves to
    let point = CGPoint(x: pacman.position.x, y: pacman.position.y)
    //Get the distance its got to travel
    let distance = distanceBetweenPoints(first: pacman.position, second: blinky.position)
    //Get the time is got to take from the speed and distance
    let time = distance / blinkySpeed
    //Create and run the action
    let action = SKAction.move(to: point, duration: TimeInterval(time))
    blinky.run(action)


//work out the distance between the sprites
func distanceBetweenPoints(first: CGPoint, second: CGPoint) -> Int 
    return Int(hypot(second.x - first.x, second.y - first.y))

最终结果会是这样的

编辑:

好的,我认为根据您的问题,您已经“眨眼”移动您只是想检测碰撞。

首先你需要将 SKPhysicsContactDelegate 添加到你的类中

public class PacmanScene: SKScene, SKPhysicsContactDelegate 

然后您需要为两个精灵添加一个类别位掩码,然后在 didBegin(_contact: SKPhysicsContact) 方法中处理碰撞。

我会做什么

//Create Physics category struct
struct PhysicsCategory 
    static let pacman : UInt32 = 0x1 << 1
    static var blinky : UInt32 = 0x1 << 2

然后你在哪里设置 pacman 和 blinky 设置类别位掩码

//Set the category bit mask for pacman
pacman?.physicsBody?.categoryBitMask = PhysicsCategory.pacman
//Set what categories you want to test contact
pacman?.physicsBody?.contactTestBitMask = PhysicsCategory.blinky
//Set what categories you want to collide with each other
pacman?.physicsBody?.collisionBitMask = PhysicsCategory.blinky

//Set the category bit mask for blinky
blinky?.physicsBody?.categoryBitMask = PhysicsCategory.blinky
//Set what categories you want to test contact
blinky?.physicsBody?.contactTestBitMask = PhysicsCategory.pacman
//Set what categories you want to collide with each other
blinky?.physicsBody?.collisionBitMask = PhysicsCategory.pacman

那么你需要实现 didBegin(_contact: SKPhysicsContact) 方法来处理碰撞

func didBegin(_ contact: SKPhysicsContact) 
    //Work out which contact was pacman
    let other = contact.bodyA.categoryBitMask == PhysicsCategory.pacman ? contact.bodyB : contact.bodyA
    //Test what it hit
    switch other.categoryBitMask 

        case PhysicsCategory.blinky:
            print("pacman hit blinky")
            //Move pacman
            pacman?.position = CGPoint(x:30, y:30)

        default:
        break

    

希望对你有帮助

【讨论】:

以上是关于如何使用已创建的 SKSpriteNode 创建与 SpriteKit 的冲突?的主要内容,如果未能解决你的问题,请参考以下文章

为无尽的跑步游戏创建动态大小的 SKSpriteNode 平台

使用SKSpriteNode physicsBody创建墙/障碍

SKScene - 如何从 SKSpriteNode 获取类

SKSpriteNode - 创建一个圆角节点?

如何检测是不是已触摸 SKSpriteNode

以编程方式使用资产创建 SKSpriteNode