gpt4 book ai didi

swift - 如何在 Swift/SpriteKit 中检测与 2 个以上对象的碰撞

转载 作者:行者123 更新时间:2023-11-30 10:08:41 24 4
gpt4 key购买 nike

所以我正在创建一个空气曲棍球游戏,有 5 个主要的 SKSpriteNode。我需要检测冰球与 goal1 和 goal2 之间的碰撞。当它检测到碰撞时,需要将 SKLabelNode 的 ScoreLeft 或 ScoreRight 加 1。我使用了 Gamescene.sks 文件来进行视觉表示。我评论了 didBeginContact 因为那是它不起作用的地方。先感谢您。

class GameScene: SKScene, SKPhysicsContactDelegate {

let paddle1CategoryName = "paddle1"
let paddle2CategoryName = "paddle2"
let puckCategoryName = "puck"
let goal1CategoryName = "goal1"
let goal2CategoryName = "goal2"
let scoreLeftCategoryName = "scoreLeft"
let scoreRightCategoryName = "scoreRight"
var isFingerOnPaddle1 = false
var isFingerOnPaddle2 = false


var paddle1Category: UInt32 = 0x1 << 0
var paddle2Category: UInt32 = 0x1 << 1
var puckCategory: UInt32 = 0x1 << 2
var goal1Category: UInt32 = 0x1 << 3
var goal2Category: UInt32 = 0x1 << 4

override func didMoveToView(view: SKView) {
/* Setup your scene here */
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
borderBody.friction = 0
self.physicsBody = borderBody
let paddle1 = childNodeWithName(paddle1CategoryName) as! SKSpriteNode
let paddle2 = childNodeWithName(paddle2CategoryName) as! SKSpriteNode
let puck = childNodeWithName(puckCategoryName) as! SKSpriteNode
let goal1 = childNodeWithName(goal1CategoryName) as! SKSpriteNode
let goal2 = childNodeWithName(goal2CategoryName) as! SKSpriteNode
let scoreLeft = childNodeWithName(scoreLeftCategoryName) as! SKLabelNode
let scoreRight = childNodeWithName(scoreRightCategoryName) as! SKLabelNode

}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
var touch = touches.first! as UITouch
var location = touch.locationInNode(self)
if let body = physicsWorld.bodyAtPoint(location){
if body.node!.name == paddle1CategoryName {
print("The game has begun.")
isFingerOnPaddle1 = true
} else if body.node!.name == paddle2CategoryName{
print("The game has begun.")
isFingerOnPaddle2 = true
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let paddle1 = childNodeWithName(paddle1CategoryName) as! SKSpriteNode
let paddle2 = childNodeWithName(paddle2CategoryName) as! SKSpriteNode
let puck = childNodeWithName(puckCategoryName) as! SKSpriteNode
let goal1 = childNodeWithName(goal1CategoryName) as! SKSpriteNode
let goal2 = childNodeWithName(goal2CategoryName) as! SKSpriteNode
var touch = touches.first! as UITouch
var touchLocation = touch.locationInNode(self)
var previousLocation = touch.previousLocationInNode(self)



if isFingerOnPaddle1{

let paddle1X = paddle1.position.x + (touchLocation.x - previousLocation.x)
let paddle1Y = paddle1.position.y + (touchLocation.y - previousLocation.y)
if (touchLocation.x <= paddle1.position.x && (touchLocation.y <= paddle1.position.y || touchLocation.y >= paddle1.position.y)){
paddle1.position = CGPoint(x: paddle1X, y: paddle1Y)
}
}
if isFingerOnPaddle2{
let paddle2X = paddle2.position.x + (touchLocation.x - previousLocation.x)
let paddle2Y = paddle2.position.y + (touchLocation.y - previousLocation.y)

if (touchLocation.x >= paddle2X && (touchLocation.y >= paddle2Y || touchLocation.y < paddle2.position.y)){
paddle2.position = CGPoint(x: paddle2X, y: paddle2Y)
}
}

}
/*
func didBeginContact(contact: SKPhysicsContact) {
let scoreLeft = childNodeWithName(scoreLeftCategoryName) as! SKLabelNode
let scoreRight = childNodeWithName(scoreRightCategoryName) as! SKLabelNode
var score = 0
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask


switch contactMask{
case puckCategory | goal1Category:
if contact.bodyA.categoryBitMask == puckCategory{
puckCategory = contact.bodyA.categoryBitMask
goal1Category = contact.bodyB.categoryBitMask
score++
scoreRight.text = "\(score)"
}else{
puckCategory = contact.bodyB.categoryBitMask
goal1Category = contact.bodyA.categoryBitMask
score++
scoreRight.text = "\(score)"
}
case puckCategory | goal2Category:
if contact.bodyA.categoryBitMask == puckCategory{
puckCategory = contact.bodyA.categoryBitMask
goal2Category = contact.bodyB.categoryBitMask
score++
scoreLeft.text = "\(score)"
}else{
puckCategory = contact.bodyB.categoryBitMask
goal2Category = contact.bodyA.categoryBitMask
score++
scoreLeft.text = "\(score)"
}
default:

// Nobody expects this, so satisfy the compiler and catch
// ourselves if we do something we didn't plan to
fatalError("other collision: \(contactMask)")

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

}

最佳答案

一个问题是在函数开头使用本地 var Score = 0。去掉它。分数应该存储在游戏的模型中,以便可以应用有关获胜的逻辑,但要匹配您的代码,至少这样做。

if let score = Int(scoreLeft.text) {
scoreLeft.text = "\(score + 1)"
}

另外还有一个问题

  case puckCategory | goal1Category:
if contact.bodyA.categoryBitMask == puckCategory{
puckCategory = contact.bodyA.categoryBitMask

你的意思是,如果contact.bodyA.categoryBitMask等于puckCategory,则将puckCategory设置为contact.bodyA .categoryBitMask。这是一个无操作,没有任何变化,更重要的是,您不想更改与子节点进行比较的位掩码。使 puckCategorygoal1Categoygoal2Category 常量。祝你好运。

跟进 OP 评论:

因此,出于两个原因,丢弃 didBeginContact 中设置类别掩码变量的代码。 1)将像puckCategory这样的变量设置为相同的值是浪费和困惑的。 2) 由于像 puckCategory 这样的变量是与子节点位掩码进行比较的,因此如果它们确实发生变化,那将是灾难性的。该函数应该如下所示。另外,请确保在您走得太远之前为其他类型的联系人添加处理程序。

func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

switch contactMask {
case puckCategory | goal1Category:
let scoreRight = childNodeWithName(scoreRightCategoryName) as! SKLabelNode
if let score = Int(scoreRight.text) {
scoreRight.text = "\(score + 1)"
}
case puckCategory | goal2Category:
let scoreLeft = childNodeWithName(scoreLeftCategoryName) as! SKLabelNode
if let score = Int(scoreLeft.text) {
scoreLeft.text = "\(score + 1)"
}
default:
// There are other contacts that need to be handled; paddle+puck,puck+wall, etc
fatalError("other collision: \(contactMask)")
}
}

关于swift - 如何在 Swift/SpriteKit 中检测与 2 个以上对象的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34472696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com