I'm working a little game for iOS (spritekit/swift).
I've an array of SKSpriteNode in my scene defined like this:
var spritesTree = [SKSpriteNode]()
then I fill the array with a function and add them to the scene like this:
spritesTree = spritesCollectionTree(count: numTrees)
for sprite in spritesTree {
addChild(sprite)
}
After that, depending the situation the process adds some more trees into the array. I Know how to remove elements from the scene and the array if I Know the index
spritesTree[i].removeFromParent()
spritesTree.removeAtIndex(i)
but my problem is to remove an especific node in this array when I don't Know the index. For exemple when one of the the sprite was touched
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
let positionInScene = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
In this case, ¿How can I remove the touchedNode from my array spritesTree of SKSpriteNode if I don't know the index? I read something about indexOf to find the index previoustly but it doesn't work with my SKSpriteNode array. Could you help me please?
Bests,
You can create a name for each SKSpriteNode :
spritesTree[index].name = String(index)
After when you check node touched you convert name to Int
let location = touch.locationInNode(self)
let positionInScene = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
var index = Int(touchedNode.name)
touchedNode.removeFromParent()
spritesTree.removeAtIndex(index)
Related
Im fairly new to using arrays, and was playing around with the following code in swift playgrounds:
var array = [SKSpriteNode]()
let sprite = SKSpriteNode()
sprite.name = "off"
print(sprite.name!) // "off"
array.append(sprite)
sprite.name = "on"
print(sprite.name!) // "on"
for i in array {
print(i.name!) // "on" ???
}
The name of the sprite is "off". I then add this sprite to the array. Next I change the name of the sprite to "on".
When I check the name of the sprite with a for loop within the array, its name is "on"?
Why is this? I thought arrays just held information, therefore the sprite.name in the array would be the sprite.name when I added it? Or are they linked? Does changing the sprite.name outside the array also change the sprite.name inside the array?
Sorry if I am not fully understanding this.
Thanks!
I am trying to make a main menu for an Mac application as a beginning task to learn about Swift. Here is my code, which does not work.
In the AppDelegate
import Foundation
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
{
#IBOutlet weak var window: NSWindow!
//private let mainWindow = NSWindow(frame: NSWindow.mainScreen().bounds)
//let mainWindow = NSWindow()
//let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSSquareStatusItemLength)
func applicationDidFinishLaunching(aNotification: NSNotification)
{
// Insert code here to initialize your application
let menuData = [getMainMenuItems]
//[makeMainMenu, menuData]
}
}
And then in a different project file, named Swift_FileManager
import Foundation
import Cocoa
class menuArrayObject
{
var title: String = ""
var subMenuTitles: [String] = []
}
func getMainMenuItems (menuData:Array<AnyObject>) -> AnyObject
{
//Make a new menu array
var menuData = [AnyObject]()
let arrayObject1 = menuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)
return menuData
}
The code compiles but the function getMainMenuItems is never called.
Can somebody shed some light on the (probably very simple) issue here? Thanks in advance
let menuData = [getMainMenuItems]
This line (probably) isn't doing what you think it's doing. What it's doing is creating an array of [(Array<AnyObject>)->(AnyObject)] type (an array of functions that take an array of AnyObjects as input, and return an AnyObject) – and adding your getMainMenuItems function to it.
It's not calling your function at all.
In order to call a function, you need to use a pair of brackets (), containing the required input. In this case, your getMainMenuItems method expects an array of AnyObjects (although it never appears to actually use them).
For example:
let menuData = getMainMenuItems([/* Insert your objects here */])
Although that all being said, I'm not entirely sure that your getMainMenuItems function actually needs an input, as you never use it. I think you're looking for something like this:
func getMainMenuItems() -> [MenuArrayObject] {
// create an empty array of MenuArrayObjects
var menuData = [MenuArrayObject]()
let arrayObject1 = MenuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)
return menuData
}
Note that the function no longer has an input, and I've replaced AnyObject with [MenuArrayObject]. It's best to be as type specific as you can in Swift (and pretty much every other OOP language), so you should really steer away from AnyObject unless you have good reason to use it.
Now you can just invoke your function like this:
let menuData = getMainMenuItems()
and it will return an array of MenuArrayObjects.
If you're trying to make the function so that it'll add an object to an already existing array, then you can use an inout parameter in your function. This will let you pass an array into your function, which it can modify.
For example:
func getMainMenuItems(inout menuData:[MenuArrayObject]) {
let arrayObject1 = MenuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)
}
You can then call it like so:
// an existing array of MenuArrayObjects
var menuDataArray = [MenuArrayObject]()
// call function with array – which it will append an element to
getMainMenuItems(&menuDataArray)
The code let menuData = [getMainMenuItems] is just creating an array containing the function. I'm guessing that you mean to call the function instead. That looks something like:
let menuData = getMainMenuItems([])
In applicationDidFinishLaunching you need to instantiate menuArrayObject:
let myMenuArray = menuArrayObject()
And then call it:
let menuData = myMenuArray.getMainMenuItems()
Your getMainMenuItems method, it seems looking at what you wrote in the method, should be defined as:
func getMainMenuItems() -> [AnyObject]
I'm making a simple game in swift and xcode and I ran into this problem that I can't figure out. Because I have so many levels, the code locks up indexing and slows down the whole program. I get a color wheel spinning for a few minutes but it never crashes. Just takes several minutes everytime I type in a few characters. Strange, but xcode has always had it's bugs right?
Each Button ("button1, button2..." below) gets a single number from "level1:Array". It's like a code that fills in the button's value for the game. There are only 4 buttons, but the numbers should be able to change as they each have their own variables.
I want to generate this for every level. I should be able to generate something like "button1 = level#[0]" where # is replaced by "userLevel". Changing to a string and doing something like "button1 = ("level(userLevel)") as! Array... doesn't seem to work. Look below and use my terminology when giving examples if you can. Thanks!
Here's the example:
let level1:Array = [9,7,4,1] // current puzzle, to go directly into button vars below (button1,button2,ect)
var userLevel = 1 // current user's level
if userLevel == 1 {
print("making Level 1, setting buttons to value from array")
button1 = level1[0]
button2 = level1[1]
button3 = level1[2]
button4 = level1[3]
}
Now, since level# is repeated so often (for each level as the number progresses) I would rather just make it something like this:
//this doesn't work in swift, but what else can I do?
if userLevel > 0 {
button1 = level\(userLevel)[0]
button2 = level\(userLevel)[1]
button3 = level\(userLevel)[2]
button4 = level\(userLevel)[3]
}
Is there an easy way to do this? Thanks!
-GG
Try using a for-in loop. Create an array of the buttons, and then
var index = 0
for button in buttons {
button = level1[index]
index++
}
EDIT since you want both the user level and the level number to increase, I suggest you define the levels like this. (Make sure that the number of buttons is equal to the number of userLevels, otherwise you will have problems)
var array = [1,2,3]
let levels = [1:[1,3,8],2:[3,6,4],3:[4,2,5]]
var index = 0
if array.count == levels.count {
for number in array {
array[index] = levels[index+1]![index]//The second index can be 0 if you want
index++
}
}
//array = [1,6,5]
// You could create a second index to match the number of levels within the main user level.
In this case, assume array to be your array of buttons
EDIT 2 :)
I've made a function that will allow you to assign all the levels to your array for a specific userLevel, since I see that is what you want
let levels = [1:[1,3,8],2:[3,6,4],3:[4,2,5]]
func assignValuesToArray(levelNo:Int) -> [Int] {
var array: [Int] = []
if (levelNo > 0) && (levelNo <= levels.count) {
for (level,levelArray) in levels {
if level == levelNo {
for value in levelArray {
array.append(value)
}
}
}
return array
} else {
print("This Level number does not exist")
return []
}
}
var finalArray = assignValuesToArray(2)
print(finalArray) // Returns [3,6,4]
As you can see from this example, you will return your array of buttons from the function, and you can assign the returned array values to whatever you like.
I am trying to create an app in which one of a few objects is randomly placed on the screen wherever you touch. I have my objects a, b, and c and I have them in an array.
(NSArray *) gamePieces {
NSArray *things = [NSArray arrayWithObjects: #"a", #"b", #"c", nil];
return things;
}
And then my touch method.
(void)touchesBegan:(NSArray *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
// code that chooses random object from array
}
}
Normally I would put in an SKSpriteNode and it would make just that one appear on the screen, but I am looking to randomly select one of many. I'm new to programming and I'm not sure if I'm on the right path. If I am, what needs to go in the touch method? If not, what am I doing wrong?
You can get a random item by getting a random index based on the number of elements in the array :
int randomIndex = arc4Random() % things.count;
NSString *thing = things[randomIndex];
// do something with thing
I have created an array as shown below
protected function getMyArray(dataArray:Array):Array
{
var labelList:Array=new Array;
for each (var property:Object in dataArray)
{
if (labelList[property.bucketTime] != property.bucketTime)
labelList[property.bucketTime]=property.bucketTime;
}
return labelList;
}
Is it possible to sort the array labelList based on property.bucketTime?
Edit: Sample input dataArray will be like this :
var tempObj:Object = new Object;
tempObj.bucketTime = DateField.stringToDate("30-01-2010", "DD-MM-YYYY").time;
tempObj.score = 76;
dataArray.addItem(tempObj);
tempObj = new Object;
tempObj.bucketTime = DateField.stringToDate("13-02-2010", "DD-MM-YYYY").time;
tempObj.score = 21;
dataArray.addItem(tempObj);
tempObj = new Object;
tempObj.bucketTime = DateField.stringToDate("30-03-2010", "DD-MM-YYYY").time;
tempObj.score = 10;
tempArry.addItem(tempObj);
Unless bucketTime is a number; then you aren't actually populating the array. You're just adding properties to the Array Object, almost like it were a Dictionary. I've seen a Dictionary called Associative Array's and Structures in other languages.
If that is the case, an you're using the Array class as a dictionary, then there is no way to sort it. The very nature of such a structure is that they are not sortable.
However, if property.bucketTime is a number, and you are trying adding items to the array as if they were an array, you can sort using the Array.sort or Array.sortOn methods.
Atlast I sorted the labelList Array.Please find my solution below. Let me know if there is any better way to achieve this.
var termObject:Object = ObjectUtil.getClassInfo(labelList);
var termsArray:Array = termObject.properties;
var sortedColumnArray:Array = new Array;
for each(var term:Object in termsArray){
if(labelList.hasOwnProperty(term)){
sortedColumnArray.push(labelList[term]);
}
}