【问题标题】:Gameover on any collision - Swift Spritekit任何碰撞的游戏结束 - Swift Spritekit
【发布时间】:2017-04-23 10:10:36
【问题描述】:

在我的游戏中,我有飞机四处移动。在我的游戏中,我希望如果任何飞机与另一架飞机相撞,它会打印“游戏结束”。我已将SKPhysicsContactDelegate 添加到我的游戏场景中。我在我的飞机上添加了一个物理实体。然后,我将此函数添加到我的 didMoveToView 函数中:

  func didBegin(_ contact: SKPhysicsContact){
        print("Game over")
        }

现在,当我运行我的游戏时,飞机发生碰撞,控制台上没有任何内容。如何更改我的代码,以便在任何飞机与另一架飞机(超过 2 架)发生碰撞时将游戏打印到控制台?

编辑:我已将物理世界联系人委托设置为 self。我没有调用这个函数——我必须调用吗?我认为这个函数在场景中发生碰撞时运行。

这是我的代码:

//
//  GameScene.swift
//  PlaneGame
//
//  Created by Lucas Farleigh on 09/04/2017.
//  Copyright © 2017 Farleigh Tech. All rights reserved.
//

import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {

private let Background = SKSpriteNode(imageNamed: "Background")
private let PlaneRed = SKSpriteNode(imageNamed: "PlaneRed")
private let PlaneBlue = SKSpriteNode(imageNamed: "PlaneBlue")
private let PlaneRed2 = SKSpriteNode(imageNamed: "PlaneRed2")
private let PlaneBlue2 = SKSpriteNode(imageNamed: "PlaneBlue2")
private let StartButton = SKLabelNode(fontNamed: "Chalkduster")
private let Trail = SKSpriteNode(imageNamed: "BlueTrail")
private let Center = SKNode()
private let Center2 = SKNode()
var GameHasStarted = false




override func didMove(to view: SKView) {

    //Defining the position,size and ZPosition for the background
    Background.position = CGPoint(x:self.frame.midX / 2,y: self.frame.midY)
    Background.xScale = 10.0
    Background.yScale = 10.0
    Background.zPosition = -10
    addChild(Background)



    //Defining a start button - will be used later as a button
    StartButton.position = CGPoint(x:self.frame.midX,y:self.frame.minY + 100)
    StartButton.text = "Tap Anywhere To Start"
    StartButton.fontSize = 50.0
    StartButton.name = "StartButton"
    addChild(StartButton)

    //Setting the planered position and size up for the plane, ready to start the game
    PlaneRed.position = CGPoint(x:self.frame.midX - 250,y: self.frame.midY)
    PlaneRed.xScale = 0.13
    PlaneRed.yScale = 0.13
    PlaneRed.zPosition = 10
    //Setting the planeblue position and size up for the plane, ready to start the game
    PlaneBlue.position = CGPoint(x:self.frame.midX + 250,y: self.frame.midY)
    PlaneBlue.xScale = 0.13
    PlaneBlue.yScale = -0.13
    PlaneBlue.zPosition = 10

    //Setting the planered position and size up for the plane, ready to start the game
    PlaneRed2.position = CGPoint(x:self.frame.midX,y: self.frame.midY + 250)
    PlaneRed2.xScale = -0.13
    PlaneRed2.yScale = 0.13
    PlaneRed2.zPosition = 10
    //Setting the planeblue position and size up for the plane, ready to start the game
    PlaneBlue2.position = CGPoint(x:self.frame.midX,y: self.frame.midY - 250)
    PlaneBlue2.xScale = 0.13
    PlaneBlue2.yScale = 0.13
    PlaneBlue2.zPosition = 10


    //Making the trail
    Trail.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    Trail.xScale = 1.08
    Trail.yScale = 1.08
    addChild(Trail)

    //In order to rotate the planes around a point, we must create the point as an SKNode, and make the planes a child of the point
    //The point then rotates bringing the planes with it
    //Setting up the point where the plane will rotate around
    Center.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    addChild(Center)
    Center2.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    addChild(Center2)
    Center.addChild(PlaneRed)
    Center.addChild(PlaneBlue)
    Center2.addChild(PlaneRed2)
    Center2.addChild(PlaneBlue2)



    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //ADDING PHYSICS TO PLANES
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Defining the red planes physics body
    PlaneRed.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed.size)
    PlaneRed2.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed2.size)
    physicsWorld.contactDelegate = self
    physicsWorld.gravity = CGVector.zero
    func didBegin(contact: SKPhysicsContact){
        print("Game over")

    }
}








