作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个用 Swift 3 编写的射击游戏。目前很难让碰撞正常工作。如果子弹击中敌人,我需要发生爆炸,然后从游戏中移除该特定敌人和子弹。如果玩家击中敌人,我需要在两者之间发生爆炸,然后将特定的敌人和玩家从屏幕上移除并称之为游戏结束。到目前为止,这就是我所拥有的,子弹只是在没有发生碰撞的情况下弹跳。非常感谢任何帮助。
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()
}
}
}
最佳答案
改为尝试类似的方法,并重构您的 ___Collided 代码以进行调整。
不要测试节点相等性。使用名称或 .categoryBitMask 来确定它是哪种节点。
获取本教程中的categoryBitMask; https://www.raywenderlich.com/145318/spritekit-swift-3-tutorial-beginners
或者试试这个;
player.name = "player1"
func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.node.name == "player1" {
playerCollided(with: contact.bodyB.node!)
} else if contact.node.name == "player1" {
playerCollided(with: contact.bodyA.node!)
}
if contact.bodyA.node.name == "ammo" {
ammoCollided(with: contact.bodyB.node!)
} else if contact.node.name == "ammo" {
ammoCollided(with: contact.bodyA.node!)
}
}
关于Swift 3 太空射击游戏 : Issue with bullet collision,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40724576/
我是一名优秀的程序员,十分优秀!