我想知道我的碰撞检测在做什么错。我正在尝试制作一个游戏,其中用户使用虚拟操纵杆控制角色并尝试捕捉从屏幕顶部掉下的甜甜圈。操纵杆有效且使甜甜圈掉落有效,但是当两个对象碰撞时,分数不会更新,并且甜甜圈位置也不会像我希望的那样重置为其默认位置。我看过一些教程,但似乎找不到我的错误。
import SpriteKit
import GameplayKit
struct BodyType {
static let Character: UInt32 = 1
static let Knife: UInt32 = 2
static let Donut: UInt32 = 4
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var score: Int = 0
var level: Int = 0
var scoreLabel: SKLabelNode = SKLabelNode(text: "Score: 0")
var BoostButton: SKSpriteNode = SKSpriteNode(imageNamed: "boost")
var Knife: SKSpriteNode = SKSpriteNode(imageNamed: "knife")
var Donut: SKSpriteNode = SKSpriteNode(imageNamed: "donut")
var velocityMultiplier: CGFloat = 0.15
var BoostActive: Bool = false
var KnifeVel: CGFloat = 3
var KnifeX: CGFloat = 0
var KnifeY: CGFloat = 0
var FoodX: CGFloat = 0
var FoodY: CGFloat = 0
var FoodVel: CGFloat = 3
enum NodesZPosition: CGFloat {
case Character, joystick
}
var Character: SKSpriteNode = SKSpriteNode(imageNamed: "character")
var analogJoystick: AnalogJoystick = {
let js = AnalogJoystick(diameter: 90, images: (UIImage(named: "substrate"), UIImage(named: "stick")))
js.position = CGPoint(x: 480, y: 75)
js.zPosition = NodesZPosition.joystick.rawValue
return js
}()
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
backgroundColor = UIColor.blue
self.anchorPoint = CGPoint(x: 0, y: 0)
Character.position = CGPoint(x: 100,y: 200)
Character.size = Donut.size
Character.physicsBody = SKPhysicsBody(texture: Character.texture!, size: Character.size)
Character.physicsBody?.affectedByGravity = false
Character.name = "Character"
Character.physicsBody?.isDynamic = true
Character.physicsBody?.categoryBitMask = BodyType.Character
Character.physicsBody?.collisionBitMask = BodyType.Knife | BodyType.Donut
Character.physicsBody?.contactTestBitMask = BodyType.Knife | BodyType.Donut
self.addChild(Character)
self.addChild(BoostButton)
BoostButton.position = CGPoint(x: 75, y: 75)
Knife.position = CGPoint(x: self.frame.width + 100, y: 200)
Knife.name = "Knife"
self.addChild(Knife)
Donut.position = CGPoint(x: 200, y: self.frame.height + 150)
Donut.name = "Donut"
self.addChild(Donut)
scoreLabel.position = CGPoint(x: 65, y: self.frame.height - 40)
scoreLabel.fontSize = 30
scoreLabel.fontColor = UIColor.black
self.addChild(scoreLabel)
setupJoystick()
let border = SKPhysicsBody(edgeLoopFrom: self.frame)
border.friction = 0
self.physicsBody = border
}
func setupJoystick (){
addChild(analogJoystick)
analogJoystick.trackingHandler = {[unowned self] data in
self.Character.position = CGPoint(x: self.Character.position.x + (data.velocity.x * self.velocityMultiplier),y: self.Character.position.y + (data.velocity.y * self.velocityMultiplier))
self.Character.zRotation = data.angular
}
}
private func didBegin(_ contact: SKPhysicsContact) {
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
if contact.bodyA.node?.name == "Character" {
firstBody = contact.bodyA
secondBody = contact.bodyB
}
else{
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.node?.name == "Character" && secondBody.node?.name == "Donut"{
print("collison")
score += 20
scoreLabel.text = "Score \(score)"
Donut.position.y = self.frame.height + 150
Donut.position.x = CGFloat.random(in: 100..<(self.frame.width - 100))
}
else if firstBody.node?.name == "Donut" && secondBody.node?.name == "Character"{
print("collison")
score += 20
scoreLabel.text = "Score \(score)"
Donut.position.y = self.frame.height + 150
Donut.position.x = CGFloat.random(in: 100..<(self.frame.width - 100))
}
}
func touchDown(atPoint pos : CGPoint) {
}
func touchMoved(toPoint pos : CGPoint) {
}
func touchUp(atPoint pos : CGPoint) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ){
let location = touch.location(in: self)
if (BoostButton.frame.contains(location)){
BoostActive = true
}
else{
BoostActive = false
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func update(_ currentTime: TimeInterval) {
// if (BoostActive == true){
// velocityMultiplier = velocityMultiplier * 1.5
// }
// else{
// velocityMultiplier = 0.15
//}
FoodY = Donut.position.y
KnifeX = Knife.position.x
if (Knife.position.x < (self.frame.width - 20) && Knife.position.x > 20){
Knife.physicsBody = SKPhysicsBody(texture: Knife.texture!, size: Knife.size)
Knife.physicsBody?.affectedByGravity = false
Knife.physicsBody?.restitution = 0
Knife.physicsBody?.pinned = false
Knife.physicsBody?.isDynamic = true
Knife.physicsBody?.allowsRotation = false
Knife.physicsBody?.categoryBitMask = BodyType.Knife
Knife.physicsBody?.collisionBitMask = BodyType.Character
Knife.physicsBody?.contactTestBitMask = BodyType.Character
}
else{
Knife.physicsBody = nil
}
if (Donut.position.y < self.frame.height && Donut.position.y > 50){
Donut.physicsBody = SKPhysicsBody(texture: Donut.texture!, size: Donut.size)
Donut.physicsBody?.affectedByGravity = false
Donut.physicsBody?.isDynamic = false
Donut.physicsBody?.categoryBitMask = BodyType.Donut
Donut.physicsBody?.collisionBitMask = BodyType.Character
Donut.physicsBody?.contactTestBitMask = BodyType.Character
}
else{
Donut.physicsBody = nil
}
if (FoodY < 30){
Donut.position.y = self.frame.height + 150
Donut.position.x = CGFloat.random(in: 100..<(self.frame.width - 100))
}
else{
Donut.position.y = Donut.position.y - FoodVel
}
if (KnifeX < 0){
Knife.position.x = self.frame.width + 150
Knife.position.y = CGFloat.random(in: 50..<(self.frame.height - 50))
}
else{
Knife.position.x = Knife.position.x - KnifeVel
}
}
}