Author: Max Pellizzaro
Date: Dicembre 5th 2007
Update: July 12th 2009
version: 3.1.1

Simple interaction mode

Objective of the tutorial

This is the first of a series of tutorial that will deal with interactions. We have already worked with some interaction in the previous tutorial based on “arrow key” movement, or mouse camera movement. Now we want to start to understand how it is possible to interact with the 3D object usng the mouse, how many possibilities we have, and how we can best use the options.
The first type of interaction we are dealing with is based on a 3D object property called container. This property is a reference to the Sprite object that contains the 3D model, with which we can add event handlers to this Sprite object. You will see how easy it is to use this kind of interaction, but there are some limitations that we will discuss at the end of the tutorial.

How to

Set up

The AS class name must be Example017.as. Not much else is needed this time.

example017.rar

The new updated version can be found here:
example017_v3.1.1.zip

The AS Code

In this section we report the AS code as a reference, and it will be explained in the next paragraph.

package {
  import flash.display.Sprite;
  import flash.events.*;
  import flash.ui.*;
  import flash.text.*;
  import sandy.core.Scene3D;
  import sandy.core.data.*;
  import sandy.core.scenegraph.*;
  import sandy.materials.*;
  import sandy.materials.attributes.*;
  import sandy.primitive.*;

  public class Example017 extends Sprite {
    private var scene:Scene3D;
    private var camera:Camera3D;
    private var myCone:Cone;
    private var myHedra:Hedra;
    private var myText:TextField = new TextField();
    private var needRemove:Boolean = false;
    
    public function Example017() { 
      camera = new Camera3D( 300, 300 );
      camera.x = 100;
      camera.y = 100;
      camera.z = -300;
      camera.lookAt(0,0,0);
      
      myText.width = 200;
      myText.x = 20;
      myText.y = 20;
      
      var root:Group = createScene();
      
      scene = new Scene3D( "scene", this, camera, root );
      
      addEventListener( Event.ENTER_FRAME, enterFrameHandler );
    }

    private function createScene():Group {
      var g:Group = new Group();
      
      myCone = new Cone("theObj1",50, 100);
      myHedra = new Hedra( "theObj2", 80, 60, 60 );
      
      myCone.x = -160;
      myCone.z = 150;
      myCone.y -= 50;
      myHedra.x = 50;
      myHedra.y -= 50;
      
      myCone.container.buttonMode = true;
      myHedra.container.buttonMode = true;
      
      var materialAttr:MaterialAttributes = new MaterialAttributes( 
                              new LineAttributes( 0.5, 0x2111BB, 0.4 ),
                              new LightAttributes( true, 0.1)
                            );
      
      var material:Material = new ColorMaterial( 0xFFCC33, 1, materialAttr );
      material.lightingEnable = true;
      var app:Appearance = new Appearance( material );
      myCone.appearance = app;
      myHedra.appearance = app;
      
      myCone.container.addEventListener(MouseEvent.CLICK, clickHandler);
      myCone.container.addEventListener(MouseEvent.MOUSE_OUT, outHandler);
      myHedra.container.addEventListener(MouseEvent.MOUSE_OVER, overHandler);
      myHedra.container.addEventListener(MouseEvent.MOUSE_OUT, outHandler);

      g.addChild(myCone);
      g.addChild(myHedra);
      
      return g;
    }

    private function enterFrameHandler( event : Event ) : void {
      myHedra.pan +=4;
      myCone.pan +=4;
      scene.render();
    }

    private function clickHandler(event:MouseEvent):void {
      myText.text = "You have hit the Cone";
      this.addChild(myText);
      needRemove = true;
    }

    private function overHandler(event:MouseEvent):void {
      myText.text = "Your mouse is over the Hedra";
      myText.x = 20;
      myText.y = 20;
      this.addChild(myText);
      needRemove = true;
    }

    private function outHandler(event:MouseEvent):void {
      if (needRemove) {
        this.removeChild(myText);
        needRemove = false;
      }
    }
  }
}

Examining the code

Let’s examine the code.

First, we add to our little flash tutorial a text field that will show the status when the user interacts with the objects.

import flash.text.*;
private var myText:TextField = new TextField();
// text position
myText.width = 200;
myText.x = 20;
myText.y = 20;
myCone = new Cone("theObj1",50, 100);
myHedra = new Hedra( "theObj2", 80, 60, 60 );
// adding interactivity...
myCone.container.addEventListener(MouseEvent.CLICK, clickHandler);
myCone.container.addEventListener(MouseEvent.MOUSE_OUT, outHandler);
myHedra.container.addEventListener(MouseEvent.MOUSE_OVER, overHandler);
myHedra.container.addEventListener(MouseEvent.MOUSE_OUT, outHandler);

Every 3D object has a property called container. The container property refers to the Sprite object, and so we add an even listener to the Sprite object. Here we have defined 3 listeners.

myText.text = "You have hit the Cone";
this.addChild(myText);
needRemove = true;
myText.text = "Your mouse is over the Hedra";
this.addChild(myText);
needRemove = true;
this.removeChild(myText);
needRemove = false;

This is it! Let’s see our result now.

The output

Click on the Cone and move the mouse over the Hydra!

Some limitations

This approach has some limitations: