Search code examples
actionscript-3functiondrag-and-dropaddeventlisteneraddchild

Error #1034 with Childs


EDIT: Wow, I didn't realize I was doing so many things so terribly wrong. This is the first code I’ve ever written by myself, without using things the school supplied. Guess I tried to bite off more than I could chew then after so few lessons.

I got most of this after googling for answers and then copying the parts of the code I thought (emphasis on ‘thought’) I needed.

Is there still a way to ‘save’ the code? Or is it best to just scrap it and start anew? And either way, what is the right way to do it then?

Also, I would ask my teacher if I could. But we don’t have any classes with him anymore and thus the man isn’t available anymore (or at least not responding to my e-mails.) I’m doing this on my own for another school assignment. So that’s why I turned to the internet.

Thanks for explaining all you did though. I appreciate it that you took the time to do so :)

Now, on to answer some of your questions, and to ask new ones:

Only the first symbol is called symbol 1, the others all have ‘real’ names. I forgot to change that when I started the project and kept it that way because I know exactly what it is, because it’s the only one called that way.

.. you know what kind of name comes out of that if the counter equals 5? "HalfCircle15". Yes, I realize that. And now that I see it like that, agree that it’s not a very neat way to write it down. Didn’t think it through enough when naming my HalfCirlce1-4.

What do you think it does? All right, let me try to explain it more clearly: When you’ve dragged and dropped the copy, you can no longer move it/select it. I want the user to be able to select it, so he can drag and drop it again for as many times as he wants. So, I think this means I have to add eventListeners to all the copies I make? Which is what I was trying to do here. Also, thanks for the error explanation. So, is this more like it?:

function makeListeners(copy:DisplayObject):void
{
    var i = this.numChildren;
    i.addEventListener(MouseEvent.CLICK, moveCopy);
}

I also moved the makeListeners call to the place where I make the copies. So it should only run once, when you make the copy, right?

Why are you using index 3 as 'newest child' index? That does not really make sense. I googled how to do this, and I believe it told me that the ‘index’ was the ‘layer’ (for lack of better word) you wanted to add the child to? I added it to 3, so that they are above some of my other images and under some of the other. It appeared to be working like that, though now I’m starting to question this too.

Here’s what I have now (deleted the other figures, so that it’s easier to look at the code). This gives me a new error TypeError: Error #1006: value is geen functie. at rondje1/makeListeners() at rondje1/dragRondje(): so I realize it’s not right. But is this at least more in the right direction than before?

import flash.display.*;
import flash.events.MouseEvent;
import flash.ui.Mouse;

var counter=1;
var copy;

//Copy dan drag and drop Rondje
buttonRondje.addEventListener(MouseEvent.CLICK, dragRondje);
function dragRondje(event:MouseEvent):void
{
    this["rondje"+ (counter)]=new block;
    this["rondje"+(counter)].x=mouseX-45;
    this["rondje"+ (counter)].y=mouseY-45;
    copy = addChildAt(this["rondje"+(counter)], 3);
    counter++;
    copy.startDrag();       
    makeListeners(copy);
}

//DROP
stage.addEventListener(MouseEvent.MOUSE_UP, dropEverything);
function dropEverything(event:MouseEvent):void
{
    stopDrag();
}

//Remove latest child
buttonRemoveChild.addEventListener(MouseEvent.CLICK, removeNewestChild);
function removeNewestChild(event:MouseEvent):void
{
    var i = 0;
    i = this.numChildren;
    if (i > 10 )
    {
        this.removeChildAt(3);
    }
}

function makeListeners(copy:DisplayObject):void
{
    var i = this.numChildren;
    i.addEventListener(MouseEvent.CLICK, moveCopy);
}

function moveCopy(event:MouseEvent):void
{
    trace('move copy!');
}

ORINIAL POST I'm making a little 'drag and drop' thing for a school project, but I've encountered a problem.

Right now I have it set up that when you click on a button, you start dragging a copy of a symbol from the library. When you click somewhere in the app, you drop it again. What I'm having trouble with, is the code that allows the user to pick this copy up to drag it again.

It gives me this error:

TypeError: Error # 1034: Type Coercion failed: can not convert block @2a308041 to flash.events.Event. at rondje1/dropEverything ()

Here's the code where I make the copy:

//Copy dan drag and drop Rondje
buttonRondje.addEventListener(MouseEvent.CLICK, dragRondje);
function dragRondje(event:MouseEvent):void
{
    this["rondje"+ (counter)]=new block;
    this["rondje"+(counter)].x=mouseX-45;
    this["rondje"+ (counter)].y=mouseY-45;
    copy = addChildAt(this["rondje"+(counter)], 3);
    counter++;
    copy.startDrag();       
}