func Start(){
    //Defining an SKAction for the plane to orbit the center
    let OrbitCenter = SKAction.rotate(byAngle: CGFloat(-2), duration: 3.8)
    let Orbit = SKAction.repeatForever(OrbitCenter)
    //Creating the action for the center 2 to rotate anti clockwise
    let AntiOrbitCenter = SKAction.rotate(byAngle: CGFloat(2), duration: 3.8)
    let AntiOrbit = SKAction.repeatForever(AntiOrbitCenter)

    //Running the SKAction on the plane
    Center.run(Orbit)
    Center2.run(AntiOrbit)


}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?){
    for touch in touches{
    //Setting up the touch settings - these two variables store the nodes that the user has touched by first defining the location and then checking for nodes at this location
    let location = touch.location(in: self)
    let node = self.atPoint(location)


        if GameHasStarted == false{
            Start()
            GameHasStarted = true

        }





    }
}




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

【问题讨论】:

  • 您是否在代码中的某处执行此函数?
  • @maximilian_cs 正如他所说,由委托人执行。
  • 您是否将SKPhysicsContactDelegate 设置为self
  • 是的,我有 - 现在忘记添加了。我的代码中没有执行这个函数。
  • @LucasFarleigh你能在飞机上添加物理体的代码吗?

标签: swift sprite-kit


【解决方案1】:

第一

您的 didBegin 函数需要在 didMove 函数之外

override func didMove(to view: SKView) {
}

func didBegin(_ contact: SKPhysicsContact) {

    print("Game over")
}

您需要为您的对象设置一些物理类别,以便它们 知道他们可以碰撞什么,他们可以通过什么以及什么 碰撞无所谓。你可以把它放在你的课外 声明

//Game Physics
struct PhysicsCategory {
    static let plane: UInt32 = 0x1 << 0
    static let plane2: UInt32 = 0x1 << 1
    static let obstacle: UInt32 = 0x1 << 2
}

第三

您需要将这些物理装饰添加到您的对象中

    //Defining the red planes physics body
    PlaneRed.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed.size)
    PlaneRed.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneRed.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneRed.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneRed.physicsBody?.isDynamic = true

    PlaneRed2.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed2.size)
    PlaneRed2.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneRed2.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneRed2.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneRed2.physicsBody?.isDynamic = true

    PlaneBlue.physicsBody = SKPhysicsBody(rectangleOf: PlaneBlue.size)
    PlaneBlue.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneBlue.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneBlue.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneBlue.physicsBody?.isDynamic = true

    PlaneBlue2.physicsBody = SKPhysicsBody(rectangleOf: PlaneBlue2.size)
    PlaneBlue2.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneBlue2.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneBlue2.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneBlue2.physicsBody?.isDynamic = true

    self.physicsWorld.contactDelegate = self
    self.physicsWorld.gravity = CGVector.zero

【讨论】:

  • 为什么所有物理类别都设置为相同的值(0 x 1)
  • 它们看起来一样,但实际上并不相同。它们是位掩码您也可以将它们设置为 2 的幂次方 = 0,平面 2 = 1 障碍物 = 2,地面 = 4。更多可以在这里阅读stackoverflow.com/questions/24069703/…
  • 为什么我们需要对类别使用 UInt32?另外 - 我在不同的地方多次看到这个词位掩码。我知道一个非常基本的定义,但是我在很多地方都看到过它,例如 categoryBitMask - 普遍的基本定义是什么?
  • Lucas,我​​不是位掩码专家。我自己几乎不了解它们。如果你有一天可以投资,我建议你阅读它们,但这不是一个容易的主题
  • 好的,非常感谢,但是,为什么我在定义类别时需要添加静态,因为当我不添加时会出错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多