【问题标题】:how to make a collision with sprite nodes on Xcode swift如何在 Xcode swift 上与精灵节点发生碰撞
【发布时间】:2015-04-04 09:02:27
【问题描述】:

IM 试图制作一个应用程序,但两个 skspriteNodes 的碰撞将无法正常工作。请帮忙。

代码:

// If statements
if CGRectIntersectsRect(heroRect, stoneRect){
    hittingTrigger()
}

func hittingTrigger() {
    heroB.removeFromParent()
    stoneGround.removeFromParent()
    yellowStripes.removeFromParent()
}



let heroB = SKSpriteNode(texture: nil, color: UIColor.grayColor(), size: CGSizeMake(32, 40))
        heroB.position = CGPointMake(self.size.width / 2, self.size.height / 2)
        self.addChild(heroB)
let stoneTrigger = SKSpriteNode(texture: nil, color: UIColor.grayColor(), size: CGSizeMake(32, 40))

heroB.runAction(SKAction.repeatActionForever(moveRight))
      stoneTrigger.runAction(SKAction.repeatActionForever(moveLeft))
 heroB.zPosition = 20
stoneTrigger.zPosition = 20
stoneTrigger.position = CGPointMake(self.size.width / 2 + 200, self.size.height / 2)

heroRect 是他的人的矩形。 而stoneRect应该是一个触发器,它不会工作。

【问题讨论】:

  • 它运行完美,但无法正常工作。
  • 请发布更多代码。 if 语句放在哪里?在更新方法中?你在使用基于物理的碰撞吗?
  • ok ZeMoon 我现在就做
  • 让 heroB = SKSpriteNode(texture: nil, color: UIColor.grayColor(), size: CGSizeMake(32, 40)) heroB.position = CGPointMake(self.size.width / 2, self. size.height / 2) self.addChild(heroB) let stoneTrigger = SKSpriteNode(texture: nil, color: UIColor.grayColor(), size: CGSizeMake(32, 40))
  • 这只是精灵的声明。 CGRectIntersectsRect() 方法在哪里被调用?

标签: xcode swift sprite-kit collision-detection


【解决方案1】:

为了使您的代码按您的意愿工作,您需要:

  1. stoneTrigger 添加到属于场景树的 SKNode,就像您对 heroB 所做的那样

  2. 移动以下代码

    if CGRectIntersectsRect(heroRect, stoneRect){
        hittingTrigger()
    }
    

    在更新方法中,实际上你想检查每一帧的碰撞。 (为了更优雅的碰撞检测,您应该使用 SpriteKit 物理引擎)。

  3. 使用适当的 SKSpriteNode 初始化器,如果你不想使用纹理,你应该使用它

    SKSpriteNode(color: UIColor.grayColor(), size: CGSizeMake(32, 40))
    

我准备了一个简单的 GameScene 来做(我猜)你想要的:

import SpriteKit
class GameScene: SKScene {

private let heroB = SKSpriteNode(color: UIColor.grayColor(), size: CGSizeMake(32, 40))
private let stoneTrigger = SKSpriteNode(color: UIColor.grayColor(), size: CGSizeMake(32, 40))

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    let moveRight = SKAction.moveByX(200, y: 0, duration: 10)
    let moveLeft = SKAction.moveByX(-200, y: 0, duration: 10)

    heroB.position = CGPointMake(self.size.width / 2, self.size.height / 2)
    heroB.runAction(SKAction.repeatActionForever(moveRight))
    heroB.zPosition = 20
    self.addChild(heroB)

    stoneTrigger.runAction(SKAction.repeatActionForever(moveLeft))
    stoneTrigger.zPosition = 20
    stoneTrigger.position = CGPointMake(self.size.width / 2 + 200, self.size.height / 2)
    self.addChild(stoneTrigger)
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
    if CGRectIntersectsRect(heroB.frame, stoneTrigger.frame){
        hittingTrigger()
    }
}

private func hittingTrigger() {
    heroB.removeFromParent()
    println("Collision!!")
//      stoneGround.removeFromParent()
//      yellowStripes.removeFromParent()
}
}

更新

查看我的代码有一些我不喜欢的地方。 2 个实例属性 heroBstoneTrigger 会保留相关的 SKSpriteNode,即使在不需要时也是如此。 事实上,即使 heroB 从 GameScene 中移除,它仍然在内存中分配。鉴于此示例的简单性,这没什么大不了的,但可以肯定这不是最佳实践。我修改了我的代码以解决这个问题。这里是:

import SpriteKit

class GameScene: SKScene {

private weak var heroB : SKSpriteNode?
private weak var stoneTrigger : SKSpriteNode?

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    let moveRight = SKAction.moveByX(200, y: 0, duration: 10)
    let moveLeft = SKAction.moveByX(-200, y: 0, duration: 10)

    let heroB = SKSpriteNode(color: UIColor.grayColor(), size: CGSizeMake(32, 40))
    heroB.position = CGPointMake(self.size.width / 2, self.size.height / 2)
    heroB.runAction(SKAction.repeatActionForever(moveRight))
    heroB.zPosition = 20
    self.addChild(heroB)
    self.heroB = heroB

    let stoneTrigger = SKSpriteNode(color: UIColor.grayColor(), size: CGSizeMake(32, 40))
    stoneTrigger.runAction(SKAction.repeatActionForever(moveLeft))
    stoneTrigger.zPosition = 20
    stoneTrigger.position = CGPointMake(self.size.width / 2 + 200, self.size.height / 2)
    self.addChild(stoneTrigger)
    self.stoneTrigger = stoneTrigger
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
    if let heroB = heroB {
        if let stoneTrigger = stoneTrigger {
            if CGRectIntersectsRect(heroB.frame, stoneTrigger.frame){
                hittingTrigger()
            }
        }
    }
}

private func hittingTrigger() {
    if let heroB = heroB {
        heroB.removeFromParent()
        println("Collision!!")
//      stoneGround.removeFromParent()
//      yellowStripes.removeFromParent()
    }
}
}

【讨论】:

  • 谢谢 appzYourLife。它适用于另一个项目,但不是我想要的。我有很多代码。剩下的交给你吗?
  • 一个问题:你说的项目可能不是SpriteKit项目?
  • 我的项目在我检查的 sprite kit 中
  • 我的项目中还有线程 1 信号香烟。我可以把我剩下的代码给你看看发生了什么吗?
  • 我不是说香烟,我是说 sigabrt,一分钟就可以了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2013-05-31
相关资源
最近更新 更多