1
我想创建写在斯威夫特3.让碰撞的正常工作目前遇到了困难射击游戏。如果子弹击中敌人,我需要发生爆炸,然后从游戏中移除特定的敌人和子弹。如果玩家击中敌人,我需要在两者之间发生爆炸,然后从屏幕上移除特定的敌人和玩家,并将其命名为gameover。这是我到目前为止,子弹只是反弹而没有发生碰撞。任何帮助是极大的赞赏。
import SpriteKit
import GameplayKit
enum CollisonType: UInt32 {
case player = 1
case ammo = 2
case enemy = 4
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var starfield: SKEmitterNode!
var player: SKSpriteNode!
var ammo: SKSpriteNode!
var enemy: SKSpriteNode!
var gameScore: SKLabelNode!
var score: Int = 0 {
didSet { // didSet a property observer used to update gameScore
gameScore.text = "Score: \(score)"
}
}
var possibleEnemies = ["ball", "hammer", "tv"]
var gameTimer: Timer! // Used to create enemies regularly.
var isGameOver = false // a boolean that will be set to true when we should stop increasing the player's score
override func didMove(to view: SKView) {
backgroundColor = UIColor.black
starfield = SKEmitterNode(fileNamed: "Starfield")!
starfield.position = CGPoint(x: 1024, y: 384)
starfield.advanceSimulationTime(10)
addChild(starfield)
starfield.zPosition = -1
player = SKSpriteNode(imageNamed: "player")
player.position = CGPoint(x: 100, y: 384)
player.physicsBody = SKPhysicsBody(texture: player.texture!, size: player.size)
player.physicsBody!.categoryBitMask = CollisonType.player.rawValue
player.physicsBody!.contactTestBitMask = CollisonType.enemy.rawValue
addChild(player)
gameScore = SKLabelNode(fontNamed: "Chalkduster")
gameScore.text = "Score: 0"
gameScore.horizontalAlignmentMode = .left
gameScore.position = CGPoint(x: 8, y: 8)
addChild(gameScore)
physicsWorld.gravity = CGVector(dx: 0, dy: 0)
physicsWorld.contactDelegate = self
gameTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
gameTimer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(createAmmo), userInfo: nil, repeats: true)
}
func createAmmo() {
if isGameOver {
return
}
ammo = SKSpriteNode(imageNamed: "bullet")
ammo.name = "ammo"
ammo.position = CGPoint(x: player.position.x + 100, y: player.position.y)
addChild(ammo)
ammo.physicsBody = SKPhysicsBody(texture: ammo.texture!, size: ammo.size)
ammo.physicsBody!.categoryBitMask = CollisonType.ammo.rawValue
ammo.physicsBody!.contactTestBitMask = CollisonType.enemy.rawValue
ammo.physicsBody!.velocity = CGVector(dx: 900, dy: 0)
ammo.physicsBody!.linearDamping = 0
ammo.physicsBody!.angularDamping = 0
}
func createEnemy() {
possibleEnemies = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: possibleEnemies) as! [String]
let randomDistribution = GKRandomDistribution(lowestValue: 50, highestValue: 736)
enemy = SKSpriteNode(imageNamed: possibleEnemies[0])
enemy.name = "enemy"
enemy.position = CGPoint(x: 1200, y: randomDistribution.nextInt())
addChild(enemy)
enemy.physicsBody = SKPhysicsBody(texture: enemy.texture!, size: enemy.size)
enemy.physicsBody!.categoryBitMask = CollisonType.enemy.rawValue
enemy.physicsBody!.contactTestBitMask = CollisonType.player.rawValue | CollisonType.ammo.rawValue
enemy.physicsBody!.velocity = CGVector(dx: -300, dy: 0)
enemy.physicsBody!.angularVelocity = 5
enemy.physicsBody!.linearDamping = 0
enemy.physicsBody!.angularDamping = 0
}
override func update(_ currentTime: TimeInterval) {
for node in children {
if node.position.x < -300 || node.position.x > 1300 || node.position.y < -300 || node.position.y > 1000 {
node.removeFromParent()
}
}
if !isGameOver {
score += 1
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
var location = touch.location(in: self)
if location.y < 50 {
location.y = 50
} else if location.y > 730 {
location.y = 730
}
player.position = location
}
func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.node == player {
playerCollided(with: contact.bodyB.node!)
} else if contact.bodyB.node == player {
playerCollided(with: contact.bodyA.node!)
}
if contact.bodyA.node == ammo {
ammoCollided(with: contact.bodyB.node!)
} else if contact.bodyB.node == ammo {
ammoCollided(with: contact.bodyA.node!)
}
}
func playerCollided(with node:SKNode) {
if node.name == "enemy" {
let explosion = SKEmitterNode(fileNamed: "explosion")!
explosion.position = enemy.position
addChild(explosion)
player.removeFromParent()
enemy.removeFromParent()
isGameOver = true
}
}
func ammoCollided(with node:SKNode) {
if node.name == "enemy" {
let explosion = SKEmitterNode(fileNamed: "explosion")!
explosion.position = enemy.position
addChild(explosion)
ammo.removeFromParent()
enemy.removeFromParent()
}
}
}
我想你的建议,但它仍然完全不起作用。碰撞后只有3/4的子弹消失(有些仍然会弹跳),以及玩家。但敌人永远不会消失。爆炸也不会发生。爆炸只会偶尔发生在iPad的右侧(超出玩家可见范围)。我会尝试按照您提供的教程链接进行操作。谢谢。 – Soja
我跟着教程链接,并能解决我的问题。再次感谢@eSpecialized! – Soja