如何一次存储多个属性?

问题描述 投票:1回答:1

我正在使用Swift,Xcode 6和SpriteKit,

我想制作一个游戏,其中一些精灵从屏幕顶部掉落,但每个精灵都有一个明确的速度,位置和激活时间。我有这个工作代码,但我真的不认为这是最优化的方法:

class obstacles: SKSpriteNode
{
    var isOnScreen = false
    var type: Int = 0
    var initTime: Int = 0
}

var obstacle = [obstacles]() // obstacle is an array of SKSpriteNode

// type : initTime : speed : position : xScale : yScale
var level1: [String] = ["0:120:3:0:1:1", "0:130:4:80:2:2","1:140:8:120:6:1","0:150:6:240:2:2"]

override func didMoveToView(view: SKView)
{        
    initObstacles()
}

func initObstacles()
{
    for var x = 0; x < level1.count; x++ // for each obstacle
    {
        var index = 0

        var type = String("")
        var initTime = String("")
        var speed = String("")
        var position = String("")
        var xScale = String("")
        var yScale = String("")

        var lastIndex = obstacle.count

        for Character in level1[x] // we read each character one by one
        {
            if Character == ":" { index++ } // if it's a ":" we change the variable
            else
            {
                switch index
                {
                case 0:
                    type += String(Character)
                case 1:
                    initTime += String(Character)
                case 2:
                    speed += String(Character)
                case 3:
                    position += String(Character)
                case 4:
                    xScale += String(Character)
                case 5:
                    yScale += String(Character)
                default:
                    break;
                }
            }
        }

        obstacle.append(obstacles(imageNamed: "Rectangle")) // we add an element to the array

        obstacle[lastIndex].type = type.toInt()! // we init all the values
        obstacle[lastIndex].initTime = initTime.toInt()!
        obstacle[lastIndex].speed = CGFloat(speed.toInt()!)
        obstacle[lastIndex].size.width = DEFAULT_OBSTACLE_SIZE * CGFloat(xScale.toInt()!)
        obstacle[lastIndex].size.height = DEFAULT_OBSTACLE_SIZE * CGFloat(yScale.toInt()!)
        obstacle[lastIndex].position = CGPointMake(CGFloat(position.toInt()!) - obstacle[lastIndex].size.width/2, CGRectGetMaxY(frame) + obstacle[lastIndex].size.height/2)
    }
}

你知道我怎么能设法做同样的事情,但更“干净”?

swift sprite-kit initialization
1个回答
1
投票

我建议创建一个classstruct,其中包含障碍物的所有必要数据,并另外将您的类型从标准数字更改为enum,例如:

enum ObstacleType {
    case Block, Tree, WhatEverObstaclesYouHave...
}
struct Obstacle {
    var type: ObstacleType
    var initializationTime: NSTimeInterval
    var speed: Double
    // and similarly for position, your scales and what you may need in future
}

并使用例如创建它们。

Obstacle(type: .Block, initializationTime: 0, speed: 12.0, ...)

优势(显然)是你不再有问题解析你的字符串(不再有字符串),并且可以直接使用适当的类型提供所有必要的信息。并且您可以轻松地为您的类型使用枚举,这应该是枚举,因为您的障碍不是1,而是块,树或其他。

您的level1变量可以像这样定义:

var level1 : [Obstacle] = [
    Obstacle(type: .Block, initializationTime: 120, speed: 3.0, ...),
    Obstacle(type: .Block, initializationTime: 130, speed: 4.0, ...),
    Obstacle(type: .Tree,  initializationTime: 140, speed: 8.0, ...),
    Obstacle(type: .Block, initializationTime: 150, speed: 6.0, ...)
]

要删除初始化程序中的标签,只需定义自己的初始化程序即可。只需将其添加到您的结构:

init(_ type: ObstacleType, _ time: NSTimeInterval, _ speed: Double, ...) {
    self.type = type
    self.initializationTime = time
    self.speed = speed
    // other variables...
}

然后你可以像这样创建每个障碍物:

Obstacle(.Block, 120, 3.0, ...)

但是现在你不能轻易地告诉哪个数字在阅读实例时具有什么意义。我不推荐这样做只是为了输入较少,因为自动完成将为您提供大部分内容。

© www.soinside.com 2019 - 2024. All rights reserved.