-3

我正在开发一个项目/游戏,我一直在为游戏添加新敌人并对其进行编程。这就是我的代码在我开始更改之前的样子,并且只有一种“外星人”。我想创建两种新类型,一种是你因击球而失去 5 分,另一种是 10 分。在现在的代码中,只有三种类型中的一种,它给出 +5 分。各位大佬怎么加两个新的?我想我想多了,这就是我搞砸的原因。

import SpriteKit
import GameplayKit
import CoreMotion

class GameScene: SKScene, SKPhysicsContactDelegate {

    var starfield:SKEmitterNode!
    var player:SKSpriteNode!

    var scoreLabel:SKLabelNode!
    var score:Int = 0 {
        didSet {
            scoreLabel.text = "Score: \(score)"
        }
    }

    var gameTimer:Timer!

    var possibleAliens = ["alien"]
    //This is the "alien you earn +5 point from shooting. Im trying to get 2 new aliens to the scene, one that you lose -5 points from shooting and one you lose -10 on.
    //I have tried to rewrite the codes to the two new, but they still earn +5 points from shooting all 3 types. What would you guys do and how?

    let alienCategory:UInt32 = 0x1 << 1
    let photonTorpedoCategory:UInt32 = 0x1 << 0


    let motionManger = CMMotionManager()
    var xAcceleration:CGFloat = 0

    override func didMove(to view: SKView) {

        starfield = SKEmitterNode(fileNamed: "Starfield")
        starfield.position = CGPoint(x: 0, y: 1472)
        starfield.advanceSimulationTime(10)
        self.addChild(starfield)

        starfield.zPosition = -1

        player = SKSpriteNode(imageNamed: "shuttle")

        player.position = CGPoint(x: self.frame.size.width / 2, y: player.size.height / 2 + 20)

        self.addChild(player)

        self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        self.physicsWorld.contactDelegate = self

        scoreLabel = SKLabelNode(text: "Score: 0")
        scoreLabel.position = CGPoint(x: 100, y: self.frame.size.height - 60)
        scoreLabel.fontName = "AmericanTypewriter-Bold"
        scoreLabel.fontSize = 36
        scoreLabel.fontColor = UIColor.white
        score = 0

        self.addChild(scoreLabel)


        gameTimer = Timer.scheduledTimer(timeInterval: 0.75, target: self, selector: #selector(addAlien), userInfo: nil, repeats: true)


        motionManger.accelerometerUpdateInterval = 0.2
        motionManger.startAccelerometerUpdates(to: OperationQueue.current!) { (data:CMAccelerometerData?, error:Error?) in
            if let accelerometerData = data {
                let acceleration = accelerometerData.acceleration
                self.xAcceleration = CGFloat(acceleration.x) * 0.75 + self.xAcceleration * 0.25
            }
        }
    }

    func addAlien () {
        possibleAliens = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: possibleAliens) as! [String]

        let alien = SKSpriteNode(imageNamed: possibleAliens[0])

        let randomAlienPosition = GKRandomDistribution(lowestValue: 0, highestValue: 414)
        let position = CGFloat(randomAlienPosition.nextInt())

        alien.position = CGPoint(x: position, y: self.frame.size.height + alien.size.height)

        alien.physicsBody = SKPhysicsBody(rectangleOf: alien.size)
        alien.physicsBody?.isDynamic = true

        alien.physicsBody?.categoryBitMask = alienCategory
        alien.physicsBody?.contactTestBitMask = photonTorpedoCategory
        alien.physicsBody?.collisionBitMask = 0

        self.addChild(alien)

        let animationDuration:TimeInterval = 6

        var actionArray = [SKAction]()

        actionArray.append(SKAction.move(to: CGPoint(x: position, y: -alien.size.height), duration: animationDuration))
        actionArray.append(SKAction.removeFromParent())

        alien.run(SKAction.sequence(actionArray))
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        fireTorpedo()
    }

    func fireTorpedo() {
        self.run(SKAction.playSoundFileNamed("torpedo.mp3", waitForCompletion: false))

        let torpedoNode = SKSpriteNode(imageNamed: "torpedo")
        torpedoNode.position = player.position
        torpedoNode.position.y += 5

        torpedoNode.physicsBody = SKPhysicsBody(circleOfRadius: torpedoNode.size.width / 2)
        torpedoNode.physicsBody?.isDynamic = true

        torpedoNode.physicsBody?.categoryBitMask = photonTorpedoCategory
        torpedoNode.physicsBody?.contactTestBitMask = alienCategory
        torpedoNode.physicsBody?.collisionBitMask = 0
        torpedoNode.physicsBody?.usesPreciseCollisionDetection = true

        self.addChild(torpedoNode)

        let animationDuration:TimeInterval = 0.3

        var actionArray = [SKAction]()

        actionArray.append(SKAction.move(to: CGPoint(x: player.position.x, y: self.frame.size.height + 10), duration: animationDuration))
        actionArray.append(SKAction.removeFromParent())

        torpedoNode.run(SKAction.sequence(actionArray))
    }

