Movie Clip through Display Object Not working correctly - arrays

Hey everyone so I have a movie Clip called popEffect that i want to show on the current bubbles that are being clicked by the mouse. Now Whenever I click on a Bubble everything works correctly they get removed from the stage, but the problem I am having is that the popEffect is not positioned to the current bubbles that are being clicked. Instead they are positioned at a different bubble that shows on the screen in the display object array.
Here is how I have it all set up:
private function addBubbles(e:TimerEvent):void
{
bubbles = new mcBubbles();
stage.addChild(bubbles);
aBubbleArray.push(bubbles);
bubbles.addEventListener(MouseEvent.CLICK, bubblesBeingClicked);
}
Then the BubblesBeingClicked function:
private function bubblesBeingClicked(e:MouseEvent):void
{
var BubblePop:DisplayObject = e.target as DisplayObject; // HERE is your clicked square
var i:int = aBubbleArray.indexOf(BubblePop); // and HERE is your index in the array
if (i < 0)
{
// the MC is out of the array
//trace("Pop Clicked");
onBubbleIsClicked(BubblePop);
aBubbleArray.splice(i, 1);
BubblePop.parent.removeChild(BubblePop);
//Remove Listeners!!!
BubblePop.removeEventListener(MouseEvent.MOUSE_DOWN, onBubbleIsClicked);
// Null
BubblePop = null;
}
}
Finally my onBubbleIsClicked function where i have the popEffect located:
private function onBubbleIsClicked(bubblePop:DisplayObject):void
{
nScore++;
updateHighScore();
//Pop Effect
popEffect = new mcBubblePop();
stage.addChild(popEffect);
popEffect.x = bubbles.x;
popEffect.y = bubbles.y;
}
Can anyone see why the popEffect wont position on the current bubble that is being popped? Its acting really weird.

The reason is this:
popEffect.x = bubbles.x;
popEffect.y = bubbles.y;
As far as I can understand, bubbles is a member variable in the class (you are using it in the addBubbles function. Inside onBubbleIsClicked, you provide bubblePop, but do not use it. You are using bubbles instead, which is actually the last instance you've created inside the tick function!
So every time you create popEffect, you actually assign the x and y to the latest created bubblePop.
Some advises:
Do not use member variables that often. They are used WHEN you need to use a variable between functions. In your case, bubbles is a variable that is used only inside the creational function. You even put them into an array! And because you override it with a new one every time you create an instance, your member variables just saves the last one. Is this really needed? Same with popEffect, does anyone else uses it, as it's again just the last one? Such things create mistakes, as you see..
I truly don't understand what this means: if (i < 0). You search if the object you've clicked is not in the array? Well if it is not (how come?!), then what's the meaning of aBubbleArray.splice(i, 1);? Since i < 0, you actually splice with negative value, so you splice some other element! Plan what you want to do, thing logically and then do the actual code. If the object is not in the array, then why do you remove anything from the array?
Start formatting your code better. Read about camel case and variables scope.
Try to manage your logic better. For example this is pretty awkward: BubblePop.parent.removeChild(BubblePop);, as long as you've added it by using stage.addChild(bubbles);. So isn't it more simple to use stage.removeChild(child);? There are some rules in programming (especially in Flash), like 'what added it should remove it'. This will keep you safe in future.
Good luck!

Related

When trying to remove an item from array errors

So when writing a game on Khan Academy When I try to remove a bullet from the array I run into the error "Object does not support method splice" I have been checking my code for hours and have not found out why it does not work. Ideas?
EDIT: The code used to remove a bullet is bullets[i].splice(i,1); and that is what errors out my code.
MVCE:
var bullets = [];
var bullet= function(x,y,blah)
{
//code that is not important here
};
bullets.push(bullet(0,0,30));
for(var I = 0; I < bullets.length; I++){
if(bulletRemove){
bullets[I].splice(i,1)
}
}
You have a variable named bullets:
var bullets = [];
(Side note: Why is there a random curly bracket right before this line?)
This bullets variable is an array. It holds instances of the Bullet class:
bullets.push(new Bullet(x, y, 10, player.x+bSize/2, player.y+bSize/2));
You can use the array to access a Bullet at a particular index, and then you can call functions of the Bullet class on that instance:
bullets[i].move();
You can also call the splice() function on the array itself:
bullets.splice(i,1);
However, you can't call the splice() function on a particular Bullet instance!
bullets[i].splice(i,1);
This line is taking an instance of Bullet from the i index of the bullets array, and then trying to call the splice() function from the Bullet class. But the Bullet class doesn't have a splice() function! This is what's causing the error.
Instead, you probably meant to call it on the array itself:
bullets.splice(i,1);
In the future, please please please try to narrow your problem down before posting a question. Try to post an MCVE instead of your entire project. You could have put together an example program that used just a few lines to create a hard-coded array and used that to demonstrate your problem. Chances are you would have found the problem yourself in the process of creating the MCVE!

Add scope variable to array and then stop data bind

For reference, here is the fiddle: http://jsfiddle.net/6u3Gn/1/
I am playing around with angular and ran into a behavior that I can understand, but am not sure how to stop. I created a simple form for places and things, where you define a place, and then you can add things at that place. When the button to add a thing is clicked, it successfully adds the thing to the place:
$scope.addThing = function() {
if ('things' in $scope.place) {
$scope.place.things.push($scope.thing);
} else {
var things = [$scope.thing]
$scope.place['things'] = thing;
}
};
However, when I try to add another thing, the first one is still bound to $scope.thing, so the first one updates to be the exact same as the second thing I add.
How can I stop the 2 way data binding once the object in the array has been added? Is there a way to do so, or am I going about adding it to the array all wrong?
Well that was easy. Not exactly sure how I missed it but the right way to do this is to use angular.copy($scope.variable). Whoops!

Deleting movieclip and clearing memory AS3

Another question from me.
For example I've made something like this.
var unit:Array = new Array()
public function add_unit()
{
unit[unit.length] = new unitclass(parameter)
}
public function remove_unit(index)
{
for(var i:int = index; i< unit.length; i++)
{
unit[i] = unit[i+1]
}
unit.pop()
}
Will after using function remove_unit, with specified id the stage will be totaly clear of the array element? If not how do I clear it properly?
Its hard to understand your question...
To add an element to an array use unit.push(new [your_object]());
To remove an element from an array use unit.splice([index], 1);
To add an element to display object(Stage, Sprite, Movieclip etc..) use [DisplayObject].addChild([element]);
To remove a element from a display object(Stage, Sprite, Movieclip etc..) use [DisplayObject].removeChild([element]);
Removing an element from an array wont remove it from the stage, you must call removeChild with the object you wish to remove from the display list.
Ok ok. I'm not used to as3, so I don't know many commands yet.
Still can you tell me: if I use these functions above the effect will be achieved? I just want to add unit to array and then remove it from memory.
I'm just noticing that my application is starting to jam and I don't really know why is this happening. Does this action clear the memory properly? I tried using splice and push instead of the method mentioned at the beginning, but this doesn't seem to help.

How to effectively garbage collect in AS3

I have a flash game that I'm building where I have an array keeping track of a bunch of power ups on the screen. When the player goes an grabs one it needs to disappear from the screen (which is easy) but it also needs to be removed from the array so that collision detection loops don't become really cumbersome. I tried using splice, but I keep get null reference errors, here's the relevant code.
public function collect():void {
try {
Main.powerUps.splice(index, 1);
stage.removeChild(this);
}catch (e:Error) {
trace("Error in splice");
}
}
}
Then when I create my PowerUp object I pass it a parameter that gets assigned to index which is the length of the array of Power Ups at the time. Can anyone see what's wrong with this code or (preferably) provide a more elegant solution? Thanks in advance for any help.
Elegant solution: use indexOf() and splice() together!
var index:int = Main.powerUps.indexOf( powerup );
Main.powerUps.splice(index, 1);
Where powerup is a reference to the object stored within the array Main.powerUps.
I also created a little class a while back that may be useful to you:
https://github.com/MartyWallace/Lotus/blob/master/Lotus/lotus/utils/Set.as
It has a .remove() method so you can just do:
powerUps.remove(powerup);