Code where to drop it, and to add the eventlisteners to the copy:

//DROP
stage.addEventListener(MouseEvent.MOUSE_UP, dropEverything);
function dropEverything(event:MouseEvent):void
{
    stopDrag();
    makeListeners(copy);
}

Code to add the listeners:

function makeListeners(e:Event):void
{
    var i = 0;
    i = this.numChildren;
    for (i = this.numChildren;i<10;i++)
    {
        this.addEventListener(MouseEvent.CLICK, moveCopy);
    }
}

function moveCopy(event:MouseEvent):void
{
    trace('move copy!');
}

The symbol is set up like so:

  • Name: Symbol 1
  • Type: Movie Clip
  • Export for ActionScript -> Checked
  • Export in frame 1 -> Checked
  • Class: block
  • Base Class: flash.display.MovieClip

I really don't understand why I'm getting an error here :S Hopefully someone here can help me out. I'd be forever gratefull. Thanks in advance, Xx

ps: Here's the entire code:

import flash.display.*;
import flash.events.MouseEvent;
import flash.ui.Mouse;

var counter=1;
var copy;

//Copy dan drag and drop Rondje
buttonRondje.addEventListener(MouseEvent.CLICK, dragRondje);
function dragRondje(event:MouseEvent):void
{
    this["rondje"+ (counter)]=new block;
    this["rondje"+(counter)].x=mouseX-45;
    this["rondje"+ (counter)].y=mouseY-45;
    copy = addChildAt(this["rondje"+(counter)], 3);
    counter++;
    copy.startDrag();       
}

//Copy dan drag and drop HalfCircle1
buttonHalfCircle1.addEventListener(MouseEvent.CLICK, dragHalfCircle1);
function dragHalfCircle1(event:MouseEvent):void
{
    this["HalfCircle1"+(counter)]=new HalfCircle1;
    this["HalfCircle1"+(counter)].x=mouseX - 45;
    this["HalfCircle1"+(counter)].y=mouseY - 55;
    copy = addChildAt(this["HalfCircle1"+(counter)], 3);
    counter++;
    copy.startDrag();   
}

//Copy dan drag and drop HalfCircle2
buttonHalfCircle2.addEventListener(MouseEvent.CLICK, dragHalfCircle2);
function dragHalfCircle2(event:MouseEvent):void
{
    this["HalfCircle2"+(counter)]=new HalfCircle2;
    this["HalfCircle2"+(counter)].x=mouseX - 45;
    this["HalfCircle2"+(counter)].y=mouseY - 55;
    copy = addChildAt(this["HalfCircle2"+(counter)], 3);
    counter++;
    copy.startDrag();   
}

//Copy dan drag and drop HalfCircle3
buttonHalfCircle3.addEventListener(MouseEvent.CLICK, dragHalfCircle3);
function dragHalfCircle3(event:MouseEvent):void
{
    this["HalfCircle3"+(counter)]=new HalfCircle3;
    this["HalfCircle3"+(counter)].x=mouseX - 45;
    this["HalfCircle3"+(counter)].y=mouseY - 5;
    copy = addChildAt(this["HalfCircle3"+(counter)], 3);
    counter++;
    copy.startDrag();   
}

//Copy dan drag and drop HalfCircle4
buttonHalfCircle4.addEventListener(MouseEvent.CLICK, dragHalfCircle4);
function dragHalfCircle4(event:MouseEvent):void
{
    this["HalfCircle4"+(counter)]=new HalfCircle4;
    this["HalfCircle4"+(counter)].x=mouseX - 45;
    this["HalfCircle4"+(counter)].y=mouseY - 5;
    copy = addChildAt(this["HalfCircle4"+(counter)], 3);
    counter++;
    copy.startDrag();   
}

//Copy dan drag and drop Streep
buttonStreep.addEventListener(MouseEvent.CLICK, dragStreep);
function dragStreep(event:MouseEvent):void
{
    this["streep"+(counter)]=new Streep;
    this["streep"+(counter)].x=mouseX - 2;
    this["streep"+(counter)].y=mouseY - 5;
    copy = addChildAt(this["streep"+(counter)], 3);
    counter++;
    copy.startDrag();   
}

//DROP
stage.addEventListener(MouseEvent.MOUSE_UP, dropEverything);
function dropEverything(event:MouseEvent):void
{
    stopDrag();
    makeListeners(copy);
}

