Swift Array Append 覆盖其他数组值 [英] Swift Array Append Overwriting Other Array Values

查看:34
本文介绍了Swift Array Append 覆盖其他数组值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Swift 的新手,但我对编码并不陌生.我想我会尝试制作一个小游戏.这是我在学习时喜欢做的事情.

I'm new to Swift, but I'm not new to coding. I thought I would try my hand at making a little game. It's something I like to do when learning.

这就是我正在做的事情.我首先调用一个方法来初始化我的对象模板"

Here's what I'm doing. I start of by calling a method that initialized my "object templates"

internal func initializeObjectTemplates(){
    objectTemplates.append(GameObject(passed_x: 0,
        passed_y: 0,
        passed_max: 25,
        passed_min: 25,
        passed_points: 100,
        passed_img: "BeerGlass1",
        passedLengthOfTimeOnScreen: 5,
        passedBottomChance: 1,
        passedTopChance: 50,
        passedId: 0))
    objectTemplates.append(GameObject(passed_x: 0,
        passed_y: 0,
        passed_max: 25,
        passed_min: 25,
        passed_points: 300,
        passed_img: "BeerGlass2",
        passedLengthOfTimeOnScreen: 2,
        passedBottomChance: 51,
        passedTopChance: 100,
        passedId: 0))

}

我有一个计时器,它每秒运行一个名为update"的函数.更新"函数随机选择两个模板之一,向模板对象添加一些其他信息,执行其他一些逻辑,并将对象附加到我拥有的数组中.直到 append 的一切似乎都在工作.我添加了各种断点,并且 GameObject 对象似乎已正确填充.

I have a timer that runs a func named "update" every second. The "update" func randomly selects one of the two templates, adds some other information to the template object, does some other logic, and appends the object to an array I have. Everything up to the append seems to be working. I have added various breakpoints and the GameObject object seems to be getting populated correctly.

当我追加对象时,它会覆盖对象数组中的其他项目.我想不通.我已经尽可能多地搜索了它,但似乎无法真正找到适合我的问题的任何内容.这是我与此相关的其余代码.

When I append the object it is overwriting other items in the objects array. I can't figure it out. I've googled it as much as possible, and can't really seem to find anything that fits my issue. Here's the rest of my code related to this.

这是ViewController和viewDidLoad的顶部

This is the top of the ViewController and the viewDidLoad

internal var step = 0
internal var objects = [GameObject]()

@IBOutlet weak var points: UILabel!

internal var objectTemplates = [GameObject]()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    view.backgroundColor = UIColor.blackColor()

    initializeObjectTemplates()

    let timer = NSTimer(timeInterval: 1, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
    //var i = 1
    //while i <= 100{
    //    update()
    //    i += 1
    //}
}

Update Func - 注释掉/硬编码的附加工作,但显然不是我想要的

Update Func - the commented out/hard coded append works, but obviously not what I want

internal func update(){
    step += 1

    //removeExpiredButtons()

    objects.append(populateObjectTemplate(selectObjectTemplate(), step: step))

    //objects.append(GameObject(passed_x: 0,
    //    passed_y: 0,
    //    passed_max: 25,
    //    passed_min: 25,
    //    passed_points: 300,
    //    passed_img: "BeerGlass2",
    //    passedLengthOfTimeOnScreen: 2,
    //    passedBottomChance: 51,
    //    passedTopChance: 100,
    //    passedId: step))

    print("There are \(objects.count) items and the first item has an id of \(objects[0].id)")
}

这些是更新调用的方法

选择对象模板

func selectObjectTemplate() -> GameObject {
    let rand = Random.within(1...100)
    return objectTemplates.filter(){
        let isAbove = $0.bottomChance <= rand
        let isBelow = $0.topChance >= rand

        return isAbove && isBelow
        }[0]
}

populateObjectTemplate

populateObjectTemplate

func populateObjectTemplate(obj: GameObject, step: Int) -> GameObject {
    let widthBoundary = Float(self.view.frame.width - 20)
    let heightBoundary = Float(self.view.frame.height - 20)

    let placex = CGFloat(Random.within(20.0...widthBoundary))
    obj.x = placex

    let placey = CGFloat(Random.within(50.0...heightBoundary))
    obj.y = placey

    obj.expiration = obj.lengthOfTimeOnScreen + step
    obj.id = step

    obj.button = populateObjectButton(obj)

    return obj
}

填充对象按钮

func populateObjectButton(obj: GameObject) -> UIButton {
    let button = UIButton(type: UIButtonType.Custom)
    let image = UIImage(named: obj.img)

    button.setBackgroundImage(image, forState: UIControlState.Normal)
    button.frame = CGRectMake(obj.x, obj.y, obj.minSize, obj.minSize)
    button.layer.cornerRadius = 0.5 * button.bounds.size.width
    button.layer.masksToBounds = true
    button.addTarget(self, action: #selector(ViewController.objectTapped(_:)), forControlEvents: .TouchUpInside)
    button.tag = obj.id

    self.view.addSubview(button)

    return button
}

抱歉发了这么长的帖子.我只是想包含尽可能多的信息.我通常不会在这样的地方发帖,因为我自己会尽可能努力地找到解决方案.swift 文件也在 Git 上.

Sorry for such a lengthy post. I just wanted to include as much information as possible. I don't usually post to places like this, because I try as hard as possible to find the solution myself. The swift file is also on Git.

https://github.com/JoeBrewing/TapGlassMasterChallenge/blob/master/Glass%20Tap%20Master%20Challenge/ViewController.swift

推荐答案

您的 objectTemplates 数组存储对 initializeObjectTemplates 中创建的两个 GameObject 实例的引用代码>.当您的计时器触发时,您可以选择这些模板"对象之一,对其进行修改并将其添加到数组中.但是,该数组仅存储对您添加到其中的对象的引用,并且您只有两个对象,即使您多次将这些对象添加到数组中.

Your objectTemplates array stores references to two GameObject instances that were created in initializeObjectTemplates. When your timer fires you select one of these 'template' objects, modify it and add it to the array. However, the array is merely storing references to the objects you add to it, and you only have two objects, even though you are adding those objects to the array multiple times.

当您调用 populateObjectTemplate 时,您修改了两个对象模板之一,这意味着数组中引用该特定模板的所有其他条目将反映这些修改.您需要 populateObjectTemplate 返回一个新的 GameObject,使用模板中的信息;

When you call populateObjectTemplate you modify one of the two object templates, which means that all other entries in the array that refer to that particular template will reflect those modifications. You need populateObjectTemplate to return a new GameObject, using the information in the template;

func populateObjectTemplate(obj: GameObject, step: Int) -> GameObject {

    let newGameObject=GameObject(passed_x: 0,
    passed_y: obj.passed_y,
    passed_max: obj.passed_max,
    passed_min: obj.passed_min,
    passed_points: obj.passed_points,
    passed_img: obj.passed_img,
    passedLengthOfTimeOnScreen: obj.passedLengthOfTimeOnScreen,
    passedBottomChance: obj.passedBottomChance,
    passedTopChance: obj.passedTopChance,
    passedId: obj.passedId)

    let widthBoundary = Float(self.view.frame.width - 20)
    let heightBoundary = Float(self.view.frame.height - 20)

    let placex = CGFloat(Random.within(20.0...widthBoundary))
    newGameObject.x = placex

    let placey = CGFloat(Random.within(50.0...heightBoundary))
    newGameObject.y = placey

    newGameObject.expiration = obj.lengthOfTimeOnScreen + step
    newGameObject.id = step

    newGameObject.button = populateObjectButton(obj)

    return newGameObject
}

这篇关于Swift Array Append 覆盖其他数组值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