Flash Error #1063 Argument count mismatch AS3 - actionscript-3

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.

Related

Remove the clicked objects

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

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller

I am trying to get rid of an object but it's throwing an error not exactly sure what is the problem.
The error I am getting:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at SchoolBook_Final_fla::MainTimeline/garbage_cl_2()[SchoolBook_Final_fla.MainTimeline::frame2:98]
at Function/SchoolBook_Final_fla:MainTimeline/choice_play_ev/SchoolBook_Final_fla:play_target()[SchoolBook_Final_fla.MainTimeline::frame2:81]
My code:
import flash.display.Sprite;
import flash.ui.Mouse;
import flash.events.Event;
var week_pick:Weekday_Choice = new Weekday_Choice ();
var weekdayArray: Array = new Array ();
var monday:Mon_D_but = new Mon_D_but ();
var tuesday:Tues_D_but = new Tues_D_but ();
var wednesday:Wed_D_but = new Wed_D_but ();
var thursday:Thurs_D_but = new Thurs_D_but ();
var friday:Fri_D_but = new Fri_D_but ();
var choice_play: Array = new Array ();
choice_play.push(monday, tuesday, wednesday, thursday, friday);
//Adding Week Pick
addChild(week_pick);
//Placing all the Buttons
choice_play[0].x = 73.1;
choice_play[0].y = 316.75;
choice_play[1].x = 251.9;
choice_play[1].y = 278.35;
choice_play[2].x = 399.95;
choice_play[2].y = 375.85;
choice_play[3].x = 345.2;
choice_play[3].y = 602.4;
choice_play[4].x = 80.15;
choice_play[4].y = 603.05;
for (var a = 0; a < choice_play.length; a++)
{
//Asking all the Buttons to stop
choice_play[a].alpha = 0;
choice_play[a].stop();
}
//Event for the week pick to start
week_pick.addEventListener(Event.ENTER_FRAME, moveon);
//Getting the function started
function moveon(event:Event)
{
if (week_pick.currentFrame == 103)
{
week_pick.stop();
for (a = 0; a < choice_play.length; a++)
{
addChild(choice_play [a]);
}
//adding an Event listener for clicking the buttons
this.addEventListener(MouseEvent.CLICK,choice_play_ev);
}
}
function choice_play_ev(play_event: MouseEvent)
{
trace ("Event gets added");
trace (play_event.target);
//Work if the target isn't the background clip
if (play_event.target != week_pick)
{
trace (play_event.target);
//Turn back the opacity for what ever was cliked on
play_event.target.alpha = 1;
//asking the choice to play it's animation
play_event.target.addEventListener(Event.ENTER_FRAME, play_target);
this.removeEventListener(MouseEvent.CLICK,choice_play_ev);
function play_target(play_event_cl:Event)
{
play_event_cl.target.play ();
if (play_event_cl.target.currentFrame == 15)
{
//remove the [;ace event listener once the animation is done
play_event.target.removeEventListener(Event.ENTER_FRAME, play_target);
garbage_cl_2 ();
}
}
}
}
function garbage_cl_2 ()
{
trace("it works");
for (a = 0; a < choice_play.length; a++)
{
//remove all the choices from the display list
removeChild(choice_play [a]);
}
//Remove all the choices from the array for better garbage cleaning
choice_play.splice(0, choice_play.length);
removeChild(week_pick);
week_pick.removeEventListener(Event.ENTER_FRAME, moveon);
trace("The choice_play is " + choice_play.length);
gotoAndStop(3);
}
Can somebody help me out with this please? Also tell me why is it throwing the error?
Your loop inside the garbage_cl_2 () function
for (a = 0; a < choice_play.length; a++)
{
//remove all the choices from the display list
removeChild(choice_play [a]);
}
and / or the call removeChild(week_pick); tries to remove a MovieClip that's not direct child of the current MovieClip object. The current clip is the one whose timeline contains the frame with the code of the garbage_cl_2 () function. The removeChild() method can only remove a direct child of a DisplayObjectContainer instance - if the current clip is not the direct parent of these clips, you need to specify the parent clip like so:
parentclip.removeChild ( ... );

Accessing event.target or event.currentTarget beyond the listener Function

Originally I had two functions, the first function being dataLoaded which had an eventListener in it that spawned a new function called itemClicked. But if I wanted to add a delayedFunction and have itemClicked as an intermittent stage between dataLoaded and delayedFunction, how can I access the event.target or event.currentTarget of the original listener when I come to reference it in my delayedFunction?
private function dataLoaded(event:Event):void {
//items properties call - add other calls to master properties later on
items = data.item;
// parsing of each ingredient
for (var i = 0; i < items.length(); i++) {
// instantiation of mcItem (the stage for each item)
_item = new Item();
// sets //over// layer to invisible / transparent
_item.item_btn_over.alpha = 0;
// creates the var itemTextField
_itemTextField = new TextField();
_itemTextField.text = items[i].toString();
// adds textfield to displaylist
_item.addChild(_itemTextField);
//adds items to container displaylist
_container.addChild(_item);
}
_item.parent.addEventListener( MouseEvent.CLICK, itemClicked );
}
function itemClicked(event:MouseEvent):void {
if (event.target is Item) {
var item:Item = Item(event.target);
TweenLite.to(item.btn_delete, 1,{rotation:180});
setTimeout(delayedFunction,5000);
item.parent.removeChild(item);
parseXML(data);
}
}
function delayedFunction():void {
var item:Item = Item(event.target);
item.parent.removeChild(item);
}
(I've mocked up the functions above, so I may be missing some closing parenthesis, but this doesn't matter in relation to my question)
This question has been on my mind for days and I can't think of a way of making the event.target of the parent _item accessible to functions other than the listening function.
You can pass arguments to your setTimeout call like this:
setTimeout(delayedFunction, 5000, event.currentTarget);
Then get the argument from the arguments array from your delayedFunction method:
function delayedFunction():void {
var item:Item = arguments[0] as Item;
item.parent.removeChild(item);
}
Have a look at the setTimeout docs if you need information.