Array of Colors error. Bug?

K. I'm getting stuck here.
I'm trying to make an array with different color values.
My problem is that when I do...
teamColor[i] = currentColor... all color values in my array turn into the currentColor.
(I would upload more code, but that would be a massive mess, considering that I have code everywhere with references from movie clips that are as far as 3 layers deep. HOWEVER, this would be irrelevant anyways (probably), because I tested this with color values on my main timeline, without any references to or from anything deeply nested)
I'm GUESSING that this is just some horrible bug, but if it's not (and I hope it isn't), please guide me in what to do to fix this problem.
I would like to add that I tried adding strings in there and that the strings remained their original, intended, value, while the color exhibited the same phenomenon.
[Partially resolved]:
I changed my code by creating separate variables for each color instead of putting the variables into an array (not what I really wanted to do, but it works). My code looks like this:
`
if (teamColor != 0)
{
this["team"+teamColor+"Color"] = new ColorTransform(0,0,0,1,currentColor.redOffset,currentColor.greenOffset,currentColor.blueOffset,0)
teamColor = 0
namebox.addboxes()//function in a movieclip
}`
teamColor is now an int that is changed based on which box a user clicks from a movie clip that has a dynamically generated name, based off of what the variable value in a loop was when it was created. (E.G: 'tempboxname[ttns].name = i;')
teamColor is then equal to that name when the user clicks it.
I have another movieclip with colors in it and the above function is called to check if any teamColor change has occurred, and if it has, act accordingly. (The idea of having teamColor equal to 0 is so that if the user clicks twice, nothing changes. I other conditionals for other colors, all within the same function).
That is how I fixed me code.
It's not what I wanted, because it's not an array (meaning a seemingly infinite number of teamColors, and thus, teams) but it'll do for me. If anyone has any suggestions, feel free to suggest.
I'm no ActionScript wiz, but what it looks like to me is that currentColor is an object that is being passed into the array by reference. This means that all array entries that you assigned currentColor will be pointing at the same currentColor object, not a copy. My advice is to make a copy and then assign that into the array.
It would be much better if you could give me more code to look at. For instance, the loop that contains that code segment would be nice. If I find a different error I'll edit my answer.
here i'm creating and then adding simple 0xRRGGBB color objects into a vector. the color objects are then parsed into 0xRRGGBB hexadecimal strings and traced.
certainly it's not exactly what your looking for, but hopefully it will help you.
var red:uint = 0xFF0000;
var green:uint = 0x00FF00;
var blue:uint = 0x0000FF;
var colors:Vector.<uint> = new Vector.<uint>()
colors.push(red, green, blue);
for each (var color:uint in colors)
{
var output:String = color.toString(16);
while (output.length < 6)
output = "0" + output;
trace("0x" + output.toUpperCase());
}
Output:
//0xFF0000
//0x00FF00
//0x0000FF

Resources