第1天碰撞检测:迅速3

时间:2016-07-14 07:17:53

标签: swift sprite-kit

所以我想制作一款游戏,这是从Xcode SpriteKit采样器条纹化的,非常简单。当我把这个关键问题排除在外时,它会发展很大。它有一个玩家,Wall和一扇门。分配节点,播放器工作正常。沃尔试图为自己的孩子,但删除我的评论崩溃。我猜是多个同名节点?但门,当分配节点时,由于某种原因,无论什么缓慢下降,没有重力滴答,没有重力编码。

这些是较少关注的问题。今天我来找你,为什么我的碰撞可能没有激活我的碰撞参数功能,进入房子。 是的我知道它说联系人映射到事件。它非常适合我的理论。

//
//  GameScene.swift
//  Sandbox
//
//  Created by M on 7/1/16.
//  Copyright © 2016 M. All rights reserved.
//

import SpriteKit
import GameplayKit



class GameScene: SKScene, SKPhysicsContactDelegate {

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

    private var lastUpdateTime : TimeInterval = 0
    private var label : SKLabelNode?
    var playerNode : SKSpriteNode?
    var wallNode : SKSpriteNode?
    var doorNode : SKSpriteNode?
    private var spinnyNode : SKShapeNode?
    var furnishing : SKSpriteNode?
    var playerCategory = 0x1 << 0
    var wallCategory = 0x1 << 1
    var doorCategory = 0x1 << 2
    var pathCategory = 0x1 << 3


    func nextRoom() {

        let sceneNode = SKScene(fileNamed: "MyScene")
        sceneNode?.scaleMode = .aspectFill

        // Present the scene
        if let view = self.view {
            view.presentScene(sceneNode)
            view.ignoresSiblingOrder = true
            view.showsFPS = true
            view.showsNodeCount = true
        }
    }

    func loadRoom() {
        let furnishing = SKSpriteNode(color: #colorLiteral(red: 0.2464724183, green: 0.05352632701, blue: 0.03394328058, alpha: 1), size:CGSize(width:25, height:25))
        doorNode?.addChild(furnishing)
    }

    func enterHouse() {
        let newWindow = CGSize(width: 500, height: 500)
        doorNode?.scale(to: newWindow)
        loadRoom()
    }

    func exitHouse(){
        let oldWindow = CGSize(width: 100, height: 100)
        doorNode?.scale(to: oldWindow)
    }


    override func sceneDidLoad() {
        self.lastUpdateTime = 0
        physicsWorld.contactDelegate = self

        // Get nodes from scene and store for use later
      self.playerNode = self.childNode(withName: "//player") as? SKSpriteNode
        playerNode?.physicsBody = SKPhysicsBody(rectangleOf: (playerNode?.frame.size)!)
        playerNode?.physicsBody?.isDynamic = true
        playerNode?.physicsBody?.affectedByGravity = false
        playerNode?.physicsBody?.categoryBitMask = UInt32(playerCategory)
        playerNode?.physicsBody?.collisionBitMask = UInt32(wallCategory)
        playerNode?.physicsBody?.contactTestBitMask = UInt32(doorCategory)

        for child in self.children {
            /*if child.name == "wall" {
                if let child = child as? SKSpriteNode {
                    wallNode?.physicsBody = SKPhysicsBody(rectangleOf: (wallNode?.frame.size)!)
                    wallNode?.physicsBody?.isDynamic = false
        wallNode?.physicsBody?.categoryBitMask = UInt32(wallCategory)
        wallNode?.physicsBody?.collisionBitMask = UInt32(playerCategory)
                    self.addChild(child)
                }
            }*/
        }

        self.doorNode = self.childNode(withName: "door") as? SKSpriteNode
        doorNode?.physicsBody?.affectedByGravity = false
        doorNode?.physicsBody?.isDynamic = false
        doorNode?.physicsBody = SKPhysicsBody(rectangleOf: (doorNode?.frame.size)!)
        doorNode?.physicsBody?.categoryBitMask = UInt32(doorCategory)
        doorNode?.physicsBody?.contactTestBitMask = UInt32(playerCategory)
    }

    func touchDown(atPoint pos : CGPoint) {
            let fromX = playerNode?.position.x
            let fromY = playerNode?.position.y
            let toX = pos.x
            let toY = pos.y
            let resultX = toX - (fromX)!
            let resultY = toY - (fromY)!
            let newX = (playerNode?.position.x)! + resultX / 10
            let newY = (playerNode?.position.y)! + resultY / 10
            playerNode?.position.x = newX
            playerNode?.position.y = newY
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchDown(atPoint: t.location(in: self)) }
    }

    func didBeginContact(contact: SKPhysicsContact) {

        //this gets called automatically when two objects begin contact with each other
         // 1. Create local variables for two physics bodies
        var firstBody: SKPhysicsBody
        var secondBody: SKPhysicsBody

        // 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }
        if secondBody.categoryBitMask == UInt32(doorCategory){
            enterHouse()
        }
    }

    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(withDeltaTime: dt)
        }

        self.lastUpdateTime = currentTime
    }
}

1 个答案:

答案 0 :(得分:0)

我认为此行导致崩溃

wallNode?.physicsBody = SKPhysicsBody(rectangleOf: (wallNode?.frame.size)!)

因为你强行展开(!)wallNode大小但是看你的代码你从来没有把它分配给任何类似的东西

wallNode = self.childNode(withName: "wallNode") as? SKSpriteNode

或在for循环中。

在for循环中尝试使用此代码,以避免崩溃并分配您的墙节点。

   for child in self.children where child.name == "wall" {
       if let child = child as? SKSpriteNode {

           wallNode = child // Try this 

           if let wallNode = wallNode { // safely unwrap wall node to avoid crashes               

               wallNode.physicsBody = SKPhysicsBody(rectangleOf: (wallNode.frame.size))
               wallNode.physicsBody?.isDynamic = false
               wallNode.physicsBody?.categoryBitMask = UInt32(wallCategory)
               wallNode.physicsBody?.collisionBitMask = UInt32(playerCategory)
               self.addChild(wallNode) // add wall node here instead if you are using your wallNode property

            }
        }
    }

希望这有帮助