/src/bipede/membres/Squelette.as
http://himemm.googlecode.com/ · ActionScript · 645 lines · 428 code · 94 blank · 123 comment · 39 complexity · 155ebca2e39e9041395d8e7c8c2c8616 MD5 · raw file
- /*
- *
- * Sprite possédant :
- *
- * une Armature
- * une pose par défaut
- * ( des poignées ? des joints physiques ? des contraintes ? )
- *
- * les IKBone nécessaires sont :
- *
- * bone_mainD
- * bone_piedD
- * bone_mainG
- * bone_piedG
- * epine
- *
- * Le MovieClip Tete contenant les Yeux
- *
- * Gestion des armatures :
- *
- * Il ne peut pas exister 2 instances avec la męme armature : la derničre écrase les précédentes.
- * ŕ cause du IKManager.getArmatureByName( "name" );
- *
- * */
- package bipede.membres
- {
- import drawer.events.DrawEvent;
-
- import fab.geom.Drawer;
- import fab.geom.Circle;
- import fab.geom.Line;
- import fab.geom.Segment;
- import fab.Utils;
-
- import events.MarcheEvent;
- import events.MoveEvent;
- import events.PersonEvent;
- import events.PhysicEvent;
-
- import bipede.controleurs.Animateur;
- import bipede.animation.Pose;
-
- import physic.Liaison;
- import physic.Contrainte;
- import physic.Engine;
- import physic.SoftBody;
- import physic.Obstacle;
-
- import clips.Poignee_mc;
- import clips.Poignee;
-
- import fl.ik.*;
-
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.events.MouseEvent;
- import flash.events.TimerEvent;
- import flash.geom.Point;
- import flash.geom.Matrix;
- import flash.geom.Rectangle;
-
- import flash.utils.getQualifiedClassName;
- import flash.utils.Timer;
- import flash.utils.Dictionary;
-
- public class Squelette extends Sprite
- {
- public var tree:IKArmature;
- public var testIKjoints:Vector.<PhysicJoint> = new Vector.<PhysicJoint>();
- public var pieds:Vector.<Pied> = new Vector.<Pied>();
- public var lesBras:Vector.<Bras> = new Vector.<Bras>();
- //public var contraintes:Vector.<Contrainte> = new Vector.<Contrainte>();
- public var contraintes:Object = new Object();
- public var physic_bones:Object = new Object();
- //private var poignees:Vector.<Poignee> = new Vector.<Poignee>();
- public var data:Dictionary = new Dictionary();
- private var _pose:Pose;
- private var _target_pose:Pose;
-
- public var default_pose:Pose;
-
- public var initStatus:Object;
-
-
- private var clipBone:Sprite;
- private var ikMover:IKMover;
- private var bones_names:Array;
- private var ikMovers:Vector.<IKMover> = new Vector.<IKMover>();
-
- //public var animateurs:Vector.<Animateur> = new Vector.<Animateur>();
- public var animateurs:Dictionary = new Dictionary();
-
- public var main_gauche:Bras;
- public var main_droite:Bras;
- public var pied_gauche:Pied;
- public var pied_droit:Pied;
- public var current_pied:Pied;
- public var autre_pied:Pied;
- private var _start_pose:Pose;
-
- private var marche_compteur:Timer;
-
- private var anim_compteur:Timer;
- private var anim_increment:Number;
-
- public var physics:SoftBody;
-
- public var _rectangle_pied_gauche:Rectangle;
-
-
- public function init():void
- {
- main_gauche = create_main( "bone_mainG" );
- main_droite = create_main( "bone_mainD" );
-
- pied_gauche = create_pied( "bone_piedG" );
- pied_droit = create_pied( "bone_piedD" );
-
- current_pied = pied_gauche;
- autre_pied = pied_droit;
-
- anim_compteur = new Timer( 40, 10 );
- anim_compteur.addEventListener( TimerEvent.TIMER, _tick );
- anim_compteur.addEventListener( TimerEvent.TIMER_COMPLETE, _fin_tick );
-
- //IKManager.trackIKObject( dummy_mainD, true );
- //create_poignee_mc( "dummy_mainD" );
-
- parse_IKJoint_tree( register_physic_bone, tree.rootJoint );
-
- //addEventListener( MoveEvent.MOVING, moving );// passage dans physics
- };
-
- public function Squelette()
- {
- addEventListener(Event.FRAME_CONSTRUCTED, frameConstructedHandler);
- }
- private function frameConstructedHandler(event:Event):void
- {
- removeEventListener(Event.FRAME_CONSTRUCTED, frameConstructedHandler);
-
- tree = IKManager.getArmatureByName( "Armature_" + getQualifiedClassName( this ) );
-
- tree.registerElements( this );
- default_pose = pose;
-
- // trace de armature
-
- parse_IKJoint_tree( traceArmature, tree.rootJoint );
-
- initStatus = { scaleX:scaleX, scaleY:scaleY };
-
- init();// to override
-
- dispatchEvent( new PersonEvent( PersonEvent.ARMATURE_READY ) );
- dispatchEvent( new PersonEvent( PersonEvent.ANIMATIONS_READY ) );
- }
-
-
- public function create_contrainte( p:Point, mobileBoneNom:String, attachBoneNom:String ):Contrainte
- {
- // TODO
- release_joint_constraint( mobileBoneNom, 4 );
-
- var mobileBone:IKBone = tree.getBoneByName( mobileBoneNom );
- //var tailJoint:IKJoint = mobileBone.tailJoint;
-
- var attachBone:IKBone = tree.getBoneByName( attachBoneNom );
- //var attachTailJoint:IKJoint = attachBone.tailJoint;
-
- var c:Contrainte = new Contrainte( this, p, mobileBone, attachBone );
- contraintes[ mobileBone.tailJoint.name ] = c;
- return c;
- }
- public function create_physic_joint( nom:String ):void
- {
- var bone:IKBone = tree.getBoneByName( nom );
- var tailJoint:IKJoint = bone.tailJoint;
- testIKjoints.push( new PhysicJoint( tailJoint ) );
- }
- public function create_pied( nom:String ):Pied
- {
- var bone:IKBone = tree.getBoneByName( nom );
- //var tailJoint:IKJoint = bone.tailJoint;
- var pied:Pied = new Pied( this, bone );
- pieds.push( pied );
- return pied;
- }
- public function get tete():*
- {
- var bone:IKBone = tree.getBoneByName( "epine" );
- //trace(bone);
- var tailJoint:IKJoint = bone.tailJoint;
- //trace(tailJoint);
- trace(tailJoint.name);
- return ( tailJoint );
- }
- public function create_main( nom:String ):Bras
- {
- var bone:IKBone = tree.getBoneByName( nom );
- //var tailJoint:IKJoint = bone.tailJoint;
- var bras:Bras = new Bras( this, bone );
- lesBras.push( bras );
- trace("create_main", nom, this.name, bras, bone);
- return bras;
- }
- public function create_poignee_bone( nom:String, x:int=0, y:int=0 ):Poignee
- {
- var bone:IKBone = tree.getBoneByName( nom );
- var tailJoint:IKJoint = bone.tailJoint;
- var position:Point = tailJoint.position;
-
- var ikMover:IKMover = new IKMover( tailJoint, tailJoint.position );
-
- var j:Poignee = new Poignee( ikMover, tailJoint );
- //stage.
- addChild( j );
- j.x = position.x;
- j.y = position.y;
- return j;
- }
- public function create_poignee_mc( nom:String, x:int=0, y:int=0 ):void
- {
- var j:Poignee_mc = new Poignee_mc( this[ nom ] );
- addChild( j );
- j.x = this[ nom ].x;
- j.y = this[ nom ].y;
- }
-
-
- public function set orientation( vers_la_droite:Boolean ):void
- {
- scaleX = vers_la_droite?initStatus.scaleX: - initStatus.scaleX;
- }
- /*
- * renvoie true si vers la droite
- * */
- public function get orientation():Boolean
- {
- return scaleX > 0;
- }
- public function get pose():Pose
- {
- _pose = new Pose();//<pose></pose>;
- parse_IKJoint_tree( getPoseJoint, tree.rootJoint );
- return _pose;
- }
- public function set pose(p:Pose):void
- {
- _target_pose = p;
- parse_IKJoint_tree( setPoseJoint, tree.rootJoint );
- }
- public function set place(p:Point):void
- {
- //x = int( p.x );// foire les petites anim comme bras_ballants
- //y = int( p.y );
- x = ( p.x );
- y = ( p.y );
- }
- public function get place():Point
- {
- return new Point( x, y );
- }
-
- // mapping functions
-
- public function getPoseJoint( nextJoint:* ):void
- {
- _pose.append( nextJoint.name, nextJoint.position );
- }
- /*
- public function setPoseJoint( nextJoint:* ):void
- {
- var position:Point = nextJoint.position;
- var target:Point = _target_pose.getPosition( nextJoint.name );
-
- var ikMover:IKMover = new IKMover( nextJoint, position );
- ikMover.limitByIteration = true;
- ikMover.iterationLimit = 6;
- ikMover.moveTo( target );
- }
- */
- public function traceArmature( obj:* ):void
- {
- trace( "\tJoint " + obj.name + "\t\t\tsur Bone " + obj.bone.name + "\t\t\t yTranslationMin " + obj.yTranslationMin + "\t\t\t yTranslation " + obj.yTranslation );
- }
- public function register_physic_bone( obj:* ):void
- {
- physic_bones[ obj.bone.name ] = new PhysicBone( obj.bone );
- }
-
- // pose de l'armature :
- // 2 méthodes : tous les joints, ou les joints ŕ poignee ? ou les bones ?
-
- public function parse_IKJoint_tree( recursiveFunc:Function, joint:IKJoint ):void
- {
- recursiveFunc( joint );
- for ( var i:int = 0; i < joint.numChildren; i++ )
- {
- var childJoint = joint.getChildAt( i );
- //if ( childJoint.numChildren > 0 )
- parse_IKJoint_tree( recursiveFunc, childJoint );
- }
- }
- public function distance_au_support( support:Obstacle ):int
- {
- return support.plateforme.distance( place );
- }
- public function release_joint_constraint( nom:String, steps:int=2 ):void
- {
- var step:int = 0;
- var bone:IKBone = tree.getBoneByName( nom );
- var currentJoint:IKJoint = bone.tailJoint;
- while( currentJoint != tree.rootJoint || step < steps )
- {
- currentJoint.rotationConstrained = false;
- step++;
- currentJoint = currentJoint.parent;
- }
- }
- public function joint2root_distance_px( nom:String ):int
- {
- var bone:IKBone = tree.getBoneByName( nom );
- var d:int = physic_bones[ bone.name ].longueur;
- var currentJoint:IKJoint = bone.tailJoint;
- while( currentJoint != tree.rootJoint )
- {
- currentJoint = currentJoint.parent;
- d += physic_bones[ currentJoint.bone.name ].longueur;
- }
- return d;
- }
-
-
- // ------------------------ from Person :
-
-
- public function record():Pose
- {
- return pose;
- }
- public function set_default_pose( event:MouseEvent=null ):void
- {
- pose = default_pose;
- }
- public function register_animateur( anim:Animateur ):void
- {
- trace("register_animateur " + anim.type);
- animateurs[ anim.type ] = anim;
- }
- public function unregister_animateur( anim:Animateur ):void
- {
- trace("UNregister_animateur " + anim.type);
- delete animateurs[ anim.type ];
- //animateurs[ anim.type ] = null;
- trace("animateurs length " + animateurs.length);
- }
- public function applique():void
- {
-
-
- }
- public function startmoving( event:MoveEvent ):void
- {
- //Engine.stop();
-
- //default_pose = pose;
- set_default_pose();
- //trace("startmoving\r" + default_pose);
-
- for each ( var anim:Animateur in animateurs )
- {
- anim.stop();
- //anim = null;
- //unregister_animateur( anim );
- }
- }
- public function endmoving( event:MoveEvent ):void
- {
- //physics.vitesse = vitesse;
- trace(physics.vitesse);
- //Engine.start();
- //pose = default_pose;// tweener !
- //trace("endmoving " + default_pose);
-
- //positionne( default_pose, 4 );
-
-
- }
- public function _physic_update( event:PhysicEvent ):void
- {
- //positionne( pose );// .translation( new Point( - physics.vitesse.x, - physics.vitesse.y ) ) );
- }
- /*
- * MOVING est subie
- * */
- public function moving(event:MoveEvent = null):void
- {
- var cible:Point = event.point;
-
- for each ( var contrainte:Contrainte in contraintes ) cible = contrainte.correction( cible );
- /*
- for each ( var pied:Pied in pieds )
- {
- if ( pied.support != null )//pied_droit ?
- {
- if ( pied.support.plateforme.distance( cible ) < distance_support )
- {
- var p:Point = pied.support.plateforme.projection( cible );
- Drawer.drawPoint( Main.drawings.graphics, p );
- var cercle:Circle = new Circle( p, distance_support );
- cible = cercle.projection( cible, false );
- }
- else {
- pied.remove_support();
- }
- }
- }
- */
- var vitesse:Point = cible.subtract( place );
-
- place = cible;
-
- if ( vitesse.length > 4 )
- positionne( default_pose );// pose.translation( new Point( vitesse.x, vitesse.y ) ) );
-
- if ( physics != null ) physics.vitesse = vitesse;
- }
- /*
- * renvoie un rectangle de test pour la pose du pied dans le systeme de Engine.espace
- * */
- public function get rectangle_pied_gauche():Rectangle
- {
- if ( !orientation ) data.rectangle_pied_gauche.x = 170;
- else data.rectangle_pied_gauche.x = 20;
-
- var origine:Point = Utils.PointLocalTransformation( data.rectangle_pied_gauche.topLeft, this, Engine.espace );
- // ( int ) pour les tests d'instersectRectangle
- return new Rectangle( int(origine.x), int(origine.y), data.rectangle_pied_gauche.width, data.rectangle_pied_gauche.height );
- }
- public function get rectangle_pied_droit():Rectangle
- {
- if ( !orientation ) data.rectangle_pied_gauche.x = 170;
- else data.rectangle_pied_gauche.x = 20;
- var rect:Rectangle = data.rectangle_pied_gauche.clone();
- rect.offset( -45, 0 );
- var origine:Point = Utils.PointLocalTransformation( rect.topLeft, this, Engine.espace );
- // ( int ) pour les tests d'instersectRectangle
- return new Rectangle( int(origine.x), int(origine.y), data.rectangle_pied_gauche.width, data.rectangle_pied_gauche.height );
- }
-
- // ŕ placer côté Person ??? :
-
- public function findSupport(event:MarcheEvent):void
- {
- var rectangle:Rectangle = event.dynamic_pied_gauche?rectangle_pied_gauche:rectangle_pied_droit;
- var intersect_array:Array = new Array();
- var intersect:Segment;
-
- dispatchEvent( new DrawEvent( DrawEvent.DRAWRECTANGLE, rectangle, 0xFF0000 ) );
-
- // recherche des Segments de plateformes d'obstacle inclus dans un rectangle
-
- for each ( var obstacle:Obstacle in Engine.obstacles )
- {
- //if ( obstacle.display.hitTestPoint( p.x, p.y, true ) )
- //{
- //Drawer.drawRectangle( Main.drawings.graphics, rectangle );
- var plateforme:Segment = obstacle.plateforme;
- //trace("findSupport ? "+obstacle);
- //Drawer.drawSegment( Main.drawings.graphics, plateforme.debut, plateforme.fin );
- intersect = plateforme.instersectRectangle( rectangle );
- if ( intersect != null )
- {
- intersect_array.push( { intersect:intersect, obstacle:obstacle, xmax:orientation?intersect.rectangle.right:intersect.rectangle.left, ymin:intersect.rectangle.top } );
- }
- //}
- }
-
- // classement des segments par leur xmax et envoie du premier
-
- if ( intersect_array.length > 0 )
- {
- intersect_array.sortOn( "xmax", (orientation?Array.DESCENDING:Array.NUMERIC) | Array.NUMERIC );
- //intersect_array.sortOn( "ymin", Array.DESCENDING | Array.NUMERIC );
-
- //Main.drawings.graphics.lineStyle( 0, 0x00FF00 );
- //Drawer.drawSegment( Main.drawings.graphics, intersect.debut, intersect.fin );
- dispatchEvent( new MarcheEvent( MarcheEvent.LOCALISE_SUPPORT, intersect_array[ 0 ].intersect, intersect_array[ 0 ].obstacle ) );
- }
- else {
- dispatchEvent( new MarcheEvent( MarcheEvent.NO_SUPPORT ) );
- trace(" pas de support" );
- }
- }
- public function repose(event:MoveEvent):void
- {
- stand(event);
- support = event.support;
- }
- public function get support():Obstacle
- {
- if ( pied_droit.support != null ) return pied_droit.support;
- if ( pied_gauche.support != null ) return pied_gauche.support;
- return null;
- }
- public function set support(o:Obstacle):void
- {
- pied_droit.support = o;
- pied_gauche.support = o;
- }
- public function stand(event:MoveEvent):void
- {
- //trace("stand " + event );
- if ( event.support == null )
- {
- trace( "il faut un support pour se stand." );
- return;
- }
- if ( event.point != null ) place = event.point;
- stayOnSupport( event.support, true, true );
- }
- public function stayOnSupport(obstacle:Obstacle, attract:Boolean = true, toujours:Boolean = false ):void
- {
- place = new Circle( support.plateforme.projection( place ), data.distance_support ).projection( place, attract, toujours );
- }
- public function move(event:MoveEvent):void
- {
- var cible:Point = (event.point as Point).clone();
- var vitesse:Point;
-
- if ( event.increment )
- {
- vitesse = cible;
- place = place.add( cible );
- }
- else {
- vitesse = cible.subtract( place );
- place = cible;
- }
- if ( event.support != null ) stayOnSupport( event.support );
-
- //positionne( pose.translation( new Point( -vitesse.x, -vitesse.y ) ) );
- if ( physics != null ) physics.vitesse = vitesse;
- }
- public function atterrit(event:MoveEvent):void
- {
- if ( animateurs.saut.running ) return;
-
- // event.point contient un tableau d'object { intersect:Point intersection, obstacle:Obstacle touché }
- var hitted_obstacles:Array = event.point;
-
- var hitted_obstacle:Obstacle = hitted_obstacles[ 0 ].obstacle;
- support = hitted_obstacle;
-
- // point sur la plateforme, que croise le vecteur deplacement de Person augmenté de data.distance_support_max
- var hitted_point:Point = hitted_obstacles[ 0 ].intersect;
-
- // calcul du point bas du Person p/r au support _bloc
- var cercle:Circle = new Circle( hitted_point, data.distance_support );
- var cible:Point = cercle.projection( place, true, true );
-
- pied_droit.support = support;
- pied_gauche.support = support;
-
- //Engine.unRegisterSoftBody( this );// fait, du côté de Engine
-
- var atterrissage:Animateur = new Animateur( this );
- atterrissage.action( "atterrissage" );
- atterrissage.configure( {
- support:support,
- sujet:this,
- place:place,
- cible:cible,
- vitesse:.2
- } );
- atterrissage.start();
- }
- public function decolle(event:MoveEvent):void
- {
- trace("decolle");
- support = null;
- physics = Engine.registerSoftBody( this );
- physics.vitesse = event.point.vitesse_sujet;
- if ( !Engine.started ) Engine.getInstance().start();
- }
-
- // mapping functions
-
- //override
- public function setPoseJoint( nextJoint:* ):void
- {
- var position:Point = nextJoint.position;
-
- var target:Point = _target_pose.getPosition( nextJoint.name );
- var startposition:Point = _start_pose.getPosition( nextJoint.name );
-
- var ikMover:IKMover = new IKMover( nextJoint, position );
- ikMover.limitByIteration = true;
- ikMover.iterationLimit = 6;
-
- var cible:Point = Point.interpolate( target, startposition, anim_increment );
-
- // contraintes
- var contrainte:Contrainte = contraintes[ nextJoint.name ]
- if ( contrainte != null ) cible = globalToLocal( contrainte );
-
- ikMover.moveTo( cible );
- }
- public function positionne( newpose:Pose, steps:int=0 ):void
- {
- //trace( "\t///////////////////////// positionne " + name );
-
- _start_pose = pose;
- _target_pose = newpose;
-
- anim_compteur.reset();
- if ( steps == 0 )
- {
- anim_increment = 1;
- parse_IKJoint_tree( setPoseJoint, tree.rootJoint );
- }
- else {
- anim_compteur.repeatCount = steps;
- anim_compteur.start();
- }
- //trace( "\t///////////////////////// ------------" );
- }
-
- // pour temporiser avant nouveau frame :
-
- private function _fin_tick( event:TimerEvent ):void
- {
- dispatchEvent( new MoveEvent( MoveEvent.FINFRAME ) );
- }
- private function _tick( event:TimerEvent ):void
- {
- anim_increment = anim_compteur.currentCount / anim_compteur.repeatCount;
-
- trace( ">increment> " + anim_increment );
-
- parse_IKJoint_tree( setPoseJoint, tree.rootJoint );
- }
- }
- }