You are Here:Home>>Old Posts>>AS3 example Drag and Drop

AS3 example Drag and Drop

Carlos Pinho
By | 2008-03-03T17:46:37+00:00 Mar 3, 2008|Old Posts|

Introduction

You will learn how to implement simple drag and drop applications.

ActionScript Program

Note: For now, the drag and drop works when you click anywhere on the tile but the letter itself. We keep things simple and won’t provide a workaround.

package {

  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.text.TextField;  

  public class AnagramDragDrop extends Sprite {
    private var dragTarget:Sprite;

    public function AnagramDragDrop() {
      var board:Sprite = new Sprite();
      var letters:Array = new Array("d","i","r","t","y","r","o","o","m")
      var l:String;
      var xPos:uint = 50
      var yPos:uint = 100
      for each (l in letters) {
        var tile:Sprite = new Sprite();
        tile = createLetterTile(l as String) // size, color yellow
        tile.x = xPos;
        tile.y = yPos;
        xPos += 50;
        board.addChild(tile);
        tile.addEventListener(MouseEvent.MOUSE_DOWN, dragStarter, false);
        tile.addEventListener(MouseEvent.MOUSE_UP, dragStopper);
      }
      addChild(board)

      var instructions:TextField = new TextField();
      instructions.text = "Re-order the letters to form another word."
      instructions.x = 20
      instructions.y = 20
      instructions.width = 300;
      addChild(instructions)

    }

    private function dragStarter(event:MouseEvent):void {
      if (event.target is Sprite) {
        dragTarget = event.target as Sprite;
        dragTarget.startDrag();
      }
    }

    private function dragStopper(event:MouseEvent):void {
      dragTarget.stopDrag();
    }

    private function createLetterTile(txt:String):Sprite {
      var s:Sprite = new Sprite();
      var letter:TextField = new TextField();
      var tileBackColor:uint = 0xDBD9A6;
      var tileShadowColor:uint = 0x676420;
      var tileBorderColor:uint = 0x000000;

      s.graphics.beginFill(tileShadowColor);
      s.graphics.drawRect(-2, 2, 40, 40);
      s.graphics.endFill();
      s.graphics.beginFill(tileBackColor);
      s.graphics.drawRect(0, 0, 40, 40);
      s.graphics.endFill();
      s.graphics.lineStyle(1, tileBorderColor, 100);
      s.graphics.drawRect(0, 0, 40, 40);

      letter.text = txt
      letter.selectable = false;
      letter.x = 14
      letter.y = 14
      letter.width = 14
      letter.height = 16
      s.addChild(letter)

      return s;
    }
  }
}

Walkthrough

