Remove the clicked objects - actionscript-3

I'm trying to remove the array objects that are being clicked and add them into another array to display them else where. I posted the current code.
I think the problem maybe with .currentTarget. I tried replacing the .currentTarget to .target but the function wasn't getting past this line : if (socket_Array[i] == in_event.target) (in this version its .currentTarget, I am just saying when I tried changing it to .target)
The error I get is this:
TypeError: Error #1034: Type Coercion failed: cannot convert []#2c2a8f11 to flash.display.DisplayObject.
Function that creates the objects:
function createSockets():void
{
var socket_one:socket = new socket ();
var socket_two: socketyellow = new socketyellow ();
var socket_three: socketdarkorange = new socketdarkorange ();
var socket_four: socketlightgreen= new socketlightgreen ();
var socket_five: socketpurple = new socketpurple ();
var socket_six: socketdarkgreen = new socketdarkgreen ();
socket_Array.push(socket_one, socket_two,socket_three, socket_four, socket_five, socket_six);
for (var i:int=0; i<socket_Array.length; i++)
{
addChild(socket_Array[i]);
socket_Array [i].x = socket_x_position;
socket_Array [i].y = socket_y_position;
socket_Array[i].addEventListener(MouseEvent.MOUSE_DOWN, removeItemOnClick);
}
temp_update ();
}
Function that is suppose to get rid of the object clicked and add it to an array.
function removeItemOnClick(in_event:MouseEvent):void
{
var i:int = 0;
for (i=0; i<socket_Array.length; i++)
{
if (socket_Array[i] == in_event.currentTarget)
{
trace ("it goes here");
var removed = socket_Array.splice(i, 1);
trace (removed);
trace (socket_Array );
var drop:Sprite = in_event.currentTarget as Sprite;
removeChild (drop);
removedItem[removedItem.length] = removed;
createremovedItem ();
trace (removedItem);
updateDisplay ();
choice_updateDisplay ();
}
}
}
var removedItem_position = 0
function createremovedItem () {
for (removedItem_position; removedItem_position<removedItem.length; removedItem_position++){
addChild (removedItem [removedItem_position]);
}
}

First of all, .currentTarget is correct.
Secondly, there's no point in calling removeChild() and then calling addChild(). The net effect of both calls is nothing.
Almost all of the code in the second function is unnecessary. Here's a shorter version:
function removeItemOnClick(in_event:MouseEvent):void {
var index:int = socket_Array.indexOf(in_event.currentTarget);
var drop:Sprite = socket_Array.splice(index,1) as Sprite;
removedItem.push(drop);
updateDisplay();
choice_updateDisplay();
}
If you want to display the new item elsewhere, just change drop.x and drop.y.

As the error suggests it looks like it is problem with type coercion.
Try to replace the condition of your if statement with this:
if (DisplayObject(socket_Array[i]) == DisplayObject(in_event.currentTarget))
In case this is not working your might have more information while debugging by storing the two objects you want to compare into temporary variables

Related

AS3 Remove items in an ENTER_FRAME

I have generated random bubbles, I used a code I found in the net. Now I want a click event that will hide a random bubble.
Here is exactly the code I used,
http://good-tutorials-4u.blogspot.com/2009/04/flash-bubbles-with-actionscript-3.html
I got the bubbles running good...
I have tried this, and so far no luck..
addEventListener(MouseEvent.CLICK, eventListener);
function eventListener(eventObject:MouseEvent) {
bubbles[i].splice(i,1,bubbles[i]);
}
I tried using an array but it returns me this output
TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/removeChild()
at Function/()
TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/removeChild()
at Function/()
If you have the bubbles in an array this should work.
var randomIndex:int = int(Math.random() * bubbles.length);
parent.removeChild(bubbles[randomIndex]);
bubbles.splice(randomIndex, 1);
Notice that you have to remove the bubble from the display list too.
You can try creating a new array without a random element from the original array. Then just reassign the old array to the new one, e.g.
// get the random index to remove element at
var randomIndex:int = 0 + bubbles.length * Math.random();
var index:int = 0;
// create new array containing all apart from the chosen one
var newBubbles:Array = [];
for each (var item:Object in bubbles) {
if (index != randomIndex) {
newBubbles.push(item);
}
index++;
}
// here you go new array without one random item
bubbles = newBubbles;
Or something like these.
Just a minor revision on Baris Usakli's code here, this is if you want the one that was clicked on to be removed.
var bubbles:Array = [];
function makeBubbles()
{
for(var i:int=0;i<100;i++)
{
var bubble:Bubble = new Bubble();
bubbles.push(bubble);
addChild(bubble);
bubble.addEventListener(MouseEvent.CLICK, eventListener);
}
}
function eventListener(eventObject:MouseEvent) {
var clickedBubbleIndex:int = bubbles.indexOf(eventObject.currentTarget);
parent.removeChild(eventObject.currentTarget);
bubbles.splice(clickedBubbleIndex:int, 1);
}
try this
bubbles.addEventListener(MouseEvent.CLICK, eventListener); // place this listener in moveBubbles function.
function eventListener(eventObject:MouseEvent):void {
eventObject.currentTarget.visible = false;
}

