2017-03-03 1 views
0

BITTE HILFE !!! Ich habe versucht, das für lange Zeit herauszufinden. Ich habe das Internet durchsucht und ich kann nichts finden, das mir helfen wird.Wie macht man Gegner zu einem unabhängigen Leben?

Ich mache gerade ein Spiel, in dem du ein Raumschiff in der Mitte bist und feindliche Schiffe sich dir nähern und du musst sie erschießen. Manche Feinde haben ein anderes Leben. zum Beispiel: ein rotes Schiff braucht einen Schuss um zu explodieren, das blaue Schiff braucht 3 usw. Ich habe alles um nur die Leben zu bearbeiten. zum Beispiel: Immer wenn ein blaues Schiff auf den Bildschirm gerufen wird, schieße ich es einmal, so dass sein Leben auf 2 sinkt. Aber immer wenn ein anderes blaues Schiff gerufen wird, wird das Leben des ersten blauen Schiffes wieder auf 3 zurückgesetzt. Kann ich es irgendwie schaffen, dass jedes Mal, wenn ein Schiff Leben verliert, es auch dann bleibt, wenn andere Schiffe gerufen werden?

das ist mein Schiff Funktion, die aufgerufen wird und fügt feindlichen Raumschiffe auf den Bildschirm:

func VillainRight(){ 
    let TooMuch = self.size.width 
    let point = UInt32(TooMuch) 
    life = 3 
    let VillainR = SKSpriteNode(imageNamed: "BlueVillain") 

    VillainR.zPosition = 2 
    VillainR.position = CGPoint(x: self.frame.minX,y: CGFloat(arc4random_uniform(point))) 

    //This code makes the villain's Zposition point towards the SpaceShip 
    let angle = atan2(SpaceShip.position.y - VillainR.position.y, SpaceShip.position.x - VillainR.position.x) 
    VillainR.zRotation = angle - CGFloat(M_PI_2) 


    let MoveToCenter = SKAction.move(to: CGPoint(x: self.frame.midX, y: self.frame.midY), duration: 15) 

    //Physics World 
    VillainR.physicsBody = SKPhysicsBody(rectangleOf: VillainR.size) 
    VillainR.physicsBody?.categoryBitMask = NumberingPhysics.RightV 
    VillainR.physicsBody?.contactTestBitMask = NumberingPhysics.Laser | NumberingPhysics.SpaceShip 
    VillainR.physicsBody?.affectedByGravity = false 
    VillainR.physicsBody?.isDynamic = true 






    VillainR.run(MoveToCenter) 
    addChild(VillainR) 
    } 

Dies ist der Code, der diese Funktion aufruft:

_ = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(Level1.VillainRight), userInfo: nil, repeats: true) 

ich die spritekit bin mit in Schnell. Vielen Dank im Voraus!

+1

Beachten Sie, dass mit Timer in SpriteKit können Sie in einigen Problemen führen, wenn Sie nicht umgesetzt haben, eine [ benutzerdefinierte Pause-Funktion] (http://stackoverflow.com/a/34398582/3402095). Wenn Sie beispielsweise in den Hintergrund treten und nach ein oder zwei Minuten zu einem Spiel zurückkehren, haben Sie wahrscheinlich einen Bildschirm voller Gegner. Dies liegt daran, dass der Timer nicht vom pausierten Status der Szene oder der Ansicht der Knoten beeinflusst wird und nicht sofort angehalten wird, nachdem die App in den Hintergrund gelangt ist. Auf der anderen Seite wird dies bei SKActions automatisch gehandhabt. – Whirlwind

+1

Sie sollten auch versuchen, Namenskonventionen zu befolgen: Namen von Typen und Protokollen sind UpperCamelCase. Alles andere ist niedrigerCamelCase. Bedeutet 'villainR.run (moveToCenter)' anstatt 'VillainR.run (MoveToCenter)';) Dies wird deinen Code für andere leichter verständlich machen ... – Whirlwind

Antwort

1

Das passiert, weil life Variable als eine Eigenschaft einer Szene deklariert wird und es nicht lokal zu einem bestimmten Knoten (feindliches Schiff) ist. Sie können dies in ein paar Möglichkeiten zu lösen ... Erste Möglichkeit userData Eigenschaft des Knotens mit würde:

import SpriteKit 

let kEnergyKey = "kEnergyKey" 

class GameScene: SKScene, SKPhysicsContactDelegate { 

    override func didMove(to view: SKView) { 


     let blueShip = getShip(energy: 3) 
     let greenShip = getShip(energy: 2) 
     let redShip = getShip(energy: 1) 

     if let blueShipEnergy = blueShip.userData?.value(forKey: kEnergyKey) as? Int { 

      print("Blue ship has \(blueShipEnergy) lives left") 
      //hit the ship 
      blueShip.userData?.setValue(blueShipEnergy-1, forKey: kEnergyKey) 

      if let energyAfterBeingHit = blueShip.userData?.value(forKey: kEnergyKey) as? Int { 

       print("Blue ship has \(energyAfterBeingHit) lives left") 
      } 
     } 
    } 

    func getShip(energy:Int)->SKSpriteNode{ 
     //determine which texture to load here based on energy value 
     let ship = SKSpriteNode(color: .purple, size: CGSize(width: 50, height: 50)) 

     ship.userData = [kEnergyKey:energy] 

     return ship 
    } 
} 

Dies ist, was die docs sagen über userData Eigenschaft:

Sie verwenden diese Eigenschaft Ihre speichern eigene Daten in einem Knoten. Beispiel: Sie können spielspezifische Daten zu jedem Knoten speichern, den Sie in Ihrer Spiellogik verwenden möchten. Dies kann eine nützliche Alternative zum Erstellen eigener Knoten Unterklassen sein, um Spieldaten zu speichern.

Wie Sie sehen können, eine Alternative dazu ist Subklassen eines Knotens (SKSpriteNode):

class Enemy:SKSpriteNode { 

    private var energy:Int 
    //do initialization here 
} 
+0

Ok ..... Und kannst du mir bitte sagen, was nötig wäre in die Funktion did beginContact zu gehen, wenn der Kugelknotenkontakt mit dem feindlichen Knotenpunkt kommt, so dass das Leben um eins abnimmt? –

+0

@AlexMerlin Es ist einfach. In 'didBegin (contact:)' Sie greifen auf das Schiff zu, dann greifen Sie auf seine userData zu, dann verringern Sie die 'energy'-Variable und je nach Art eines Schiffes, entfernen Sie es schließlich? Sinn ergeben? – Whirlwind

+0

Ok großartig ... Ich werde dies so schnell wie möglich umsetzen und Sie wissen lassen, wie es geht. Vielen Dank –

Verwandte Themen