2015-11-09 1 views
0

Existe-t-il un moyen facile de créer un niveau procédural avec un automate cellulaire dans swift/SpriteKit (bibliothèque?)? Je veux créer une "cave" avec 11 champs dans la hauteur et 22 largeur. Ceux-ci devraient être créés au hasard et chaque champ sans mur devrait être atteint. Je viens de trouver un documentation en utilisant Objective-C, que je ne connais pas. Je passe beaucoup de temps à essayer de comprendre le code et de suivre l'exemple sans succès.Génération de niveau procédural avec automate cellulaire dans Swift

PS: S'il y a un moyen plus facile j'apprécie certains algorithmes

Répondre

3

J'ai fait une aire de jeux où vous pouvez expérimenter

//: Playground - noun: a place where people can play 

import UIKit 
import SpriteKit 
import XCPlayground 


class Cave { 

    var cellmap:[[Bool]] 

    let chanceToStartAlive = 35 
    let deathLimit = 3 
    let birthLimit = 4 
    var xCell = 40 // number of cell in x axes 
    var yCell = 20 // number of cell in y axes 
    var wCell = 20 // cell width 
    var hCell = 20 // cell height 

    init(){ 
     cellmap = Array(count:yCell, repeatedValue: 
      Array(count:xCell, repeatedValue:false)) 

     cellmap = self.initialiseMap(xCell, yIndex:yCell) 
    } 

    func initialiseMap(xIndex:Int, yIndex:Int) -> [[Bool]]{ 
     var map:[[Bool]] = Array(count:yIndex, repeatedValue: 
      Array(count:xIndex, repeatedValue:false)) 

     for y in 0...(yIndex - 1) { 
      for x in 0...(xIndex - 1) { 

       let diceRoll = Int(arc4random_uniform(100)) 

       if diceRoll < chanceToStartAlive { 
        map[y][x] = true 
       } else { 
        map[y][x] = false 
       } 
      } 
     } 
     return map 
    } 

    func addSprite(scene:SKScene){ 
     for (indexY, row) in cellmap.enumerate(){ 
      for (indexX, isWall) in row.enumerate(){ 
       if isWall { 

        let wall = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: wCell, height: hCell)) 
        wall.position = CGPoint(x: (indexX * wCell) + (wCell/2) , y: (indexY * hCell) + (hCell/2) ) 
        scene.addChild(wall) 
       } 
      } 
     } 
    } 

    func countAliveNeighbours(x:Int, y:Int) -> Int{ 

     var count = 0 
     var neighbour_x = 0 
     var neighbour_y = 0 

     for i in -1...1 { 

      for j in -1...1 { 

       neighbour_x = x + j 
       neighbour_y = y + i 


       if(i == 0 && j == 0){ 
       } else if(neighbour_x < 0 || neighbour_y < 0 || neighbour_y >= cellmap.count || neighbour_x >= cellmap[0].count){ 
        count = count + 1 
       } else if(cellmap[neighbour_y][neighbour_x]){ 
        count = count + 1 
       } 

      } 

     } 

     return count 

    } 

    func applyRules(){ 

     var newMap:[[Bool]] = Array(count:yCell, repeatedValue: 
      Array(count:xCell, repeatedValue:false)) 



     for y in 0...(cellmap.count - 1) { 
      for x in 0...(cellmap[0].count - 1) { 
       let nbs = countAliveNeighbours(x, y: y); 
       if(cellmap[y][x]){ 
        if(nbs < deathLimit){ 
         newMap[y][x] = false; 
        } 
        else{ 
         newMap[y][x] = true; 
        } 
       } else{ 
        if(nbs > birthLimit){ 
         newMap[y][x] = true; 
        } 
        else{ 
         newMap[y][x] = false; 
        } 
       } 
      } 
     } 
     cellmap = newMap 
    } 
} 

let view:SKView = SKView(frame: CGRectMake(0, 0, 1024, 768)) 

XCPShowView("Live View", view: view) 

let scene:SKScene = SKScene(size: CGSizeMake(1024, 768)) 
scene.scaleMode = SKSceneScaleMode.AspectFit 

let aCave = Cave() 