AS3 multiple file download, check when completed?

I am looping through a small array of file names to grab from a remote server and save locally. This bit works OK.
The problem is, I need to run my next function when the downloads are complete.
Currently, my function, lets call it step2(), gets called before all the FileStreams can finish (infact, its called before that function even starts!)
I read that there is a complete event listener when using openAsynch, but I need to check that all files, e.g. 3 remote swfs) have been written and then start step2() function.
How can I go about this?
Code below:
function onPlaylistComplete(e:Event)
{
var myArray:Array = new Array();
for each(var i in list_of_files)
{
myArray.push(i);
}
for(i = 0; i < myArray.length; i++)
{
swfItem = myArray[i];
var urlString:String = site_url + myArray[i];
var urlReq:URLRequest = new URLRequest(urlString);
var urlStream:URLStream = new URLStream();
urlStream.addEventListener(Event.COMPLETE, urlStreamComplete(swfItem));
urlStream.load(urlReq);
}
function urlStreamComplete(swfItem):Function
{
var downloadSwf:Function = function (event:Event):void {
var fileData:ByteArray = new ByteArray();
var stream = event.target;
stream.readBytes(fileData, 0, stream.bytesAvailable);
try {
var f : File = File.documentsDirectory.resolvePath(swfItem);
var fs : FileStream = new FileStream();
fs.addEventListener(Event.COMPLETE, fileCompleteHandler);
fs.openAsync(f, FileMode.WRITE);
fs.writeBytes(fileData);
}
catch (err : Error) {
trace(err.message);
}
}
return downloadSwf;
}
function fileCompleteHandler(e:Event):void {
e.target.close();
}
step2(); // this seems to run before UrlStreamComplete()
}
Problem with your for loop it will never work with Async model. so better need work to with recursive function.
downloadAllFiles method second arg that is function called when all download are completed.Then you can call step2() or whatever may be.
Make sure if any problem while download file like IOErrorEvent,etc...
downloadAllFiles(myArray,function():void
{
step2();
});
function downloadAllFiles(myArray:Array, complete:Function):void
{
if(myArray && myArray.length == 0)
{
if(complete)
complete.call();
return;
}
swfItem = myArray.shift();
var urlString:String = site_url + swfItem;
var urlReq:URLRequest = new URLRequest(urlString);
var urlStream:URLStream = new URLStream();
urlStream.addEventListener(Event.COMPLETE, function (event:Event):void
{
var fileData:ByteArray = new ByteArray();
var stream = event.target;
stream.readBytes(fileData, 0, stream.bytesAvailable);
try {
var f : File = File.documentsDirectory.resolvePath(swfItem);
var fs : FileStream = new FileStream();
fs.addEventListener(Event.CLOSE, function(closeEvent:Event):void
{
downloadAllFiles(myArray,complete);
return;
});
fs.openAsync(f, FileMode.WRITE);
fs.writeBytes(fileData);
}
catch (err : Error)
{
trace(err.message);
}
});
urlStream.load(urlReq);
}
Can't you just move step2(); at the end of fileCompleteHandler function?
Because at this point step2(); is called right after going through for(i = 0; i < myArray.length; i++)
loop (Which is way to early).
What you are missing is a way to check that all files from your list are loaded, 3vliguy is right and your step2(); should be in the complete handler but, not alone, you have to also test if ALL files are loaded. you can do it in various ways, e.g. use file counter and when it is 0 (all files loaded) you will execute step2() else you will ignore it and just decrease counter.
p.s. the Raja Jaganathan way will work as well, only it is queued loading whereas with the counter you can start loading of all files at the beginning.

Flash Error #1063 Argument count mismatch AS3

