didBeginContact没有被称为斯威夫特
我正在研究一个应用程序,当*球颜色匹配一个较小的球,正在朝*球颜色飞行球员得分。 所以为了这个工作,我需要didBeginContact函数来调用“敌人”和“mainBall”相撞的时候。唯一移动的是敌方球,因为它飞向固定的主球体 我相信我已经正确设置了位掩码,但didBeginContact函数没有被调用。 有人可以帮忙吗?didBeginContact没有被称为斯威夫特
这里是我的代码
struct bitMasks{
static let mainBallMask:UInt32 = 0x1 << 0
static let enemyBall:UInt32 = 0x1 << 1
}
class GameScene: SKScene,SKPhysicsContactDelegate {
var mainBall = SKSpriteNode()
var ballSetToMainColor = true
var enemyTimer = Timer()
var hits = 0
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
mainBall = childNode(withName: "centralBall") as! SKSpriteNode
mainBall.zPosition = 1.0
mainBall.physicsBody = SKPhysicsBody(circleOfRadius: mainBall.size.width/2)
mainBall.physicsBody?.categoryBitMask = bitMasks.mainBallMask
mainBall.physicsBody?.collisionBitMask = bitMasks.enemyBall
mainBall.physicsBody?.contactTestBitMask = bitMasks.enemyBall
mainBall.physicsBody?.isDynamic = false
mainBall.physicsBody?.affectedByGravity = false
enemyTimer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(enemies), userInfo: nil, repeats: true)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesCheckForChangedBall(touches: touches)
}
func didBegin(_ contact: SKPhysicsContact) {
let firstBody = contact.bodyA.node as! SKSpriteNode
let secondBody = contact.bodyB.node as! SKSpriteNode
if firstBody.name == "enemy" && secondBody.name == "centralBall"{
collisionMain(enemy: firstBody)
}else if firstBody.name == "centralBall" && secondBody.name == "enemy"{
collisionMain(enemy: secondBody)
}
}
func collisionMain(enemy: SKSpriteNode){
hits += 1
enemy.removeAllActions()
enemy.removeFromParent()
print(hits)
}
func touchesCheckForChangedBall(touches: Set<UITouch>){
for t in touches {
let location = t.location(in: self)
let nodes = self.nodes(at: location)
if nodes.isEmpty == false {
if let name = nodes[0].name{
if name == "centralBall"{
changeMainBallColor()
}
}
}
}
}
func changeMainBallColor(){
ballSetToMainColor = !ballSetToMainColor
if ballSetToMainColor == true{
mainBall.texture = SKTexture(imageNamed: "ball-mainColor")
}else{
mainBall.texture = SKTexture(imageNamed: "ball-secondaryColor")
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
func getRandomImageColor()->String{
let randVal = arc4random_uniform(2)
if randVal == 0{
return "ball-secondaryColor"
}else{
return "ball-mainColor"
}
}
func enemies(){
let color = getRandomImageColor()
let enemy = SKSpriteNode(imageNamed: color)
enemy.size = CGSize(width: 30, height: 30)
enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.size.width/2)
enemy.physicsBody?.categoryBitMask = bitMasks.enemyBall
enemy.physicsBody?.collisionBitMask = bitMasks.mainBallMask
enemy.physicsBody?.contactTestBitMask = bitMasks.mainBallMask
enemy.name = "enemyBall"
enemy.physicsBody?.isDynamic = true
enemy.physicsBody?.affectedByGravity = false
let randomPositionNumber = arc4random() % 3
switch randomPositionNumber{
case 0:
enemy.position.x = 0
let posY = arc4random_uniform(UInt32(frame.size.height))
enemy.position.y = CGFloat(posY)
self.addChild(enemy)
break
case 1:
enemy.position.y = frame.size.height
let posX = arc4random_uniform(UInt32(frame.size.width))
enemy.position.x = CGFloat(posX)
self.addChild(enemy)
break
case 2:
enemy.position.x = frame.size.width
let posY = arc4random_uniform(UInt32(frame.size.height))
enemy.position.y = CGFloat(posY)
self.addChild(enemy)
break
default:
break
}
enemy.run(SKAction.move(to: mainBall.position, duration: 3))
}
}
正如上面提到,似乎你有拼写错误的节点名称。您在碰撞方法中寻找“敌人”,但将您的敌人命名为“enemyBall”。这就是为什么我们应该总是创建常量来避免这种情况
let enemyName = "Enemy"
,比使用它像这样
enemy.name = enemyName
您也可以尝试写你的碰撞方法就是这样,这将使我们更好小幅阅读,你只需要1如果每次碰撞声明。这种方式也不需要节点名称来比较物体。
func didBegin(_ contact: SKPhysicsContact) {
let firstBody: SKPhysicsBody
let secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
// Main ball with enemy or enemy with main ball
if (firstBody.categoryBitMask == bitMasks.mainBall) && (secondBody.categoryBitMask == bitMasks.enemy) {
// do something
}
}
我也试着按照快速指导,类,枚举和结构应该以大写字母开头。
希望这有助于
他已经说过mainball不会移动,因此将它设置为动态为true服务无效 – Knight0fDragon
问题是他命名了他的敌人“enemyBall”,但看了他的didBeginContact字的“敌人”。
这就是为什么它是一个糟糕的主意,用字符串比较(以及它比其他比较慢)
我会建议先检查categoryBitmask,其次是名或类视具体怎么的检查你的需要。
您将动态设置为false,任何移动并需要物理的对象必须将此设置为true – Knight0fDragon
@ Knight0fDragon移动的唯一东西就是敌人球抱歉,我应该明确地说明我将编辑问题 – spies9149
你命名敌人'enemyBall',但你的联系人正在寻找'敌人' – Knight0fDragon