//Remove latest child
buttonRemoveChild.addEventListener(MouseEvent.CLICK, removeNewestChild);
function removeNewestChild(event:MouseEvent):void
{
    var i = 0;
    i = this.numChildren;
    if (i > 10 )
    {
        this.removeChildAt(3);
    }
}

function makeListeners(e:Event):void
{
    var i = 0;
    i = this.numChildren;
    for (i = this.numChildren;i<10;i++)
    {
        this.addEventListener(MouseEvent.CLICK, moveCopy);
    }
}

function moveCopy(event:MouseEvent):void
{
    trace('move copy!');
}

Solution

  • Your code is could be improved. If the school learned you to code and name stuff like this, you should be pissed. Symbols named 'Symbol 1' is not done, just like coding with Dutch names. I would recommend to make the code cleaner.

     this["HalfCircle1"+(counter)]
    

    .. you know what kind of name comes out of that if the counter equals 5? "HalfCircle15".

    Take a closer look at this function:

    function makeListeners(e:Event):void
    {
        var i = 0;
        i = this.numChildren;
        for (i = this.numChildren;i<10;i++)
        {
            this.addEventListener(MouseEvent.CLICK, moveCopy);
        }
    }
    

    What do you think it does? First, you set i to 0. Then you set it to the number of children in the current movie clip. This could be any number. So first setting it to 0 is pointless. But why in the world you want to loop from 3 to 10 and don't use the index i? You are just doing the same thing multiple times. In case of listeners, that's bad practise. You add the same listener to the same object multiple times (?!) 1 listener of the same type should be enough, otherwise it's overkill and can give unwanted effects.

    for me it's unclear what you are trying to do, but I guess you mean to add listeners to specific objects, since you are using numChildren.

    Resolving the error

    makeListeners(copy);
    

    the function makeListeners expects an Event as parameter, you are sending copy, which is a DisplayObject. This results in an error. You probably should change e:Event to copy:DisplayObject, which will hide the error.

    In your code it looks like you keep adding listeners on every drag/click, but none is ever deleted. That means if you click 10 times, moveCopy could be called a 100 times(!) This will increment while clicking. You should add the listeners once using some kind of call-once init-function.

    // add child at certain index
    copy = addChildAt(this["HalfCircle4"+(counter)], 3);
    
    // and..
    this.removeChildAt(3);
    

    I wonder why are you using index 3 as 'newest child' index?

    Sorry, maybe this comment isn't very helpful and isn't an answer to the question, but your code could be improved at several points. If it already works its because of black magic, but it's full of leaks and not-so-clean code.

    You should go to your teacher and tell him you need help. You're at school.

    UPDATE:

    I think this would be enough to create an copy-and-drag-that-clip app:

    import flash.display.*;
    import flash.events.MouseEvent;
    
    var _lastClip:MovieClip;
    
    // add a listener to all buttons. 
    buttonRondje.addEventListener(MouseEvent.CLICK, handleClick);
    buttonHalfCircle1.addEventListener(MouseEvent.CLICK, handleClick);
    buttonHalfCircle2.addEventListener(MouseEvent.CLICK, handleClick);
    buttonHalfCircle3.addEventListener(MouseEvent.CLICK, handleClick);
    buttonHalfCircle4.addEventListener(MouseEvent.CLICK, handleClick);
    buttonStreep.addEventListener(MouseEvent.CLICK, handleClick);
    
    function handleClick(event:Event):void
    {
         var clip:MovieClip;
                 trace("Clicked on: " + clip);
                 // based on which clip is clicked, we deside which object should be created.
         switch(event.currentTarget)
         {
             case buttonRondje:
             {
                 clip = new Circle();
                 break;
             }
             case buttonHalfCircle1:
             {
                 clip = new HalfCircle1();
                 break;
             }
             case buttonHalfCircle2:
             {
                 clip = new HalfCircle2();
                 break;
             }
             case buttonHalfCircle3:
             {
                 clip = new HalfCircle3();
                 break;
             }
             case buttonHalfCircle4:
             {
                 clip = new HalfCircle4();
                 break;
             }
             case buttonStreep:
             {
                 clip = new Streep();
                 break;
             }
        }
    
        // Move to mouse. It would be better to move the center points inside the clips so we don't need custom offsets here
        clip.x = mouseX;
        clip.y = mouseY;
        clip.startDrag();
    
        this.addChildAt(clip, 3);
    
        // remember the latest added clip
        this._lastClip = clip;
    }
    
    stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
    
    function handleMouseUp(event:MouseEvent):void
    {
         // if you where dragging, stop it
         if(this._lastClip)
         {
             this._lastClip.stopDrag();
         }
    }