2015-07-10 74 views
1

我的敵人有問題。我做了5個,每個都獨立於另一個。但事情是 - 除了外表,它們幾乎是一樣的。他們喜歡分成一組,因爲每個人都有一個隨機的耳環機制。 我試圖使用SKConstraint來縮小它們之間的距離,但它不適合我。所以我想到了不同的方法:我想用一些東西,比如一個空的節點來代表敵人,然後它出現在一個場景中(它們就像從右邊到左邊的飛鳥中的下層管道)。在它們出現在屏幕上之前,我希望我的遊戲能夠在它們的5個節點之間隨機選擇並執行正確的動畫。因爲我的小組出現的問題將被解決。我可以使用某種容器節點代替SKSpriteNode來表示敵人嗎?

我該怎麼辦?

現在我使用他們的節點。我提供的代碼,如果它有助於:

var robot = SKSpriteNode() 
let robotAtlas = SKTextureAtlas(named: "robot") 
var robotArray = [SKTexture]() 

robotArray.append(robotAtlas.textureNamed("robot0")); 
robotArray.append(robotAtlas.textureNamed("robot1")); 

然後我申請physicBodies他們

robot = SKSpriteNode(texture: robotArray[0]); 
robot.position = CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMidY(self.frame) - 138) 
self.robot.name = "robot" 
self.addChild(robot) 

我怎麼能這樣做或許有其他的方法做這樣的事情?

現在,這是我的計劃: 這是隨機函數:

func random() -> UInt32 { 
var range = UInt32(60)..<UInt32(200) 
return range.startIndex + arc4random_uniform(range.endIndex - range.startIndex + 1)} 

我對外觀的自定義類:

