EdgeFromLoop 似乎没有调用 didBegin?

Posted

技术标签:

【中文标题】EdgeFromLoop 似乎没有调用 didBegin?【英文标题】:EdgeFromLoop doesn't seem to call didBegin? 【发布时间】:2020-06-04 22:51:49 【问题描述】:

我正在尝试编写一个游戏,其中星星从 iphone 屏幕的顶部落到底部。我想在它们离开屏幕时删除我的星图。我尝试使用physicsContactDelegate,并使用edgeFromLoop(self.frame)在我的框架周围创建一个边缘,但从未调用过didBegin。

下面是我的 gameScene.swift 文件

import SpriteKit
import GameplayKit
import UIKit

class GameScene: SKScene, SKPhysicsContactDelegate 

    var entities = [GKEntity]()
    var graphs = [String : GKGraph]()

    private var lastUpdateTime : TimeInterval = 0

    struct PhysicsCategory 
      static let none: UInt32 = 0
      static let all : UInt32 = UInt32.max
      static let star: UInt32 = 0b1       // 1
      static let edge: UInt32 = 0b10      // 2
    

    private var edge: SKPhysicsBody!

    override func sceneDidLoad() 

        self.lastUpdateTime = 0

        edge = SKPhysicsBody(edgeLoopFrom: self.frame)
        edge.categoryBitMask = PhysicsCategory.edge
        edge.contactTestBitMask = PhysicsCategory.star
        edge.collisionBitMask = PhysicsCategory.star
    


    override func didMove(to view: SKView) 

        physicsWorld.contactDelegate = self

        run(SKAction.repeatForever(
            SKAction.sequence([
                SKAction.run(addStar),
                SKAction.wait(forDuration: 1.0)
            ])
      ))
    

    func didBegin(_ contact: SKPhysicsContact) 

      print("didBegin called")
      // 1
      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
      

      if((firstBody.categoryBitMask & PhysicsCategory.star != 0) &&
          (secondBody.categoryBitMask & PhysicsCategory.edge != 0))

          print("call destroyStar")
          if let star = firstBody.node as? SKSpriteNode 
              destroyStar(star: star)
          
      
    

    func addStar()

        let star = SKSpriteNode(imageNamed: "star")

        let scale = CGFloat.random(in: 0.1 ... 0.5)
        star.xScale = scale
        star.yScale = scale
        star.zPosition = 1.0

        star.physicsBody = SKPhysicsBody(rectangleOf: star.size)
        star.physicsBody?.linearDamping = 1.0
        star.physicsBody?.friction = 1.0

        star.physicsBody?.isDynamic = true // 2
        star.physicsBody?.categoryBitMask = PhysicsCategory.star // 3
        star.physicsBody?.contactTestBitMask = PhysicsCategory.edge // 4
        star.physicsBody?.collisionBitMask = PhysicsCategory.edge

        let actualX = CGFloat.random(in: (-1*size.width/2)+50 ... (size.width/2)-50)

        star.position = CGPoint(x: actualX, y: self.size.height)
        addChild(star)
    

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

        // Initialize _lastUpdateTime if it has not already been
        if (self.lastUpdateTime == 0) 
            self.lastUpdateTime = currentTime
        

        // Calculate time since last update
        let dt = currentTime - self.lastUpdateTime

        // Update entities
        for entity in self.entities 
            entity.update(deltaTime: dt)
        

        self.lastUpdateTime = currentTime
    

    func destroyStar(star: SKSpriteNode)

        print("star destroyed")
        star.removeFromParent()

    


这是我的 GameViewController

import UIKit
import SpriteKit
import GameplayKit

class GameViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()

        // Load 'GameScene.sks' as a GKScene. This provides gameplay related content
        // including entities and graphs.
        if let scene = GKScene(fileNamed: "GameScene") 

            // Get the SKScene from the loaded GKScene
            if let sceneNode = scene.rootNode as! GameScene? 

                // Copy gameplay related content over to the scene
                sceneNode.entities = scene.entities
                sceneNode.graphs = scene.graphs

                // Set the scale mode to scale to fit the window
                sceneNode.scaleMode = .aspectFit

                // Present the scene
                if let view = self.view as! SKView? 
                    view.presentScene(sceneNode)

                    view.ignoresSiblingOrder = true

                    view.showsFPS = true
                    view.showsNodeCount = true
                
            
        
    

    override var shouldAutorotate: Bool 
        return true
    

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask 
        if UIDevice.current.userInterfaceIdiom == .phone 
            return .allButUpsideDown
         else 
            return .all
        
    

    override var prefersStatusBarHidden: Bool 
        return true
    

我是一个快速的初学者,我知道我的问题可能非常基础,但我非常感谢任何帮助!谢谢!

【问题讨论】:

我认为“边缘”不是场景或节点的一部分,您在哪里将边缘添加到节点/场景? @Maetschl at edge = SKPhysicsBody(edgeLoopF​​rom: self.frame) ? 但未引用 SKPhysicsBody 实例(边缘) 【参考方案1】:

你需要制作edge和SKNode(),然后将physicsBody分配给edge。

试试这个。

let edge = SKNode()

override func didMove(to View: SKView) 
    edge.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
    edge.physicsBody.categoryBitMask = PhysicsCategory.edge
    edge.physicsBody.contactTestBitMask = PhysicsCategory.star
    edge.physicsBody.collisionBitMask = PhysicsCategory.star

    self.addChild(edge)

【讨论】:

以上是关于EdgeFromLoop 似乎没有调用 didBegin?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot JpaRepository 保存调用似乎没有做任何事情

迭代 RDD 迭代器并应用限制时,Spark 似乎没有调用 hasNext

为啥我在 UITableCellView 中的 UIView 中的 UILabel 在正确的数据库调用后没有更新(似乎与单元重用有关)?

调用异步方法后,进程似乎没有回到 WPF 应用程序中的主线程

AJAX 调用似乎从未发生过

setInterval 在它调用的函数中似乎不喜欢 () 。为啥? [复制]