Papervision3D Multiple Objects hitTest

Posted on January 10, 2009
Filed Under experiments, Papervision | 1 Comment

experiment_3D_v004

A little research on hitTest with multiple objects. You could imagine what you could do with it, for instance create a game like Guitar Hero (with a setup like this that is).

Code is now committed at codexperiments.googlecode.com, hope you enjoy it

If you want to add more hitArea’s (planes) on the stage to do hitTests with use for instance the following line of code:_world.addHitArea(0x0000FF, 500, -25, 600);.

experiment_3D_v006
1. Click here to see it in action with multiple hitarea’s

experiment_3D_v005
2. And add some nice reflections, and it will look like this

Code of the reflection version:

Main Class

  1. /**
  2.  * @author janwillemwisman
  3.  * We have 3 lanes, in this case: -500, 0 and 500
  4.  */
  5. package
  6. {
  7.  // wismanas3lib
  8.  import nl.wisman.utils.MathExt;
  9.  import nl.wisman.components.Slider;
  10.  
  11.  // flash
  12.  import flash.events.TimerEvent;
  13.  import flash.utils.Timer;
  14.  import flash.events.Event;
  15.  import flash.display.MovieClip;
  16.  
  17.  public class DemoHitTestReflection extends MovieClip
  18.  {
  19.   //
  20.   // on stage
  21.   //
  22.   public var thumb:MovieClip;
  23.   public var track:MovieClip;
  24.  
  25.   //
  26.   // private  properties
  27.   //
  28.   private var _world:GuitarHeroSetupReflection;
  29.   private var _leftLaneTimer:Timer;
  30.   private var _centerLaneTimer:Timer;
  31.   private var _rightLaneTimer:Timer;
  32.  
  33.   // wismanas3lib
  34.   private var _slider:Slider;
  35.  
  36.   //////////////////////////////////////////////////////////////////////////////////////
  37.   //
  38.   // Constructor
  39.   //
  40.   //////////////////////////////////////////////////////////////////////////////////////
  41.      
  42.   // ———————————————————————————–
  43.   public function DemoHitTestReflection()
  44.   {
  45.    addEventListener(Event.ADDED_TO_STAGE, initialize);
  46.   }
  47.  
  48.   //////////////////////////////////////////////////////////////////////////////////////
  49.   //
  50.   // Public methods
  51.   //
  52.   //////////////////////////////////////////////////////////////////////////////////////
  53.  
  54.   // ———————————————————————————–
  55.   // none
  56.  
  57.   //////////////////////////////////////////////////////////////////////////////////////
  58.   //
  59.   // Private methods
  60.   //
  61.   //////////////////////////////////////////////////////////////////////////////////////
  62.  
  63.   // ———————————————————————————–
  64.   private function initialize(event:Event):void
  65.   {
  66.    removeEventListener(Event.ADDED_TO_STAGE, initialize);
  67.    
  68.    // create world
  69.    _world = new GuitarHeroSetupReflection();
  70.    
  71.    // set start and end points
  72.    _world.startPointZ = 2000;
  73.    _world.endPointZ = -1000;
  74.    
  75.    // set hitarea positions
  76.    // (back) 1000 -> 0 -> -1000 (front) on z-axis
  77.    // left
  78.    _world.addHitArea(0xFF0000, -500, -25, 1200);
  79.    _world.addHitArea(0xFF0000, -500, -25, 0);
  80.    // center
  81.    _world.addHitArea(0xFFFFFF, 0, -25, 900);
  82.    _world.addHitArea(0xFFFFFF, 0, -25, 0);
  83.    // right
  84.    _world.addHitArea(0x0000FF, 500, -25, 1600);
  85.    _world.addHitArea(0x0000FF, 500, -25, 600);
  86.    _world.addHitArea(0x0000FF, 500, -25, 0);
  87.    
  88.    // initialize timers
  89.    _leftLaneTimer = new Timer(1000);
  90.    _leftLaneTimer.addEventListener(TimerEvent.TIMER, leftLaneTimerHandler);
  91.    _leftLaneTimer.start();
  92.    
  93.    _centerLaneTimer = new Timer(2000);
  94.    _centerLaneTimer.addEventListener(TimerEvent.TIMER, centerLaneTimerHandler);
  95.    _centerLaneTimer.start();
  96.    
  97.    _rightLaneTimer = new Timer(3000);
  98.    _rightLaneTimer.addEventListener(TimerEvent.TIMER, rightLaneTimerHandler);
  99.    _rightLaneTimer.start();
  100.  
  101.    // add to stage
  102.    addChild(_world);
  103.    
  104.    // Slider
  105.    _slider = new Slider(stage, thumb, track);
  106.    _slider.restricted = true;
  107.    _slider.friction = .90;
  108.    _slider.addEventListener(Event.CHANGE, sliderUpdate);
  109.   }
  110.  
  111.   // ———————————————————————————–
  112.   private function sliderUpdate(event:Event):void
  113.   {
  114.    var rot:Number = _slider.percentage;
  115.    
  116.    // only from front to back (1.8 instead of 3.6)
  117.    _world.universe.rotationY = rot * 1.8;
  118.   }
  119.  
  120.   // ———————————————————————————–
  121.   private function leftLaneTimerHandler(event:TimerEvent):void
  122.   {
  123.    _world.addNote(0xFF0000, -500, 0, MathExt.random(1, 4));
  124.   }
  125.  
  126.   // ———————————————————————————–
  127.   private function centerLaneTimerHandler(event:TimerEvent):void
  128.   {
  129.    _world.addNote(0xFFFFFF, 0, 0, MathExt.random(2, 5));
  130.   }
  131.  
  132.   // ———————————————————————————–
  133.   private function rightLaneTimerHandler(event:TimerEvent):void
  134.   {
  135.    _world.addNote(0x0000FF, 500, 0, MathExt.random(3, 6));
  136.   }
  137.  }
  138. }

