0
我是新來編碼,所以要友好。我在Swift 3中創建了一個類似於Flappy Bird的遊戲,並且對我的分數節點有問題。我爲分數創建了一個標籤節點,但是當玩家聯繫scoreDetect節點時沒有添加分數。我無法確定是否編寫了錯誤地添加點或者物理代碼不正確的部分。任何幫助表示讚賞。謝謝。Swift 3更新標籤節點與整數遞增
import SpriteKit
import GameplayKit
struct PhysicsCategory {
static let player : UInt32 = 0x1 << 1
static let roof : UInt32 = 0x1 << 2
static let floor : UInt32 = 0x1 << 3
static let lowerObstacle : UInt32 = 0x1 << 4
static let upperObstacle : UInt32 = 0x1 << 5
static let scoreDetect : UInt32 = 0x1 << 6
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var bgColor = UIColor(red: 39/255, green: 41/255, blue: 56/255, alpha: 1.0)
var roof = SKSpriteNode()
var floor = SKSpriteNode()
var lowerObstacle = SKSpriteNode()
var upperObstacle = SKSpriteNode()
var player = SKSpriteNode()
var randomValue = Int()
var scoreDetect = SKSpriteNode()
var scoreLabel = SKLabelNode()
var scoreValue = Int()
var logo = SKSpriteNode()
var gameStarted = Bool()
override func didMove(to view: SKView) {
createPlayer()
createTiles()
createScoreLabel()
physicsWorld.contactDelegate = self
self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -4.0)
backgroundColor = bgColor
let delay = SKAction.wait(forDuration: 3)
let repeatingAction = SKAction.run(repeatingSequence)
let sequence = SKAction.sequence([ delay, repeatingAction ])
run(SKAction.repeatForever(sequence))
}
// Random Selector For Obstacles
func randomSelector() -> Int {
let array = [1, 2, 3]
return Int(arc4random_uniform(UInt32(array.count)))
}
// Player Rules
func createPlayer() {
player = SKSpriteNode(imageNamed: "Player")
player.setScale(0.4)
player.position = CGPoint(x: -player.size.width, y: 0)
player.zPosition = 2
addChild(player)
player.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Player"), size: player.size)
player.physicsBody?.categoryBitMask = PhysicsCategory.player
player.physicsBody?.collisionBitMask = PhysicsCategory.roof | PhysicsCategory.floor | PhysicsCategory.upperObstacle | PhysicsCategory.lowerObstacle | PhysicsCategory.scoreDetect
player.physicsBody?.contactTestBitMask = PhysicsCategory.roof | PhysicsCategory.floor | PhysicsCategory.upperObstacle | PhysicsCategory.lowerObstacle | PhysicsCategory.scoreDetect
player.physicsBody?.allowsRotation = false
player.physicsBody?.affectedByGravity = true
player.physicsBody?.isDynamic = false
}
// Create Background
func createTiles() {
roof = SKSpriteNode(imageNamed: "Roof")
roof.position = CGPoint(x: 0, y: self.frame.height/2 - roof.size.height/2)
roof.zPosition = 1
addChild(roof)
roof.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Roof"), size: roof.size)
roof.physicsBody?.categoryBitMask = PhysicsCategory.roof
roof.physicsBody?.collisionBitMask = PhysicsCategory.player
roof.physicsBody?.contactTestBitMask = PhysicsCategory.player
roof.physicsBody?.allowsRotation = false
roof.physicsBody?.affectedByGravity = false
roof.physicsBody?.isDynamic = false
floor = SKSpriteNode(imageNamed: "Floor")
floor.position = CGPoint(x: 0, y: -self.frame.height/2)
floor.zPosition = 1
addChild(floor)
floor.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Floor"), size: floor.size)
floor.physicsBody?.categoryBitMask = PhysicsCategory.floor
floor.physicsBody?.collisionBitMask = PhysicsCategory.player
floor.physicsBody?.contactTestBitMask = PhysicsCategory.player
floor.physicsBody?.allowsRotation = false
floor.physicsBody?.affectedByGravity = false
floor.physicsBody?.isDynamic = false
}
// Obstacle Spawn Rules
func createObstacle() {
if (randomSelector() == 1) {
lowerObstacle = SKSpriteNode(imageNamed: "Fire Barrel 1")
upperObstacle = SKSpriteNode(imageNamed: "Fire Barrel 3")
scoreDetect = SKSpriteNode(color: UIColor.red, size: CGSize(width: 32, height: frame.height))
upperObstacle.position = CGPoint(x: self.frame.width/2 + upperObstacle.size.width/2, y: self.frame.height/2 - upperObstacle.size.height/2 + 12)
lowerObstacle.position = CGPoint(x: self.frame.width/2 + lowerObstacle.size.width/2, y: -self.frame.height/2 + lowerObstacle.size.height - 15)
scoreDetect.position = CGPoint(x: self.frame.width/2 + upperObstacle.size.width, y: 0)
}
else {
if (randomSelector() == 2) {
lowerObstacle = SKSpriteNode(imageNamed: "Fire Barrel 2")
upperObstacle = SKSpriteNode(imageNamed: "Fire Barrel 2")
scoreDetect = SKSpriteNode(color: UIColor.red, size: CGSize(width: 32, height: frame.height))
upperObstacle.position = CGPoint(x: self.frame.width/2 + upperObstacle.size.width/2, y: self.frame.height/2 - upperObstacle.size.height/1.9)
lowerObstacle.position = CGPoint(x: self.frame.width/2 + lowerObstacle.size.width/2, y: -self.frame.height/2 + lowerObstacle.size.height/1.5)
scoreDetect.position = CGPoint(x: self.frame.width/2 + upperObstacle.size.width, y: 0)
}
else {
lowerObstacle = SKSpriteNode(imageNamed: "Fire Barrel 3")
upperObstacle = SKSpriteNode(imageNamed: "Fire Barrel 1")
scoreDetect = SKSpriteNode(color: UIColor.red, size: CGSize(width: 32, height: frame.height))
upperObstacle.position = CGPoint(x: self.frame.width/2 + upperObstacle.size.width/2, y: self.frame.height/2 - upperObstacle.size.height/1.5 + 4)
lowerObstacle.position = CGPoint(x: self.frame.width/2 + lowerObstacle.size.width/2, y: -self.frame.height/2 + lowerObstacle.size.height/1.75 + 7)
scoreDetect.position = CGPoint(x: self.frame.width/2 + upperObstacle.size.width, y: 0)
}
}
lowerObstacle.zPosition = 2
lowerObstacle.setScale(0.8)
lowerObstacle.physicsBody = SKPhysicsBody(rectangleOf: lowerObstacle.size)
lowerObstacle.physicsBody?.categoryBitMask = PhysicsCategory.lowerObstacle
lowerObstacle.physicsBody?.collisionBitMask = PhysicsCategory.player
lowerObstacle.physicsBody?.contactTestBitMask = PhysicsCategory.player
lowerObstacle.physicsBody?.allowsRotation = false
lowerObstacle.physicsBody?.affectedByGravity = false
lowerObstacle.physicsBody?.isDynamic = false
upperObstacle.zPosition = 2
upperObstacle.setScale(0.8)
upperObstacle.physicsBody = SKPhysicsBody(rectangleOf: upperObstacle.size)
upperObstacle.physicsBody?.categoryBitMask = PhysicsCategory.upperObstacle
upperObstacle.physicsBody?.collisionBitMask = PhysicsCategory.player
upperObstacle.physicsBody?.contactTestBitMask = PhysicsCategory.player
upperObstacle.physicsBody?.allowsRotation = false
upperObstacle.physicsBody?.affectedByGravity = false
upperObstacle.physicsBody?.isDynamic = false
scoreDetect.physicsBody?.categoryBitMask = PhysicsCategory.scoreDetect
scoreDetect.physicsBody?.collisionBitMask = PhysicsCategory.player
scoreDetect.physicsBody?.contactTestBitMask = PhysicsCategory.player
scoreDetect.physicsBody?.allowsRotation = false
scoreDetect.physicsBody?.affectedByGravity = false
scoreDetect.physicsBody?.isDynamic = false
addChild(lowerObstacle)
addChild(upperObstacle)
addChild(scoreDetect)
lowerObstacle.run(
SKAction.sequence([
SKAction.wait(forDuration: 6),
SKAction.removeFromParent()
])
)
upperObstacle.run(
SKAction.sequence([
SKAction.wait(forDuration: 6),
SKAction.removeFromParent()
])
)
scoreDetect.run(
SKAction.sequence([
SKAction.wait(forDuration: 6),
SKAction.removeFromParent()
])
)
}
// Create Spawn and Move Sequence
func repeatingSequence() {
createObstacle()
let moveLowerObstacle = SKAction.moveBy(x: -self.frame.width - lowerObstacle.size.width * 2, y: 0, duration: 5)
lowerObstacle.run(moveLowerObstacle)
let moveUpperObstacle = SKAction.moveBy(x: -self.frame.width - upperObstacle.size.width * 2, y: 0, duration: 5)
upperObstacle.run(moveUpperObstacle)
let moveScoreDetect = SKAction.moveBy(x: -self.frame.width - upperObstacle.size.width * 2, y: 0, duration: 5)
scoreDetect.run(moveScoreDetect)
}
func createScoreLabel() {
scoreLabel = SKLabelNode(fontNamed: "Arial")
scoreLabel.fontSize = 22
scoreLabel.position = CGPoint(x: 305, y: -638)
scoreLabel.horizontalAlignmentMode = .center
scoreLabel.verticalAlignmentMode = .center
scoreLabel.text = "SCORE: \(scoreValue)"
scoreLabel.fontColor = UIColor.white
scoreLabel.zPosition = 4
addChild(scoreLabel)
}
func didBegin(_ contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == PhysicsCategory.scoreDetect && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.scoreDetect {
scoreValue += 1
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
player.physicsBody?.isDynamic = true
let impulse = CGVector(dx: 0, dy: 200)
player.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
player.physicsBody?.applyImpulse(impulse)
}
override func update(_ currentTime: TimeInterval) {
}
}
感謝您的迴應。我已經做出了你所建議的改變,但它仍然不能按預期工作,這使我相信也許錯誤與檢測本身有關? –
繼續我的最後,我注意到'scoreDetect'節點沒有分配物理體來解決問題。但是,現在發生碰撞時,每次檢測到碰撞時,得分值都會上升到大約35。有任何想法嗎? –
@MartinJones:因爲func didBegin(_ contact:SKPhysicsContact)'可以在兩個物體碰撞時被多次調用。 [看這個](http://stackoverflow.com/questions/24228274/why-are-didbegincontact-called-multiple-times/38364703#38364703)。 –