Create a Drag and Drop Game in ActionScript 3

Create a Drag and Drop Puzzle in ActionScript 3.0

Drag-and-drop is the action of clicking on a virtual object and dragging it to a different location or onto another virtual object. In general, it can be used to invoke many kinds of actions, or create various types of associations between two objects.

In this tutorial we will create a Drag and Drop Matching game using ActionScript 3.

Step 1: Brief Overview

Using ActionScript 3, we will make draggable MovieClips that will be dropped in the MovieClip targets, we’ll check if the target its correct by using the hitTestObject method.

Step 2: Starting

Open Flash and create a new Flash File (ActionScript 3).

Set the stage size to 450×300 and add a black background (#1B1B1B).

””

Step 3: Draggable Clips

We’ll need some MovieClips to drag, I’ve used some of the Envato Marketplace logos.

Convert them to MovieClips and set their instance names:

Step 4: Drop Target

A MovieClip will be used as a drop target for each draggable clip, a simple rectangle will do the job.

Convert the rectangle to MovieClip and duplicate it (Cmd + D) to match the number of draggable objects.

The instance names will be the name of the draggable clip, plus Target, leaving us with denTarget, oceanTarget, etc.

Step 5: Guides

Let’s add some guides to help the user figure out what to do.

A title that will tell the user what to do with the elements in the screen.

An icon to tell the user how to do it.

Keywords to tell the user where to match the objects.

Step 6: ActionScript Time

Create a new ActionScript Document and save it as "Main.as".

Step 7: Required Classes

This time we’ll need just a few classes.

package
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;

Step 8: Extending the Class

We’re going to use Sprite specific methods and properties so we extend using the Sprite Class.

public class Main extends Sprite
{

Step 9: Variables

These are the variables we will use, explained in the comments.

var xPos:int; //Stores the initial x position
var yPos:int; //Stores the initial y position

Step 10: Main Function

This function is executed when the class is loaded.

public function Main():void
{
	addListeners(den, ocean, jungle, river, forest); //A function to add the listeners to the clips in the parameters
}

Step 11: Position Function

A function to get the position of the MovieClips, this will help us return the MC to its original position when the drop target its incorrect or no drop target was hit.

private function getPosition(target:Object):void
{
	xPos = target.x;
	yPos = target.y;
}

Step 12: Start Drag

This function enables the dragging to the clip with the listener.

private function dragObject(e:MouseEvent):void
{
	getPosition(e.target);

	e.target.startDrag(true);
}

Step 13: Stop Drag

The next function stops the dragging when the mouse button is released, it also checks if the object is in the correct drop target.

private function stopDragObject(e:MouseEvent):void
{
	if (e.target.hitTestObject(getChildByName(e.target.name + "Target"))) //Checks the correct drop target
	{
		e.target.x = getChildByName(e.target.name + "Target").x; //If its correct, place the clip in the same position as the target
		e.target.y = getChildByName(e.target.name + "Target").y;
	}
	else
	{
		e.target.x = xPos; //If not, return the clip to its original position
		e.target.y = yPos;
	}

	e.target.stopDrag(); //Stop drag
}       

Step 14: Listeners

Adds the listeners to the clips in the parameters using the …rest argument.

private function addListeners(... objects):void
{
	for (var i:int = 0; i < objects.length; i++)
	{
		objects[i].addEventListener(MouseEvent.MOUSE_DOWN, dragObject);
		objects[i].addEventListener(MouseEvent.MOUSE_UP, stopDragObject);
	}
}

Step 15: Document Class

Go back to the .Fla file and in the Properties Panel add "Main" in the Class field to make this the Document Class.

Conclusion

Now you know how to easily make a drag target, this can be very useful for games and applications. Make your own drag app and take this concept further!

Thanks for reading!

Add Comment

Discussion 47 Comments

  1. Ciobanasu Alexandru Sergiu says:

    verry nice. And nicely explained. Good work. :D

  2. Bloody Mary says:

    hehe try to drag the items from right to left and see what happens:-)

  3. R762mm says:

    Great tut, but i would add ‘buttonMode = true’ to the logo’s :p

  4. jamie says:

    Thanks for the tut, very easy to understand. I have an issue tho, I followed the code and have checked it a couple of time and I am missing 2 right braces at the end of the code. Also When i publish I can drag the icons but they go behind the targets and won’t stop dragging on mouse up.

    Any ideas what may be causing this?

    • Ricardo says:

      The same thing is happening to me, some of my objects can’t be hitTested, the mouse simply won’t let go of the draggable items. I’ve checked and re-checked everything, all is well with the code, since it only happens with half of the items. Have you found what’s causing your problem?

      • Adam says:

        If you’re still having issues, try moving the anchor point of the object to the centre of the object, instead of the corner. When I was having issues it was because when I clicked to drag, the object would jump away from the cursor. When it does this, the cursor is no longer holding the “hit area” and therefore can never stop dragging.

    • Jack says:

      Simply put all icons (den, ocean, forest,…) IN FRONT OF the target rectangles (denTarget, oceanTarget, forestTarget,…) and your app should work.

      Simply select all icons movie clips (Shift+click), then Control+click (Mac) or Right click(PC), Arrange > Bring to front.
      Now all of your drag/drop icons will show up on top of the rectangles on the right and the release will work just fine as well.

      Good luck!

      Keep up the good work, Carlos. Cheers!!!

  5. Aranea says:

    Very bad tutorial dude! You should stop writing tuts if you don’t know how to do it properly. Your code must work on first place. Writing tuts is more than writing nice explanation and comments.

  6. Karl Macklin says:

    This is the result I get:
    http://img514.imageshack.us/img514/526/ss20100111214215.jpg

    Not sure I get the point of this is not focusing on the interactive experience.

  7. Raoul says:

    What happen if i like Champagne when i win ? (traduction : how could i make something happen when i put all the parts on the right place ? )

    Tks from france,
    R.

    Ps : Aranea, Stop coffee right NOW !

  8. samBrown says:

    code works fine for me; nice work – tons of possible implementations and this is a nice base to build on..

  9. kick says:

    you always make your code looks complicated so you can make everyone think you did something good. I can’t believe they’re paying more than 5 dollars for this tutorial

    • Ian Yates says:
      Staff

      Carlos consistently demonstrates all manner of techniques in ActionScript, along with a clean way of working.

      Whilst you may not be able to take this as an out of the box product, you can certainly use the skills discussed. In this case, why not take the concepts of dragging, dropping and targeting, and build on them?

      If you see a problem, by all means point it out. Perhaps even offer up a suggestion.

  10. Humphrey Ngoiya says:

    great but update the link to your portfolio

  11. Radu says:

    e.target.startDrag(true);
    Looks bad with thing

    Although, a very nice tutorial as always.

  12. Ricardo says:

    This is very useful and pretty well made, I’m able to use it pretty much out of the box and I thank for that. But since this is a tutorial, I would have liked a more detailed explanation of what’s going on here.

    Yes, it’s easy to understand as a whole, but some of the code doesn’t make any sense to me, and I’d like to know why.

    For example,

    “private function addListeners(… objects):void”

    I have no idea what this means, why the three dots and objects? I can figure out that this is a way to add the drag properties to all the objects. I know it works, but since this is a tutorial I would like to know more, instead of simply looking at a source code. Otherwise I won’t know that these 3 dots mean, it’s a useful tutorial but by your explanations I can’t learn much.

    But I thank you anyway, I like the way you coded this to be so easily reusable.

  13. Simple but useful, congratulations Carlos.

  14. Jack Milano says:

    150$ for this tutorial huh . I’ll prepare it for 10 $ . That’s what it worths .

  15. srinu says:

    this is the don’t open work in cs3 but this program is very good

  16. Dom says:

    Thanks a lot for this!

  17. Adam says:

    This is awesome, exactly what I was looking for!

    I am a complete n00b and only just learning AS3 for myself and this really helped. Does anyone know how to extend this script so a movie clip plays once all the targets have been filled though? I’m trying to overlay a semi transparent black background, and give some congratulatory text. My knowledge of the language isn’t large enough for this yet!

    Any help would be appreciated! Thanks!

  18. Thank you so much for this tutorial. I always wanted to make a puzzle like this one. Thanks.

  19. Carlos says:

    Hola Carlos, me parece un buen ejemplo, el detalle es que a mi me sale un error que se indica desde la linea 1 hasta la 11

    Main.as Linea 1 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 2 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 3 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 4 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 5 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 5 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 6 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 9 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 9 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.
    Main.as Linea 10 1046: No se encontró el tipo o no es una constante en tiempo de compilación: MovieClip.

    Bueno spero me puedas ayudar.

  20. Anonymous says:

    This does work, but you have to change the registration point to the center of the object, and it works.. although it should be mentioned in the tutorial.

  21. Anze says:

    Hi!
    My question has nothing to do with that totorial (which is owesome), but anyway I would be very pleased if you could help me with that one…so…

    I’ve got a small problem..
    I have to write a code – I want animation to go to second frame, when last piece of puzzle is dropped down.

    In AS there is function resetShapes, I dont need that, insted of that I want animation to go and play next frame. How can I do that?

    ActionScript Code:
    function resetShapes() {
    if ((item1.val == 1)&& (item2.val == 1) && (item3.val == 1)) {

    Full code: http://dl.dropbox.com/u/9143275/gotoAndPlay%20if.rtf

  22. Hi Carlos Yanez,

    Nice and easy to understand tutorial, I have also planned to upload this kind of interactivity on my institute website’s portfolio page. Plz suggest me some games for this page http://www.admecindia.co.in/flash-games-training-institutes-delhi.html .

    I want to say for those who r criticizing, plz do not write critical comments for such type of nice post. If any of u is criticizing than also post explanation with improved Code also.

    Thanks
    Ravi Bhadauria
    admec multimedia institute

  23. Manx says:

    How would you change the code to allow an original drag object to be left behind when dragged?

    For example, if I drag ActiveDen to its correct target, the ActiveDen logo would be left in its original position so another ActiveDen logo could be dragged to a target.

  24. Rajesh says:

    Very Nice… Its very helpful to me…

  25. icnovaro says:

    I’m create this code.

    package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    public class Main extends Sprite {
    var xPos:int;//Stores the initial x position
    var yPos:int;//Stores the initial y position
    public function Main():void {
    addListeners(rigoso);
    }

    private function getPosition(target:Object):void {
    var object=target;
    xPos=object.x;
    yPos=object.y;
    }
    private function dragObject(e:MouseEvent):void {
    var object=e.target;
    getPosition(object);
    // we should limit dragging to the area inside the canvas
    object.startDrag();
    }

    private function stopDragObject(e:MouseEvent):void {
    var obj=e.target;
    var target=obj.dropTarget;
    if (target!=null&&target.parent==getChildByName(obj.name+”Target”)) {
    obj.x=rigosoTarget.x;
    obj.y=rigosoTarget.y;
    trace(“Made it !!”);
    } else {
    obj.x=xPos;
    obj.y=yPos;
    trace(“Missed :(“);
    }
    obj.stopDrag();
    }

    private function addListeners(… objects):void {
    for (var i:int = 0; i < objects.length; i++) {
    objects[i].buttonMode=true;
    objects[i].useHandCursor=true;
    objects[i].addEventListener(MouseEvent.MOUSE_DOWN, dragObject);
    objects[i].addEventListener(MouseEvent.MOUSE_UP, stopDragObject);
    }
    }
    }
    }

    • dimdim says:

      help me how to create code, but the as3 is in every frame not in main.as like that..thx
      this is my code
      import flash.display.Sprite;
      import flash.events.MouseEvent;

      var xPos:int;//Stores the initial x position
      var yPos:int;//Stores the initial y position

      //mybe the problem at this function
      function objek ():void{
      addListeners(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);}

      function getPosition(target:Object):void {
      var object=target;
      xPos=object.x;
      yPos=object.y;
      }

      function dragObject(e:MouseEvent):void {
      var object=e.target;
      getPosition(object);
      // we should limit dragging to the area inside the canvas
      object.startDrag();
      }

      function stopDragObject(e:MouseEvent):void {
      var obj=e.target;
      var target=obj.dropTarget;
      if (target!=null&&target.parent==getChildByName(obj.name+”Target”)) {
      e.target.x = getChildByName(e.target.name + “Target”).x;
      e.target.y = getChildByName(e.target.name + “Target”).y;
      trace(“Made it !!”);
      } else {
      obj.x=xPos;
      obj.y=yPos;
      trace(“Missed :(“);
      }
      obj.stopDrag();
      }

      function addListeners(…objects):void {
      for (var i:int = 0; i < objects.length; i++) {
      objects[i].buttonMode=true;
      objects[i].useHandCursor=true;
      objects[i].addEventListener(MouseEvent.MOUSE_DOWN, dragObject);
      objects[i].addEventListener(MouseEvent.MOUSE_UP, stopDragObject);
      }
      }

      I try use that code in every frame its work,, but any problem there.. anyone can help me??

  26. tim says:

    This tutorial rules! Thanks amazing
    Please keep up the good work

  27. Edgar Arcaya says:

    icnovaro envia el .swf

  28. Kamil says:

    Great game. How to reset positions when i want to play again?

  29. Ara says:

    yes thank you for the tut. it was really helpful. but i would also like a reset button, and when i put a puzzle piece in its place, i would like like for some information to pop up over to the side, that means i make mc piece that i placed on the target piece a button? or the target piece a button? sorry.. i’m new and excited.

  30. james says:

    Works for me after I made sure the icon was centered in the mc. I also added a hand curser to my code (and changed its name to Main2):
    package
    {
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    public class Main2 extends Sprite
    {
    var xPos:int;
    var yPos:int;

    public function Main2():void
    {
    addListeners(ethic, discrim, account);
    this.buttonMode = true;
    this.useHandCursor = true;
    }

    private function getPosition(target:Object):void
    {
    xPos = target.x;
    yPos = target.y;
    }

    private function dragObject(e:MouseEvent):void
    {
    getPosition(e.target);
    e.target.startDrag(true);

    }

    private function stopDragObject(e:MouseEvent):void
    {
    if (e.target.hitTestObject(getChildByName(e.target.name + “Target”)))
    {
    e.target.x = getChildByName(e.target.name + “Target”).x;
    e.target.y = getChildByName(e.target.name + “Target”).y;
    }
    else
    {
    e.target.x = xPos;
    e.target.y = yPos;
    }

    e.target.stopDrag();
    }

    private function addListeners(… objects):void
    {
    for (var i:int = 0; i < objects.length; i++)
    {
    objects[i].addEventListener(MouseEvent.MOUSE_DOWN, dragObject);
    objects[i].addEventListener(MouseEvent.MOUSE_UP, stopDragObject);
    }
    }
    }
    }

    I would love to know how to add a feedback image that sates its correct or incorrrect :)

  31. Bertus says:

    Is this exercise at one layer?

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.