3D World/setup Class

  1. package
  2. {
  3.  // flash
  4.  import flash.filters.BlurFilter;
  5.  import flash.events.Event;
  6.  
  7.  // tweenmax
  8.  import gs.TweenMax;
  9.  
  10.  // papervision3d
  11.  import org.papervision3d.objects.primitives.Plane;
  12.  import org.papervision3d.objects.DisplayObject3D;
  13.  import org.papervision3d.core.proto.MaterialObject3D;
  14.  import org.papervision3d.lights.PointLight3D;
  15.  import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
  16.  import org.papervision3d.materials.utils.MaterialsList;
  17.  import org.papervision3d.objects.primitives.Cube;
  18.  import org.papervision3d.core.effects.view.ReflectionView;
  19.  import org.papervision3d.materials.WireframeMaterial;
  20.  
  21.  
  22.  public class GuitarHeroSetupReflection extends ReflectionView
  23.  {
  24.   //
  25.   // public properties
  26.   //
  27.   // the higher it is, the further away
  28.   public var startPointZ:Number = 500;
  29.   // the lower the closer it will come
  30.   public var endPointZ:Number = -500;
  31.  
  32.   //
  33.   // private properties
  34.   //
  35.   private var _light:PointLight3D;
  36.   private var _matList:MaterialsList = new MaterialsList();
  37.   private var _hitAreaList:Array = new Array();
  38.   private var _noteList:Array = new Array();
  39.   private var _universe:DisplayObject3D;
  40.  
  41.   //////////////////////////////////////////////////////////////////////////////////////
  42.   //
  43.   // Constructor
  44.   //
  45.   //////////////////////////////////////////////////////////////////////////////////////
  46.      
  47.   // ———————————————————————————–
  48.   public function GuitarHeroSetupReflection()
  49.   {
  50.    // use reflection
  51.    viewportReflection.filters = [new BlurFilter(6,6,1)];
  52.    setReflectionColor(.5, .5, .5);
  53.    surfaceHeight = -100;
  54.    
  55.    _universe = new DisplayObject3D();
  56.    scene.addChild(_universe);
  57.    
  58.    initialize();
  59.   }
  60.  
  61.   //////////////////////////////////////////////////////////////////////////////////////
  62.   //
  63.   // Public methods
  64.   //
  65.   //////////////////////////////////////////////////////////////////////////////////////
  66.  
  67.   // ———————————————————————————–
  68.   public function addHitArea(hitColor:Number = 0×000000, xPos:Number = 0, yPos:Number = 0, zPos:Number = 0):void
  69.   {
  70.    var material:MaterialObject3D = new WireframeMaterial(hitColor, .5, 1);
  71.    material.doubleSided = true;
  72.    var plane:Plane = new Plane(material, 200, 200, 2, 2);
  73.    plane.x = xPos;
  74.    plane.y = yPos;
  75.    plane.z = zPos;
  76.    plane.rotationX = 90;
  77.    universe.addChild(plane);
  78.    
  79.    _hitAreaList.push(plane);
  80.   }
  81.  
  82.   // ———————————————————————————–
  83.   public function addNote(noteColor:Number = 0xFF0000, xPosition:Number = 0, yPosition:Number = 0, speed:Number = 1):void
  84.   {
  85.    // create material
  86.    var material:MaterialObject3D = new FlatShadeMaterial(_light, noteColor ,0X333333);
  87.    _matList.addMaterial(material, "all");
  88.    
  89.    // create box
  90.    var box:Cube = new Cube(_matList, 200, 200,50, 2, 2, 2);
  91.    box.x = xPosition;
  92.    box.y = yPosition;
  93.    box.z = startPointZ;
  94.    box.extra = {hitted: false};
  95.    
  96.    // add box
  97.    universe.addChild(box);
  98.    
  99.    // store all 3d objecs
  100.    _noteList.push(box);
  101.    
  102.    // start tween
  103.    startTween(box, speed);
  104.   }
  105.  
  106.   //////////////////////////////////////////////////////////////////////////////////////
  107.   //
  108.   // Getters & Setters
  109.   //
  110.   //////////////////////////////////////////////////////////////////////////////////////
  111.  
  112.   // ———————————————————————————–
  113.   public function get universe():DisplayObject3D
  114.   {
  115.    return _universe;
  116.   }
  117.  
  118.   //////////////////////////////////////////////////////////////////////////////////////
  119.   //
  120.   // Private methods
  121.   //
  122.   //////////////////////////////////////////////////////////////////////////////////////
  123.  
  124.   // ———————————————————————————–
  125.   private function initialize():void
  126.   {
  127.    // place camera higher-up and look down
  128.    camera.y = 400;
  129.    
  130.    // light
  131.    _light = new PointLight3D();
  132.    _light.x = camera.x + 500;
  133.    _light.y = camera.y;
  134.  
  135.    var do3d:DisplayObject3D = new DisplayObject3D();
  136.    scene.addChild(do3d);
  137.    camera.lookAt(do3d);
  138.    _light.lookAt(do3d);
  139.    
  140.    // render
  141.    addEventListener(Event.ENTER_FRAME, update);
  142.   }
  143.  
  144.   // ———————————————————————————–
  145.   private function startTween(box:Cube, speed:Number):void
  146.   {
  147.    TweenMax.to(box, speed, {z: endPointZ});
  148.   }
  149.  
  150.   // ———————————————————————————–
  151.   private function update(event:Event):void
  152.   {
  153.    for (var i:int = 0; i < _noteList.length; ++i)
  154.    {
  155.     for (var j:int = 0; j < _hitAreaList.length; ++j)
  156.     {
  157.      var note:Cube = _noteList[i] as Cube;
  158.      var hitArea:Plane = _hitAreaList[j] as Plane;
  159.      
  160.      // reset when needed
  161.      if (!note.hitTestObject(hitArea) && note.extra.hitted)
  162.      {
  163.       note.y = 0;
  164.       note.extra.hitted = false;
  165.      }
  166.      
  167.      // set note when hits a plane
  168.      if (note.hitTestObject(hitArea))
  169.      {
  170.       note.extra.hitted = true;
  171.       note.y = 100;
  172.       break;
  173.      }
  174.     }
  175.    
  176.     // remove when needed
  177.     if (note.z <= endPointZ)
  178.     {
  179.      _universe.removeChild(note);
  180.      _noteList.slice(i,0);
  181.     }
  182.    }
  183.    
  184.    // render reflection
  185.    singleRender();
  186.   }
  187.  }
  188. }

Comments

One Response to “Papervision3D Multiple Objects hitTest”

  1. Timur I. Alhimenkov on January 27th, 2009 11:31 pm

    Great! Thank you very much!
    I always wanted to write in my site something like that. Can I take part of your post to my blog?
    Of course, I will add backlink?

    Sincerely, Your Reader

-->