class EnemyAppear { 
var nowAppear = false 
var waitToAppear = UInt32(0) 
var currentInterval = UInt32(0) 
init(nowAppear:Bool, waitToAppear:UInt32, currentInterval:UInt32) { 
self.nowAppear = nowAppear 
self.waitToAppear = waitToAppear 
self.currentInterval = currentInterval } 


func shouldRun() -> Bool { 
return self.appearInterval > self.waitToAppear } 

然後,我有一個狀態跟蹤敵人:

var enemyStatus:Dictionary<String,EnemyAppear> = [:] 


enemyStatus["robot"] = EnemyAppear(nowAppear: false, waitToAppear: random(), currentInterval: UInt32(0)) 
enemyStatus["drone"] = EnemyAppear(nowAppear: false, waitToAppear: random(), currentInterval: UInt32(0)) 

而在更新功能,我有移動它們的功能:

func enemyRun() { 
    for(enemy, enemyAppear) in self.enemyStatus { 
    var thisPet = self.childNodeWithName(enemy)! 
     if enemyAppear.shouldRun() { 
      enemyAppear.waitToAppear = random() 
      enemyAppear.currentInterval = 0 
      enemyAppear.nowAppear = true 
     } 

     if enemyAppear.nowAppear { 
      if thisPet.position.x > petMaxX { 
       thisPet.position.x -= CGFloat(self.groundSpeed) 
      }else { 
       thisPet.position.x = self.originalPetPositionX 
       enemyAppear.nowAppear = false 
       self.score++ 
       self.scoreText.text = String(self.score) 
      } 
     } 
    } 

我只需要設置敵人之間的距離。

+1

我已經讀過兩次你的問題,但仍然不確定你想要達到的目標。你是否試圖將敵人移動到編隊中,或者將它們隨機產生並移出屏幕並分別移動它們? – Whirlwind

+0

創建一個空的/清除SKSpriteNode。 – sangony

+0

@Whirlwind現在我的程序產生了5個不同的敵人,5個不同的節點。我想讓它只產生1個敵人,你知道,像骨架一樣。我希望它從5個節點中選擇,例如從五個皮膚中選擇一個,並將其放置在該骨架上。以汽車製造廠爲例。起初汽車沒有顏色。有5種不同的顏色來繪製該車。我希望它隨機選擇那種顏色並繪製它。是否有意義? – TimurTest

回答

2

我認爲你是事情複雜不必要的或我仍然誤解你:(但這裏有一些建議,如果你只需要生成隨機的敵人,你可以幾種方式之間進行選擇:

1.製作定製Robot類

可以使一類叫做機器人和隨機選擇不同的紋理。要做到隨機紋理(從紋理地圖或紋理數組),您可以使用使用的arc4random()方法。

例(僞合作德):在這種情況下

Robot.init(texture:someRandomTexture) //note that texture is a type of SKTexture, it's not a string 

Robot類是SKSpriteNode的子類,你可以通過構造函數與紋理初始化(從上面的例子一樣),或者你可以將內部構造所有紋理選擇邏輯(INIT方法)。隨你便。用法

例子:

Robot.init()

整個邏輯被稱爲這就要求SKSpriteNode的initWithTexture方法

如果你真的需要你的機器人有骨骼和皮膚,你可以init方法裏面對每種類型的機器人都不使用單紋理,那麼你可以製作SKNode(空容器)的子類的Robot類。

在這種情況下,Robot類應該有兩個變量,SKSpriteNode骨架和SKSpriteNode皮膚。這種情況下的皮膚變量將被隨機選擇。骨骼和皮膚節點應該作爲孩子添加到自己(在這種情況下,自己是Robot類,它是SKNode)。 SKNode沒有可視化表示,但它有位置屬性,所以當你移動SKNode時,你也要移動它的子節點。

2.使用SKSpriteNode

如果你決定不有一個機器人類,而只使用SKSpriteNode,故事是一樣的。我會爲每種類型的敵人使用不同的紋理,但如果這不可管理,則可以爲每個機器人使用多個SKSpriteNodes。

所以,你應該製作一個返回一個敵人的方法,它是SKSpriteNode。在該方法中,您將創建帶有骨骼紋理的SKSpriteNode,之後您將添加皮膚作爲子項,將皮膚的zPosition設置爲高於骨骼的zPosition,創建物理主體並返回該節點。

一個有用的東西(如果你只需要改變精靈的顏色)是你可以輕鬆地colorize nodes programatically(着色紋理)

編輯:

使用動作序列菌種

簡單的例子時間的隨機時間後敵人:

import SpriteKit 

class GameScene: SKScene { 

    var enemies: NSMutableArray = [] 
    var textures = [SKTexture]() 

    let debugLabel = SKLabelNode(fontNamed: "Arial-BoldMT") 

    override func didMoveToView(view: SKView) { 

     /* Setup your scene here */ 

     debugLabel.fontColor = SKColor.purpleColor() 
     debugLabel.fontSize = 20.0 
     debugLabel.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)) 
     self.addChild(debugLabel) 


     let atlas = SKTextureAtlas(named: "enemies") 

     //Fill the array with textures to use them later 
     //Not needed IMO, but suitable to show you how to pick a random element from an array 
     for var i = 1; i<=atlas.textureNames.count; i++ { 

      textures.append(atlas.textureNamed("enemy\(i)")) 

     } 


     debugLabel.text = "Enemies count : \(enemies.count), Nodes count : \(self.children.count)" 

     spawnEnemiesWithDelay(3) 

    } 


    //This method is just for creating a sprite 
    func createRandomEnemy() ->SKSpriteNode{ 

     let rand = Int(arc4random_uniform(UInt32(textures.count))) 

     let enemy = SKSpriteNode(texture: textures[rand]) 

     //setup here enemy physics body 

     return enemy 

    } 

    //This method spawns enemies after random period of time. You can stop this by removing an action key 
    func spawnEnemiesWithDelay(delay: NSTimeInterval){ 



     let delay = SKAction.waitForDuration(delay, withRange:3) //The duration may vary in either direction by up to half of the value of the durationRange parameter. Which means duration can vary either plus or minus 1.5 sec 



     let block = SKAction.runBlock({ 

      let enemy = self.createRandomEnemy() 

      enemy.position = CGPoint(x: self.frame.size.width+enemy.size.width/2, y:100) 

      self.addChild(enemy) 

      self.enemies.addObject(enemy) // Store reference to enemy if needed 

      let move = SKAction.moveTo(CGPoint(x: -enemy.size.width/2, y: 100), duration: 5) 

      let moveAndRemove = SKAction.sequence([move, SKAction.runBlock({ 
       enemy.removeFromParent() 


       self.enemies.removeObjectIdenticalTo(enemy as AnyObject) 

      })]) //remove enemy when offscreen 



      enemy.runAction(moveAndRemove, withKey: "moving") 

     }) 

     let sequence = SKAction.sequence([delay,block]) 

     self.runAction(SKAction.repeatActionForever(sequence), withKey: "spawning") 

    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 

     debugLabel.text = "Enemies count : \(enemies.count), Nodes count : \(self.children.count)" 

    } 
} 

如果您的場景,並查看是否正確初始化,您可以enemies.atlas很少不同的紋理文件夾,複製&粘貼此代碼來嘗試它。希望這個對你有幫助。

+0

男人,這是偉大的意見!感謝您的工作,我希望我可以多次標記這是最好的答案!我想我現在會和你的第二個建議一起去,但是由於這個答案,我總是有一個備份計劃:) – TimurTest

+0

我很抱歉再次問你,但也許你知道答案。如果我會像你說的那樣使用普通的SKSpriteNodes呢?我只想在我的敵人之間留下一個空間。但是我的隨機函數正在決定它是否應該按照上次發射敵人的時間在場景中運行另一個敵人。而且我認爲如果它能夠通過發射任何敵人的時間來決定它會更好。我已經更新了我的問題,也許可以這樣做? – TimurTest

+0

@TimurTest你有沒有嘗試用動作序列來產生敵人,如建議(一個接一個)?您可以使用一個鍵開始產卵序列,而不必在需要時將其刪除。我無法真正幫助您使用swift代碼,因爲我目前只使用Obj-C。 – Whirlwind

相關問題