I'm trying to mix two tutorials in one game. Level 3 is previously used in a action script file but I transferred it into a normal AS3 timeline.
I get this error:
ArgumentError: Error #1063: Argument count mismatch on adventure_fla::MainTimeline/newObjects(). Expected 0, got 1.
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.utils::Timer/flash.utils:Timer::tick()
This is the code... sorry if its messy.
const speed:Number = 5.0;
var nextObject:Timer;
// array of objects
var objects:Array = new Array();
function initGame():void{
player.x=200;
player.y=400;
stage.addEventListener(MouseEvent.MOUSE_MOVE,movePlayer);
Mouse.hide();
player.gotoAndStop("arrow");
setGameTimer();
newObjects();
addEventListener(Event.ENTER_FRAME, moveObject);
}
function movePlayer(e:MouseEvent):void{
player.x=mouseX;
e.updateAfterEvent();}
function setGameTimer():void {
trace("GAME TIMER STARTED");
var gameTimer:Timer = new Timer(40000, 1);
gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, endGame);
gameTimer.start()
}
function endGame(e:Event):void {
trace("Game Over");
// remove all objects
for (var i:int=objects.length-1; i>=0; i--) {
removeChild(objects[i]);
objects.splice(i, 1);
} }
function setNextObject():void {
nextObject = new Timer(1000, 1);
nextObject.addEventListener(TimerEvent.TIMER_COMPLETE, newObjects);
nextObject.start();
function newObjects():void{
//create next object
// array of good and bad objects
var badObjects:Array = ["Bad_1", "Bad_2"]
var goodObjects:Array = ["Good_1", "Good_2"]
// create random number
if (Math.random() < .5 ) {
//based of treat object length
var r:int = Math.floor(Math.random()*goodObjects.length);
// get the treat object by name and cast it as its own class in a temporary variable
var classRef:Class = getDefinitionByName(goodObjects[r]) as Class;
// now we can make a new version of the class
var newObjects:MovieClip = new classRef();
// dynamic var (because mc is an object) typestr it as good
newObjects.typestr = "good";
} else {
// for bad same as above
r = Math.floor(Math.random()*badObjects.length);
var classRef:Class = getDefinitionByName(badObjects[r]) as Class;
var newObjects:MovieClip = new classRef();
// typestr it bad
newObjects.typestr = "bad";
}
// random pos
newObjects.x = Math.random()* 500;
newObjects.scaleX = newObjects.scaleY = .4;
addChild(newObjects);
// push it to array
objects.push(newObjects);
// create another one
setNextObject();
}
function moveObject(e:Event):void {
// cycle thru objects using a for loop
for (var i:int=objects.length-1; i>=0; i--) {
//move objects down based on speed
objects[i].y += speed;
objects[i].rotation += speed;
// if objects leaves the stage
if (objects[i].y > 400) {
removeChild(objects[i]);
objects.splice(i, 1);
}
}
}
newObjects does not take any arguments, but it's used as an event listener (which requires it to take the event object).
It should probably look something like function newObjects(event:TimerEvent):void.
A function used as event listener should accept one parameter of type Event, depending on what class of events it listens to. You are listening to an event of a TimerEvent class, so yes, declare parameter as TimerEvent. To add a function that does not need parameters passed to it as an event listener, use default value construction like this:
function newObjects(event:TimerEvent=null):void {...}
The "=null" addition will allow you to pass no parameters to your function, and the declared parameter will allow you to not get exceptions when it will be called as an event handler.

stoping a yoyo() Tween within a function

I am wanting to stop this yoyo movement when a sound stops.
This is not all the code but the important parts:
I DECLARED THE VAR OUTSIDE OF THE FUNCTION:
var BB:Tween;
........
function BounceBeau()
{
var BB:Tween = new Tween(Beau,"y",Strong.easeOut,stage.stageHeight - BeauHeight,33,5,false);
BB.addEventListener(TweenEvent.MOTION_FINISH, PlayBB);
function PlayBB(e:TweenEvent):void
{
BB.yoyo();
}
}
THE BOUNCE STARTS WITH SOUND AND STOPS WHEN OVER.
function PlaySound()
{
var ThemeSong:SoundChannel;
var s:Sound = new Sound(new URLRequest("MySound.mp3"));
ThemeSong = s.play();
...
BounceBeau();
...
ThemeSong.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
function onPlaybackComplete(event:Event):void
{
BounceBeauStop();
}
}
...
THIS CODE WAS IN BUT I FORGOT TO POST IT
function BounceBeauStop()
{
BB.stop();
}
THE ERROR I GET:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
Any Thoughts. :)
In your BounceBeau(), change var BB:Tween to just BB. You are inadvertently shadowing the declaration of BB by redeclaring it locally.
function BounceBeau()
{
BB = new Tween( ...
...
I believe you get that error here:
var ThemeSong:SoundChannel;
var s:Sound = new Sound(new URLRequest("MySound.mp3"));
ThemeSong = s.play();
Because you are not instantiating a new SoundChannel variable. Then, when you try to play the sound, and pass it to the channel, the latter one is not defined. I think you should try updating your code this way:
var themeSong:SoundChannel = new SoundChannel();
var s:Sound = new Sound(new URLRequest("MySound.mp3"));
themeSong = s.play();
Let us know if it works out. Have a great day.

How to use an array in actionscript?

var fruit:Array = new Array();
var frName:String;
var i:Number;
save_btn.addEventListener(MouseEvent.CLICK, storeName);
function storeName(Event:MouseEvent)
{
frName = name_txt.text;
fruit[i] = frName;
i++;
}
detail_btn.addEventListener(MouseEvent.CLICK, dispName);
function dispName(Event:MouseEvent)
{
for(i=0; i<=1; i++)
{
trace(fruit[i]);
}
}
The script has two buttons: one for saving the text in a fruit array and the other for displaying the text.
However, when I click the display button, the script shows undefined as output in actionscript. Please help.
When you defined your "i" variable you never set a value... e.g. it is "undefined". Just set it to zero.
var i:Number = 0;
declaring i as a global variable is making things difficult. Perhaps try rewritting like so:
var fruit:Array = new Array();
save_btn.addEventListener(MouseEvent.CLICK, storeName);
function storeName(Event:MouseEvent){
fruit.push(name_txt.text);
}
detail_btn.addEventListener(MouseEvent.CLICK, dispName);
function dispName(Event:MouseEvent){
for(var f:String in fruit){
trace(f);
}
}