    func didBegin(_ contact: SKPhysicsContact) {
        var firstBody:SKPhysicsBody
        var secondBody:SKPhysicsBody

        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        }else{
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }

        if (firstBody.categoryBitMask & photonTorpedoCategory) != 0 && (secondBody.categoryBitMask & alienCategory) != 0 {
           torpedoDidCollideWithAlien(torpedoNode: firstBody.node as! SKSpriteNode, alienNode: secondBody.node as! SKSpriteNode)
        }

    }

    func torpedoDidCollideWithAlien (torpedoNode:SKSpriteNode, alienNode:SKSpriteNode) {

        let explosion = SKEmitterNode(fileNamed: "Explosion")!
        explosion.position = alienNode.position
        self.addChild(explosion)

        self.run(SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: false))

        torpedoNode.removeFromParent()
        alienNode.removeFromParent()

        self.run(SKAction.wait(forDuration: 2)) { 
            explosion.removeFromParent()
        }

        score += 5
    }

    override func didSimulatePhysics() {
        player.position.x += xAcceleration * 50

        if player.position.x < -20 {
            player.position = CGPoint(x: self.size.width + 20, y: player.position.y)
        }else if player.position.x > self.size.width + 20 {
            player.position = CGPoint(x: -20, y: player.position.y)
        }
    }

    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}
4

1 回答 1

0

如果您的游戏变得更复杂,我不建议您遵循此答案。通常我会说把外星人放在用他们自己的类别位掩码和其他属性初始化的子类中,但是为了避免过多地修改你的代码,我只是改变了addAlien()方法和didBeginContact方法。每个外星人都有自己的 categoryBitMask 和 textureName。

let alienCategories:[UInt32] = [(0x1 << 1),(0x1 << 2),(0x1 << 3)]
let alienTextureNames:[String] = ["alien1","alien2","alien3"]

这将使用上面集合中的值生成一个随机外星人

func addAlien () {

    //Random index between 0 and 2 changing the texture and category bitmask
    let index = Int.random(in: 0...2)
    let textureName = alienTextureNames[index]
    let alien = SKSpriteNode(imageNamed: textureName)

    //Use Int.random() if you don't want a CGFLoat
    let xPos = CGFloat.random(in: 0...414)
    let yPos = frame.size.height + alien.size.height
    alien.position = CGPoint(x: xPos, y: yPos)

    alien.physicsBody = SKPhysicsBody(rectangleOf: alien.size)
    alien.physicsBody?.isDynamic = true

    alien.physicsBody?.categoryBitMask = alienCategories[index]
    alien.physicsBody?.contactTestBitMask = photonTorpedoCategory
    alien.physicsBody?.collisionBitMask = 0

    self.addChild(alien)

    let moveAction = SKAction.moveTo(y: -alien.size.height, duration: 6)
    alien.run(moveAction, completion: { alien.removeFromParent() })

}

func didBegin(_ contact: SKPhysicsContact) {
    var firstBody:SKPhysicsBody
    var secondBody:SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    }else{
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if firstBody.categoryBitMask == photonTorpedoCategory && secondBody.categoryBitMask == alienCategories[0] {
        torpedoDidCollideWithAlien(torpedoNode: firstBody.node as! SKSpriteNode, alienNode: secondBody.node as! SKSpriteNode)
        score += 5

    }else if firstBody.categoryBitMask == photonTorpedoCategory && secondBody.categoryBitMask == alienCategories[1] {
        torpedoDidCollideWithAlien(torpedoNode: firstBody.node as! SKSpriteNode, alienNode: secondBody.node as! SKSpriteNode)
        score -= 5

    }else if firstBody.categoryBitMask == photonTorpedoCategory && secondBody.categoryBitMask == alienCategories[2] {
        torpedoDidCollideWithAlien(torpedoNode: firstBody.node as! SKSpriteNode, alienNode: secondBody.node as! SKSpriteNode)
        score -= 10

    }
}

torpedoNode.physicsBody?.contactTestBitMask = alienCategory将 fireTorpedo 方法中的行更改为alien.physicsBody?.contactTestBitMask = (alienCategories[0] | alienCategories[1] | alienCategories[2])

于 2018-12-11T16:33:17.967 回答