package {

  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.text.TextField;  

  public class AnagramDragDrop extends Sprite {

Package declaration, import statements, class definition.

    private var dragTarget:Sprite;

Declaration of all variables that will be used in more than one functions. We store in a variable information about the sprite object that was the target of the drag. When the mouse gets up, we want the drag action to stop, whether the mouse is over that object or not.

    public function AnagramDragDrop() {
      var board:Sprite = new Sprite();
      var letters:Array = new Array("d","i","r","t","y","r","o","o","m")
      var l:String;
      var xPos:uint = 50
      var yPos:uint = 100
      for each (l in letters) {
        var tile:Sprite = new Sprite();
        tile = createLetterTile(l as String) // size, color yellow
        tile.x = xPos;
        tile.y = yPos;
        xPos += 50;
        board.addChild(tile);
        tile.addEventListener(MouseEvent.MOUSE_DOWN, dragStarter);
        tile.addEventListener(MouseEvent.MOUSE_UP, dragStopper);
      }
      addChild(board)

      var instructions:TextField = new TextField();
      instructions.text = "Re-order the letters to form another word."
      instructions.x = 20
      instructions.y = 20
      instructions.width = 300;
      addChild(instructions)

    }

Rather than draw a single object on the screen to be dragged and dropped, we spice things up a bit. We will draw a number of tiles letters.

It would be quite tedious to have something of the like:

 var tile1:Sprite = createLetterTile("d")
 tile1.x = 50
 tile1.y = 50
 addChild(tile1)

 var tile2:Sprite = createLetterTile("i")
 tile2.x = 50+30
 tile2.y = 50
 addChild(tile2)

 var tile3:Sprite = createLetterTile("r")
 tile3.x = 50+(30*2)
 tile3.y = 50
 addChild(tile3)

What if we were to decide to change to offset all times by 10 pixels? What if we wanted to change the anagram to appear on the screen. This would be a very slow, tedious process, and error prone process.

We opt for a more efficient of coding this. We put the letters in an array and we use Flash built in for each (value in array) to rapidly loop across the items with in this array.

We also define a point of origin (x=50, y=100), where the first tile will appear. Within the for each loop, we add 50 pixels to the x position, causing the tiles to appear one on the right of the other.

Because all tiles are to look the same except for the letter in the middle, we delegate the creation of each tile to a function. This way, we are free to change the look and feel of a tile later on.

For convenience reasons, we create a board object to store all sprites. This way, we can treat the tiles as component and position it on its own.

Finally, we add two mouseEvent listener, one to trigger a function whenever a mousedown event occurs, another one to trigger another function whenever a mouseup event occurs. They will be used to trigger start drag and stop drag actions, respectively.

    private function dragStarter(event:MouseEvent):void {
      dragTarget = event.target as Sprite;
      dragTarget.startDrag();
    }
    private function dragStopper(event:MouseEvent):void {
      dragTarget.stopDrag();
    }

whenever a mousedown event occurs anywhere on the interface, the event is forwarded to the function specified as parameter to the addListener function. In this program, it is the dragStarter function.

The function is called and the information about the event that toke place passed as a parameter to this function. We therefore create a parameter event, of type MouseEvent, to be able to access information about the event from within our function.

Different information become available, the target, the mouse location and others. These information vary slightly from mouseevent to mouseevent. Detailed information about event information can be obtained on the MouseEvent entry in the Actionscript Language Reference.

Here, we are only interested in the target property. This holds information on the on-screen object that was the target of the event. We store this information in a variable because we want a mouse up action to interrupt the dragging of the object on which a dragging action was initiated rather than the object currently under the mouse.

    private function createLetterTile(txt:String):Sprite {
      var s:Sprite = new Sprite();
      var letter:TextField = new TextField();
      var tileBackColor:uint = 0xDBD9A6;
      var tileShadowColor:uint = 0x676420;
      var tileBorderColor:uint = 0x000000;

      s.graphics.beginFill(tileShadowColor);
      s.graphics.drawRect(-2, 2, 40, 40);
      s.graphics.endFill();
      s.graphics.beginFill(tileBackColor);
      s.graphics.drawRect(0, 0, 40, 40);
      s.graphics.endFill();
      s.graphics.lineStyle(1, tileBorderColor, 100);
      s.graphics.drawRect(0, 0, 40, 40);

      letter.text = txt
      letter.selectable = false;
      letter.x = 14
      letter.y = 14
      letter.width = 14
      letter.height = 16
      s.addChild(letter)

      return s;
    }

Function to create a given tile object.

  }
}

closing the class definition and the package delcaration.

Variants

Fridge Magnets

You could design a basic fridge magnet application the same way. The magnets can be moved by clicking on the green tab that appears in front of them and dragging the magnet around the screen.

Here is the code:

package {

   import flash.display.Sprite;
   import flash.events.Event;
   import flash.events.MouseEvent
   import flash.text.TextField;
   import flash.text.TextFieldAutoSize;
   import flash.text.TextFormat;

   public class FridgeMagnets extends Sprite {
     private var dragTarget:Sprite;

     public function FridgeMagnets() {
       var board:Sprite = new Sprite();
       var words:Array = new Array("flash.","Sprite","display.","import")
       var w:String;
       var xPos:uint = 0
       var yPos:uint = 0
       for each (w in words) {
         var magnet:Sprite = createMagnet(w as String)
         magnet.y = yPos;
         magnet.x = xPos;
         xPos += magnet.width;

         board.addChild(magnet);
         magnet.addEventListener(MouseEvent.MOUSE_DOWN, dragStarter);
         magnet.addEventListener(MouseEvent.MOUSE_UP, dragStopper);
       }

       board.x = 20; board.y = 100;
       addChild(board)
     }

      private function dragStarter(event:MouseEvent):void {
        dragTarget = event.target as Sprite;
        dragTarget.startDrag();
      }
      private function dragStopper(event:MouseEvent):void {
        dragTarget.stopDrag();
      }

     private function createMagnet(txt:String):Sprite {
       var s:Sprite = new Sprite();
       var m:TextField = new TextField();
       var format:TextFormat = new TextFormat();
       m.selectable = false;
       m.autoSize = TextFieldAutoSize.LEFT;
       m.background = true;
       m.border = true;
       m.height=20;
       format.font = "Verdana";
       format.color = 0x000000;
       format.size = 14;
       m.defaultTextFormat = format;
       m.text = txt;

       s.graphics.beginFill(0x3E7D24)
       s.graphics.drawRect(-9,1,10,20)
       s.graphics.endFill()

       s.addChild(m)
       return s;
     }
   }
 }

Why not use this to set yourself some exercises to practice your ActionScript? You could mix words of a line like shown here.

Challenge

Drag lines and blocks of lines

Write a program that presents lines of text. The task is then to put the lines in the correct order. For extra difficulty, make it possible to have single lines of text as well as multilines.

When finished, why not use it to present programs like the ones above (if you don’t allow for multiline blocks, shorter programs may be more convenient) in a somewhat shuffled order. Set yourself or your friends the task to put the lines back in a correct order.

Dominos

Write a smini-game game of dominos. Information about the game and the rules can be found on this page about Dominos puzzle and logic game. To keep things simple have a board where only horizontal dominos are used.

About Authors

Daniel K. Schneider is senior lecturer and researcher at TECFA, a research and teaching unit in the faculty of psychology and education, University of Geneva. Holding a PhD in political science, he has been working in educational technology since 1988 and participated in various innovative pedagogical and technological projects. He has been a prime mover towards the introduction of creative pedagogical strategies and ICT technologies. His current R&D interests focus on modular, flexible and open Internet architectures supporting rich and effective educational designs. Within TECFA’s “blended” master program in educational technology, he teaches educational information & communication systems, virtual environments and research methodology.
Marielle Lange trained as a cognitive psychologist (M.Phil Cambridge, UK; PhD Brussels, Belgium), Marielle Lange always had a passion for e-learning. Thinking that a PhD was not challenging enough, she set to design a Web-Museum for Perception and Cognition during her PhD years. She is originally from Brussels (Belgium, french speaking) but has had the chance to spend a lot of time in English speaking countries (UK, Australia, Scotland, and soon New Zealand). After 10 years as an academic, she turned freelance e-learning developer two years ago. Since then, she has been involved in various projects that have in common the design of software that let students and teachers create quality interactive content.

She is also the administrator of the Exercist project, on eduforge, which is about open source activities in Flex.

In fact, the idea is not only to propose interactive activities but a framework to create, manage, and re-use a large range of interactive activities, as explained on the Widged wiki. But to get there requires good mastery of Flex/Actionscript 3 and she only started learning these in August/September 2007.

True wiki style, she decided to contribute to this wiki without having any connection with the edutech team other than having been inspired by their work and having much liking for their philosophy and initiatives.

She maintains two domains, widged.com and learning-activities.org. She also offers free hosting to iberry, a porthole to Open Courseware Directory and Higher Education Resources maintained by Dr Boss (Gordon Lockart).

About the Author:

Carlos Pinho
A father, a husband and a geek... Carlos was the founder of projects like The Tech Labs and Flash Enabled Blog. He is the founder of TekTuts He is passionate about technologies. Their main skills are in analytics, transport & logistics, business administration. He also writes about programming resources, trends, strategy and web development.