3

So within my project, I am basically trying to make a randomly generated maze with random entrances and exits. I have three classes (a Maze class, a GameScene class, and a Grid Class) within so far I have successfully been able to code a randomly generated maze.

However my problem is that the Maze class (which is where the random generation code takes place) purely contains the data for the maze, but no current connection to the graphics. So when I run my app, a blank screen shows up.

What I am trying (but am unsure how) to do is basically place a line (aka a black color sprite shaped in a line) in the location where the maze wall is.

So, the way my maze works is that it is a grid (array) in which each array cell's "walls" (up, down, left, or right) are defined as either true or false. If the cell wall is false, then there is no maze wall there; but if it is true, then there is a maze wall there. The state of each wall being randomly generated is what creates the maze.

I was able to connect the code to the color sprite named "mazeWall" within the GameScene class (using this code:)

var mazeWall: SKNode!

[...]

mazeWall = self.childNode(withName: "mazeWall")

Also, I was able to access the Maze class's data within GameScene class using this code to create an object of the Maze class type:

var maze = Maze()

However I am now unsure how to call the color sprite to the position of the true walls on the grid.

This is the code I attempted to have within the GameScene Class to access Maze class' data and to loop through the maze's cells and check which walls are true:

class GameScene: SKScene {
var mazeWall: SKNode!
var maze = Maze()
var backgroundColorCustom = UIColor(red: 255, green: 244, blue: 231,
                                    alpha: 4.0)



override func didMove(to view: SKView) {
    /* Set reference to obstacle layer node */
    mazeWall = self.childNode(withName: "mazeWall")

    //going through each cell and checking if it is true in order to place a wall
    for x in 0..<self.maze.gridSize{
        for y in 0..<self.maze.gridSize{
            if (self.maze.down[x,y]) == true {
                //code
            }

            if (self.maze.up[x,y]) == true {
                //code
            }

            if (self.maze.left[x,y]) == true{
                //code
            }
            if (self.maze.right[x,y]) == true {
                //code
            }

        }//end of y forloop
    }//end of x for loop

}//end of func didMove

}//end of GameScene class

Please let me know how I can call the mazeWall color sprite to the position of the "true" maze walls within the maze. Also let me know if you need me to include more of my code (my maze class, the grid class, maze generation, etc)...

Thanks in advance!

JohnV
  • 981
  • 2
  • 8
  • 18
  • if you could include a link to a github or dropbox of your sample project, that would be helpful! – Fluidity Jul 18 '17 at 23:59
  • I would start with your gameScene scale mode set to .aspectFit. and set the scene size in your SKS file to the size of your map. This way 1 point(pixel) = 1 map position. Then create a color sprite of 1 point, and set it at your map position – Knight0fDragon Jul 19 '17 at 01:32

2 Answers2

1

You could consider adding a function that would convert the x,y of your grid point on the maze into a CGPoint where the maze wall should be placed. Once you get the cgpoint for the x,y of a grid point, it's just a matter of creating a new sprite with the wall texture and adding it as a child at that cgpoint position.

First define, as a constant, how large the size of each grid point should be. You will most likely later on also need to refer to this constant outside of the function below (e.g. when setting the size of the maze wall sprite), so give it some higher scope (e.g. as a property of your scene).

let sizeOfEachGridPoint = CGSize(width: 32, height: 32) // 32 just an example

To write the required function, I've made some assumptions; you could easily adapt this function if the assumptions are not correct.

  • x,y == (0,0) is the bottom left grid point of your maze
  • The bottom left corner of the bottom left grid point will be at CGPoint.zero.
  • The anchor points of the wall sprites will be 0.5,0.5

Based on these assumptions, you could have:

func cgPointForGridPoint(x: Int, y: Int) -> CGPoint    
{
 // Note that we are also adding half of the width and half of the 
 // height since the anchor point of the grid point is at its center

    let xOfPoint = CGFloat(x) * sizeOfEachGridPoint.width
                   + sizeOfEachGridPoint.width / 2 

    let yOfPoint = CGFloat(y) * sizeOfEachGridPoint.height
                   + sizeOfEachGridPoint.height / 2  

    return CGPoint(x: xOfPoint, y: yOfPoint)
}

Hope this helps!

JohnV
  • 981
  • 2
  • 8
  • 18
1

What you should do is use SKTexture to cache the same wall you will be using for all the SKSpriteNode created.

So you load your wall asset into a let wallTexture = SKTexture(imageNamed: <NameOfYourWall>) then in each one of your 4 if, you create a SKSpriteNode(texture: wallTexture).

Now comes the math where you have to set the position of each one of those SKSpriteNode.

Let's say you want a maze that fits the screen, so you need to get the maximum size of a tile doing this pseudo code:

let maxWidth = SCREEN_SIZE / maze.gridSize
let maxHeight = SCREEN_SIZE / maze.gridSize
let tileSize = max(maxWidth, maxHeight)

And you can finally place the walls in your logic. Don't forget that by default the anchorPoint of a SKSpriteKit is its center and that the geometry is like this:

^ y
|
|-->x

`

if self.maze.down[x,y] == true {
    let wall = SKSpriteNode(texture: wallTexture)
    let centerTile = CGPoint(x: (x * tileSize + tileSize/2), y: (y * tileSize + tileSize/2))
    let xPos = centerTile.x - wall.width /2
    let yPos = centerTile.y - tileSize / 2 + wall.height
    wall.position = CGPoint(x: xPos, y: yPos)
    yourScene.addChild(wall)
}

You will probably have to rotate the wall for the let and right size (unless your original texture is already vertically) or you just have to create another asset with a vertical version and load this new asset into another texture.

Just tweak around the math and you'll get it done.

Kalzem
  • 7,320
  • 6
  • 54
  • 79