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!
Related
I'm using SpriteKit and Swift 3 to create a simple game.
I have an array of Rings/Circles:
mRings = [mRingOne, mRingTwo, mRingThree, mRingFour, mRingFive]
each object in the array has a different color, In some point in the game I want to change the color of each ring, but I have 2 condition for this to happen:
1. a ring should not have the color it had one iteration before.
2. each ring should be in a different color from the others.
for the first condition I did this:
func changeRingsColor(){
var previousColor: UIColor?
for ring in mRings {
previousColor = ring.fillColor
repeat{
ring.fillColor = hexStringToUIColor(hex: mColors[Int(arc4random_uniform(UInt32(5)))])
}while(ring.fillColor.isEqual(previousColor))
}
}
and it is working, however, I couldn't figure out a way to answer the second condition.
In Java I would probably do something like this:
for (int i=0; i<mRings.length; i++){
for( int j=1; j<mRings.length; j++){
if (ring[i].fillColor == ring[j].fillColor){
generate another color for 'j' ring.
}
}
}
but nothing I tried worked.
Hope you guys can help me, Thanks in advance!
btw, mColors is an array of 5 different colors, from there I pick the colors.
I'm going to ignore some of the implementation details and focus on the core of the question, which is:
Loop through an array
Within each loop, start a new loop at the current index to the end of the array.
Let me know if I'm misunderstanding the above. But I would do it like this:
for (index, ring) in mRings.enumerated() {
let remainingRings = mRings[index+1..<mRings.count]
for otherRing in remainingRings {
print("Now comparing \(ring) to \(otherRing)")
}
}
First, enumerated() gives you both the current ring, and the index, on each iteration of the first for loop. Then, we slice the array from the current index to the end (remainingRings), and loop through those.
It is possible to rewrite Java code in this way :
let mRings = ["mRingOne", "mRingTwo", "mRingThree", "mRingFour", "mRingFive"]
for (index, item) in mRings.enumerated() {
for item in index + 1..<mRings.count {
}
}
Something like this will work:
func changeRingsColor(){
// extract the previous colors
let colors = rings.map { $0.fillColor }
// the order in which the rings will pass color to each other
let passOrder = mRings.indices.shuffled()
for i in mRings.indices {
let previous = i == 0 ? mRings.count - 1 : i - 1
mRings[passOrder[i]].fillColor = colors[passOrder[previous]]
}
}
Using this implementation of shuffled
How does it work?
Instead of randomly choosing a color for each individual ring, I am randomly generating an order in which the rings will swap the colors (passOrder). Since every ring will pass its color to a different ring in that order, you can be sure no color will stay the same.
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)
I'm trying to make a guessing game in SpriteKit. My questions are images that I need to display once. I can't understand how to display them properly and only once. I have an array of them:
var pics = ["queston1","question2","question3","question4","question5"]
For that purpose I tried to show them with textures like that:
var pic = SKSpriteNode(imageNamed: "question1")
func setPics() {
pic.texture = SKTexture(imageNamed: "question1")
pic.name = pic.texture
addChild(pic)
}
Then I put setPics() at didMoveToView and loop through buttons:
case trueButton:
if pic.name == "question1"
//also tried if pic.texture == pic[0] {
print("true")
pic.texture = pic[1]
pic.removeAtIndex[0] //to prevent displaying it another time
// pic.texture = SKTexture(imageNamed: "question2"
}
if pic.texture == "question2" {
...
And so on. It doesn't work. And I understand that I'm doing it wrong, but I don't know how to do it better. This logic kind of worked when I tried to use random instead of hardcoding which question would be the next, but now it's completely wrong. But with random it was another problem. Textures layered on top of each other even though I was removing them from array.
How to make it right?
i've created an array. Each element is a button object. Is there a possibility to hook mouseclick on every array at the same time? I mean something like this.
var Objects:Array = new Array
Objects[0] = new button(parameters)
Objects[1] = new button(parameters)
Objects[2] = new button(parameters)
Objects[n].addEventListener(MouseEvent.CLICK, Clicked(n));
function Clicked(n,...)
{
THECODE PROCEEEEDS for Objects[n]
}
I know that's not the clearest and most correct writing, but I'm asking if this is possible in similiar way? And how to do it? I know I can hook every mouseclick and then check if the clicked under the mouse is one of the array elements with for loop, but I'm asking about this way.
Yes. You are unable to directly pass an index into a listener, but you can retrieve that via calling indexOf() inside it.
for each (b in Objects) b.addEventListener(MouseEvent.CLICK, clicked);
// note, you just put function name here!
public function clicked(e:MouseEent):void {
var i:int=Object.indexOf(e.target);
if (i==-1) {
// panic behavior
return;
}
// now you can parse that index into something valuable
}
I am making a little game and I have an array. The array contains 4 characters. When one of the characters is clicked the opacity should turn to 0, if another is clicked the same should also happen.
So far I have put the array into a function but the function will only hide one of the characters, and not even the one which is clicked. Could anyone help me please? Here is the code I have:
for(var g:int = 0; g<ghostsL.length; g++){
ghostsL[g].addEventListener(MouseEvent.CLICK, clickGrey)
};
function clickGrey(e:MouseEvent):void{
this.ghostsL[i].alpha = 0;
var npoint:NPoint = new NPoint();
npoint.play();
};
We do not know what this.ghostsL[i] is.
Why don't you just do it this way:
function clickGrey(e:MouseEvent):void{
MovieClip(e.currentTarget).alpha = 0;
var npoint:NPoint = new NPoint();
npoint.play();
};