aCave.applyRules() 
aCave.applyRules() 

aCave.addSprite(scene) 
view.presentScene(scene) 
1

Mise à jour le code de jeu pour Xcode 8 et Swift 3. Je troqué le X et le nombre de cellules Y puisque vous verrez probablement la vue dans une orientation "portrait". N'oubliez pas d'ouvrir l'Assistant Editor pour afficher les résultats. Il faut aussi un peu de temps pour l'exécuter, alors donnez-lui quelques minutes pour lancer l'algorithme.

//: Playground - noun: a place where people can play 

import UIKit 
import SpriteKit 
import XCPlayground 
import PlaygroundSupport 


class Cave { 

    var cellmap:[[Bool]] 

    let chanceToStartAlive = 35 
    let deathLimit = 3 
    let birthLimit = 4 
    var xCell = 20 // number of cell in x axes 
    var yCell = 40 // number of cell in y axes 
    var wCell = 20 // cell width 
    var hCell = 20 // cell height 

    init(){ 
     cellmap = Array(repeating: 
      Array(repeating:false, count:xCell), count:yCell) 

     cellmap = self.initialiseMap(xIndex: xCell, yIndex:yCell) 
    } 

    func initialiseMap(xIndex:Int, yIndex:Int) -> [[Bool]]{ 
     var map:[[Bool]] = Array(repeating: 
      Array(repeating:false, count:xIndex), count:yIndex) 

     for y in 0...(yIndex - 1) { 
      for x in 0...(xIndex - 1) { 

       let diceRoll = Int(arc4random_uniform(100)) 

       if diceRoll < chanceToStartAlive { 
        map[y][x] = true 
       } else { 
        map[y][x] = false 
       } 
      } 
     } 
     return map 
    } 

    func addSprite(scene:SKScene){ 
     for (indexY, row) in cellmap.enumerated(){ 
      for (indexX, isWall) in row.enumerated(){ 
       if isWall { 

        let wall = SKSpriteNode(color: UIColor.red, size: CGSize(width: wCell, height: hCell)) 
        wall.position = CGPoint(x: (indexX * wCell) + (wCell/2) , y: (indexY * hCell) + (hCell/2) ) 
        scene.addChild(wall) 
       } 
      } 
     } 
    } 

    func countAliveNeighbours(x:Int, y:Int) -> Int{ 

     var count = 0 
     var neighbour_x = 0 
     var neighbour_y = 0 

     for i in -1...1 { 

      for j in -1...1 { 

       neighbour_x = x + j 
       neighbour_y = y + i 


       if(i == 0 && j == 0){ 
       } else if(neighbour_x < 0 || neighbour_y < 0 || neighbour_y >= cellmap.count || neighbour_x >= cellmap[0].count){ 
        count = count + 1 
       } else if(cellmap[neighbour_y][neighbour_x]){ 
        count = count + 1 
       } 

      } 

     } 

     return count 

    } 

    func applyRules(){ 

     var newMap:[[Bool]] = Array(repeating: 
      Array(repeating:false, count:xCell), count:yCell) 



     for y in 0...(cellmap.count - 1) { 
      for x in 0...(cellmap[0].count - 1) { 
       let nbs = countAliveNeighbours(x: x, y: y); 
       if(cellmap[y][x]){ 
        if(nbs < deathLimit){ 
         newMap[y][x] = false; 
        } 
        else{ 
         newMap[y][x] = true; 
        } 
       } else{ 
        if(nbs > birthLimit){ 
         newMap[y][x] = true; 
        } 
        else{ 
         newMap[y][x] = false; 
        } 
       } 
      } 
     } 
     cellmap = newMap 
    } 
} 

let view:SKView = SKView(frame: CGRect(x: 0, y: 0, width: 768, height: 1024)) 

let scene:SKScene = SKScene(size: CGSize(width: 768, height: 1024)) 
scene.scaleMode = SKSceneScaleMode.aspectFit 

PlaygroundPage.current.needsIndefiniteExecution = true 
PlaygroundPage.current.liveView = view 

let aCave = Cave() 

aCave.applyRules() 
aCave.applyRules() 

aCave.addSprite(scene: scene) 
view.presentScene(scene)