actionscript 3: how to pass array by reference to function, and have that function update it?

ActionScript 3 passes an array by reference, by default. I must be making a rookie mistake. Here's a snapshot of my code:
private function testFunc():void {
var testArray:Array=new Array();
myFunction(testArray);
trace(testArray); // []; length=0
}
private function myFunction(tArray:Array):void {
tArray = myOtherFunction();
trace(tArray); // 0, 1, 2; length=3
}
private function myOtherFunction():Array {
var x:Array=new Array;
for (var i:int=0; i<3; i++)
x[i]=i;
return x;
}
I can see that tArray is correct, but testArray is always empty. Any idea how to make testArray equal tArray? Thanks in advance.
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000049.html
UPDATE:
For what it's worth, I found the following change (hack) to work:
private function myFunction(tArray:Array):void {
var Z:Array=new Array;
Z = myOtherFunction();
for (var i:int=0; i<Z.length; i++)
tArray[i]=Z[i];
}
Georgii's solution is better design though.
When you pass testArray as a parameter to myFunction, its reference is copied and assigned to local reference tArray, such that inside of myFunction tArray points to the same object as testArray, but is in fact a different reference. That is why when you change tArray reference, testArray itself does not change.
private function testFunc():void {
var testArray:Array=new Array();
// testArray is a local variable,
// its value is a reference to an Array object
myFunction(testArray);
trace(testArray); // []; length=0
}
private function myFunction(tArray:Array):void {
// tArray is a local variable, which value equals to testArray
tArray = myOtherFunction();
// now you changed it and tArray no longer points to the old array
// however testArray inside of testFunc stays the same
trace(tArray); // 0, 1, 2; length=3
}
What you probably want is:
private function testFunc():void {
var testArray:Array=new Array();
testArray = myFunction(testArray);
trace(testArray); // 0, 1, 2; length=3
}
private function myFunction(tArray:Array):Array {
// do what you want with tArray
tArray = myOtherFunction();
trace(tArray); // 0, 1, 2; length=3
// return new value of the tArray
return tArray;
}
private function myOtherFunction():Array {
var x:Array=new Array;
for (var i:int=0; i<3; i++)
x[i]=i;
return x;
}
Basically what's happening is that you've passed your Array to the function, which in turn creates a local reference to it (within the function).
This means that if you decide to go ahead and assign a newly created Array to the local variable (tArray in your case), it will be used instead, and the original will retain its original instance.
This is the same for any object, for example with a Sprite:
var sprite:Sprite = new Sprite();
// We set the original Sprite's x to 10.
sprite.x = 10;
function mutilate(subject:Sprite):void
{
// Notice here how we are making a new instance. This won't assign a new
// instance to the "sprite" property that we've passed here, but rather
// a new instance to the local variable "subject".
subject = new Sprite();
// And here we set the x of the new instance to 20.
subject.x = 20;
}
mutilate(sprite);
trace(sprite.x); // Outputs 10, though you may have expected 20.
Take the return of myOtherFunction() iterate through it and then call tArray.push() for each element. Currently all you are doing is changing a local reference to a newly created object.
You need to add elements to the original array which you lose the reference too on assignment.

as3 error loading "good" "bad" array

I am creating a "good" "bad" array to display on screen which i can later use simple if statements to do something upon if the player has collided with the "good" "bad" objects.
I cant get the objects to randomly generate on screen with the following code.
// Create and Set good/bad random Word objects
public function newObject(e:Event)
{
var goodObjects:Array = ["WordObject1"];
var badObjects:Array = ["WordObject2"];
if (Math.random() < .5)
{
var r:int = Math.floor(Math.random()*goodObjects.length);
var classRef:Class = getDefinitionByName(goodObjects[r]) as Class;
var newObject:MovieClip = new classRef();
newObject.typestr = "good";
} else
{
r = Math.floor(Math.random()*badObjects.length);
classRef = getDefinitionByName(badObjects[r]) as Class;
newObject = new classRef();
newObject.typestr = "bad";
}
newObject.x = Math.random();
newObject.y = Math.random();
addChild(newObject);
objects.push(newObject);
placeWords();
}
// create random Word objects
public function placeWords() {
objects = new Array();
for(var i:int=0;i<numWordObjects;i++) {
// loop forever
while (true) {
// random location
var x:Number = Math.floor(Math.random()*mapRect.width)+mapRect.x;
var y:Number = Math.floor(Math.random()*mapRect.height)+mapRect.y;
// check all blocks to see if it is over any
var isOnBlock:Boolean = false;
for(var j:int=0;j<blocks.length;j++) {
if (blocks[j].hitTestPoint(x+gamesprite.x,y+gamesprite.y)) {
isOnBlock = true;
break;
}
}
// not over any, so use location
if (!isOnBlock) {
newObject.x = x;
newObject.y = y;
newObject.gotoAndStop(Math.floor(Math.random()*1)+1);
gamesprite.addChild(newObject);
objects.splice(newObject);
break;
}
}
}
}
i get the following errors:
1119: Access of possibly undefined property x through a reference with static type Function.
1119: Access of possibly undefined property y through a reference with static type Function.
1067: Implicit coercion of a value of type Function to an unrelated type flash.display:DisplayObject.
Try renaming var x and var y to something else. Those are public properties in any class that extends as a display object (Sprite/MovieClip/Shape).