使用Swift编写程序,尝试以等轴网格的形式呈现。

6

我尝试以编程方式完成这个任务,唯一的原因是为了能够访问每个瓦片的位置,从而可以操作网格。我已经查看了大约15个使用其他编程语言的教程,但即使有这些知识,我在Swift中创建一个程序仍然非常困难。

我尝试创建了一个嵌套的for循环,但我甚至不确定循环内部的代码是否具有逻辑上的意义来创建一个等角网格,我只是从我找到的其中一个教程中复制的:

func generateGrid() {
    for (var i = 0; i < 5; i++) {
        for (var j = 5; j >= 0; j--){
            tile.position = CGPoint(x: (j * Int(tile.size.height) / 2) + 
                                       (i * Int(tile.size.width) / 2), 
                                    y: (i * Int(tile.size.height) / 2) - 
                                       (j * Int(tile.size.width) / 2))
            addChild(tile)
        }
    }
}

然后我尝试在“didMoveToView”函数中调用它,但显然你不能多次添加相同的节点。

请给我一些方向。


1
每次都应该创建一个新的瓦片,然后设置它的位置并将其添加到场景中。 - user4233369
如何在for循环的每次运行中创建一个新变量? - Ethan Scott Miller
在for循环之外,你会如何做?同样的方式。 - Robert Harvey
for (var j=... 循环内:let tile=SKSpriteNode()/*在此处进行任何设置*/\*设置位置*/ - user4233369
2个回答

13

这是在SpriteKit中创建等轴网格的示例:

定义网格设置

let tileHeight:CGFloat = 16.0
let tileWidth:CGFloat = 32.0
let numRows = 5
let numCols = 6
创建网格元素并将它们添加到场景的正确位置。
let size = CGSizeMake(tileWidth, tileHeight)
for row in 1...numRows {
    for col in 1...numCols {
        // Create a new tile object
        let tile = newTile(size)
        // Convert (col,row) to (x,y)
        tile.position = tilePosition(col, row: row)
        self.addChild(tile)
    }
}

该函数将网格位置转换为x和y场景坐标。使用此函数创建网格并在网格上添加建筑物。

func tilePosition(col:Int, row:Int) -> CGPoint {
    let x = (CGFloat(row) * tileWidth  / 2.0) + (CGFloat(col) * tileWidth  / 2.0)
    let y = (CGFloat(col) * tileHeight / 2.0) - (CGFloat(row) * tileHeight / 2.0)
    return CGPointMake(x+100.0, y+100.0)
}

该函数创建一个新的菱形 SKShapeNode

func newTile(size:CGSize) -> SKShapeNode {
    let shape = SKShapeNode()
    let path = UIBezierPath()
    path.move(to: CGPoint(x:0, y:size.height / 2.0))
    path.addLine(to: CGPoint(x:size.width / 2.0, y:0))
    path.addLine(to: CGPoint(x:0, y:-size.height / 2.0))
    path.addLine(to: CGPoint(x:-size.width / 2.0, y:0))
    path.close()
    shape.path = path.cgPath
    shape.lineWidth = 1.0
    shape.fillColor = SKColor.gray
    return shape
}

该函数确定适当的z位置,以确保放置在网格上的建筑物将按正确顺序呈现。

func buildingZPosition(col:Int, row:Int) -> CGFloat {
    return CGFloat(row*numCols + numCols-col)
}

带有建筑物的等轴网格图

图1. 使用上述代码创建的等轴网格


2
这太棒了!运行得很好。这是我遇到的第一个真正有效并且让我理解整个过程如何组合的教程。干得好。我仍然苦于如何正确使用构建函数来将订书钉固定在板子上。如果你有时间…… :) - tore
buildingZPosition 函数返回一个角色的 zPosition 值,以便它相对于网格上的其他角色以正确的顺序出现。在上面的图像中,绿色块出现在蓝色和棕色块的前面,因为它的 zPosition 值比其他块高。 - 0x141E
明白了!非常感谢! :) - tore

7
创建如下所示的等角网格,需要创建两个循环。其中一个循环逐行迭代,另一个循环逐列迭代。请注意,每个其他列的中心点上移半个瓷砖的高度,每个其他行也是如此。为了弥补这一点,我们检查行和列是否为偶数或奇数,并相应地进行调整。一个可能的函数看起来像这样:
func generateGrid() {

    for i in 0..<5 {

        // Every other line needs to be shifted
        var offsetX = 0
        if i % 2 == 0 {
            offsetX = 0
        } else {
            offsetX = tile.size.width / 2.0
        }

        for j in 0..<5 {
            var tile = Tile()

            // Every other line needs to be shifted
            var offsetY = 0
            if i % 2 == 0 {
                offsetX = 0
            } else {
                offsetX = tile.size.height / 2.0
            }

            tile.position = CGPoint(x: (i * tile.size.width) - offsetX, y: (j * tile.size.height) - offsetY)
            addChild(tile)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接