Как вызвать цветной спрайт в определенную позицию (Swift 3)


Таким образом, в рамках моего проекта я в основном пытаюсь создать случайно сгенерированный лабиринт со случайными входами и выходами. У меня есть три класса (Класс Maze, класс GameScene и класс Grid), в которых до сих пор я успешно мог кодировать случайно сгенерированный лабиринт.

Однако моя проблема заключается в том, что класс Maze (в котором происходит код случайной генерации) чисто содержит данные для maze, но не имеет текущего соединения с графикой. Поэтому, когда я запускаю свое приложение, пустое место появляется экран.

То, что я пытаюсь (но не уверен, как) сделать, это в основном поместить линию (она же черный цветной спрайт, сформированный в линию) в том месте, где находится стена лабиринта.

Таким образом, мой лабиринт работает так, что это сетка (массив), в которой "стены" каждой ячейки массива (вверх, вниз, влево или вправо) определяются как истинные или ложные. Если клеточная стенка ложна, то там нет стены лабиринта; но если она истинна, то там есть стена лабиринта. Состояние каждой стены случайно генерируется то, что создает лабиринт.

Мне удалось подключить код к цветовому спрайту с именем "mazeWall" в классе GameScene (используя этот код:)

var mazeWall: SKNode!

[...]

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

Кроме того, я смог получить доступ к данным класса Maze в классе GameScene, используя этот код для создания объекта типа класса Maze:

var maze = Maze()
Однако теперь я не знаю, как вызвать цветовой спрайт в положение истинных стен на сетке.

Это код, который я пытался иметь внутри класса GameScene доступ к данным класса Maze и петлю через ячейки лабиринта и проверить, какие стены истинны:

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

Пожалуйста, дайте мне знать, как я могу вызвать спрайт цвета mazeWall в положение "истинных" стен лабиринта внутри лабиринта. Также дайте мне знать, если вам нужно, чтобы я включил больше моего кода (мой класс maze, класс grid, генерация maze и т. д.)...

Заранее спасибо!

2 3

2 ответа:

То, что вы должны сделать, это использовать SKTexture для кэширования той же стены, которую вы будете использовать для всех SKSpriteNode созданных.

Таким образом, вы загружаете свой актив стены в let wallTexture = SKTexture(imageNamed: <NameOfYourWall>), а затем в каждом из ваших 4 if создаете SKSpriteNode(texture: wallTexture).

Теперь идет математика, где вы должны установить положение каждого из этих SKSpriteNode.

Предположим, вам нужен лабиринт, который соответствует экрану, поэтому вам нужно получить максимальный размер плитки, выполняя этот псевдокод:
let maxWidth = SCREEN_SIZE / maze.gridSize
let maxHeight = SCREEN_SIZE / maze.gridSize
let tileSize = max(maxWidth, maxHeight)

И Вы, наконец, можете разместить стены в ваша логика. Не забывайте, что по умолчанию точкой привязки SKSpriteKit является его центр и что геометрия выглядит следующим образом:

^ 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)
}

Вам, вероятно, придется повернуть стену для нужного размера (если только ваша исходная текстура не находится уже вертикально) или просто создать другой актив с вертикальной версией и загрузить этот новый актив в другую текстуру.

Просто подправьте математику, и вы ее сделаете.

Вы можете добавить функцию, которая преобразует x, y вашей точки сетки на Лабиринте в точку CG, где должна быть размещена стена лабиринта. Как только вы получите cgpoint для x,y точки сетки, это просто вопрос создания нового спрайта с текстурой стены и добавления его в качестве дочернего элемента в этой позиции cgpoint.

Сначала определите, как константу, насколько большим должен быть размер каждой точки сетки. Вы, скорее всего, позже также должны будете ссылаться на эту константу вне функция ниже (например, при установке размера спрайта стены лабиринта), поэтому дайте ему некоторую более высокую область действия (например, как свойство вашей сцены).
let sizeOfEachGridPoint = CGSize(width: 32, height: 32) // 32 just an example

Чтобы написать требуемую функцию, я сделал некоторые предположения; вы можете легко адаптировать эту функцию, если предположения не верны.

  • x, y = = (0,0) - нижняя левая точка сетки вашего лабиринта
  • нижний левый угол нижней левой точки сетки будет находиться в точке CGPoint.ноль.
  • опорные точки спрайтов стены будет 0.5, 0.5

Исходя из этих предположений, вы могли бы иметь:

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)
}

Надеюсь, это поможет!