forked from: flash on 2011-1-6

by j2e forked from flash on 2011-1-6 (diff: 222)
♥0 | Line 160 | Modified 2011-01-06 22:20:37 | MIT License
play

ActionScript3 source code

/**
 * Copyright j2e ( http://wonderfl.net/user/j2e )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/36nO
 */

package
{
    import com.greensock.TweenMax;
    import com.greensock.easing.*;
    
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.trace.Trace;
    
    public class MotionDetection extends Sprite
    {
        private var _camera:Camera;                                // camera class for webcam capture
        private var _video:Video;                                // video class for displaying the camera class
        private var _tracking:VideoTracker;                        // motion tracking class
        
        private var _paddle:PaddleMC            = new PaddleMC();        // table tennis paddle
        private var _shadow:ShadowMC            = new ShadowMC();        // table tennis paddle shadow
        private var _ball:BallMC                = new BallMC();            // table tennis ball
        private var _ballShadow:BallShadowMC    = new BallShadowMC();    // table tennis ball shadow
        private var _bkgd:BackgroundMC            = new BackgroundMC();    // table tennis table background
        private var _scoreMC:ScoreMC            = new ScoreMC();        // simple score text movie
        private var _startPanel:StartPanelMC    = new StartPanelMC();    // start game panel
        private var _endPanel:EndPanelMC;                                // end game panel
        
        private var _pos:Point            = new Point();            // current position of motion detection
        
        private var _w:uint                = 320;                    // width of camera/video source
        private var _h:uint                = 240;                    // height of camera/video source
        private var _ratioX:Number;                                // ratio of stage width over the video width
        private var _ratioY:Number;                                // ratio of stage height over the video height
        private var _maxRot:Number        = 30;                    // the maximum amount the paddle will rotate when moving away from the center of the screen
        private var _score:uint            = 0;                    // keeps tracks of the amount of times the balls been hit
        
        public function MotionDetection()
        {
            // setup
            setup();
            setupStage();
            resize();
            
            // events
            addEventListener(Event.ENTER_FRAME, loop);
            
            // add assets to the screen
            addChild(_bkgd);
            addChild(_scoreMC);
            addChild(_shadow);
            addChild(_paddle);
            addChild(_startPanel);
        }
        
        // main setup
        private function setup():void
        {
            // setup camera
            _camera    = Camera.getCamera();
            _camera.setMode(_w, _h, 15);
            
            // setup video and attach the camera
            _video    = new Video(_w, _h);
            _video.attachCamera(_camera);
            
            // setup the tracking class with the video as the source
            _tracking    = new VideoTracker(_video);
            
            // position start panel
            _startPanel.x    = sW*.5;
            _startPanel.y    = sH*.5;
            
            // add listener for button to start the game
            _startPanel.start_but.addEventListener(MouseEvent.MOUSE_DOWN, startGame, false, 0, true);
            
            // set default props on assets
            _paddle.z        = 0;
            _shadow.z        = 200;
            _shadow.alpha    = .5;
            _scoreMC.x        = sW*.5;
            _scoreMC.y        = sH-50;
        }
        
        // stage settings
        private function setupStage():void
        {
            stage.align            = StageAlign.TOP_LEFT;
            stage.scaleMode        = StageScaleMode.NO_SCALE;
            stage.addEventListener(Event.RESIZE, resize);
        }
        
        // reset/start game
        private function startGame(e:MouseEvent=null):void
        {
            // reset score
            _score    = 0;
            _scoreMC.tf_txt.text    = "0";
            
            // default the balls position to the center of the screen and hide it
            _ball.x                = sW*.5;
            _ball.z                = 0;
            _ball.alpha            = 0;
            _ballShadow.x        = sW*.5;
            _ballShadow.z        = 0;
            _ballShadow.alpha    = 0;
            
            // add ball to the scene
            addChild(_ballShadow);
            addChild(_ball);
            
            // if the start panel is showing then hide it
            if (_startPanel != null) TweenMax.to(_startPanel, .5, { alpha: 0, onComplete: removePanel, onCompleteParams: [_startPanel] });
            
            // if the end panel is showing then hide it
            if (_endPanel != null) TweenMax.to(_startPanel, .5, { alpha: 0, onComplete: removePanel, onCompleteParams: [_endPanel] });
            
            // set a delayed fade up animation for the ball and have a callback function to start the balls motion
            TweenMax.to(_ball, 1, { alpha: 1, onComplete: moveBall });
        }
        
        // end game
        private function endGame():void
        {
            // add end panel
            _endPanel    = new EndPanelMC();
            
            // position it
            _endPanel.x    = sW*.5;
            _endPanel.y    = sH*.5;
            
            // show it
            _endPanel.alpha    = 0;
            TweenMax.to(_endPanel, 1, { alpha: 1 });
            
            // update its score
            _endPanel.tf_txt.text    = String(_score);
            
            // add listener for button
            _endPanel.again_but.addEventListener(MouseEvent.MOUSE_DOWN, startGame, false, 0, true);
            
            // remove ball to the scene
            removeChild(_ballShadow);
            removeChild(_ball);
            
            // add the end panel to the display
            addChild(_endPanel);
        }
        
        // remove the speicifed panel from the scene
        private function removePanel(panel:Sprite):void
        {
            removeChild(panel);    // remove the panel from the display
            panel = null;        // null it to remove from memory
        }
        
        // update motion detection and render all elements
        private function loop(e:Event):void
        {
            // update tracking
            _tracking.track();
            
            _pos    = _tracking.pos;    // update current position
            _pos.x    *= _ratioX;            // update the positions by the ratio we have set
            _pos.y    *= _ratioY;
            
            movePaddle();                // update paddle movement
        }
        
        // update the movement of the paddle
        private function movePaddle():void
        {
            // update tracker
            _paddle.x    += (_pos.x - _paddle.x) * .1;
            _shadow.x    += (_pos.x - _shadow.x) * .1;
            
            // update rotation
            // this is based on the position of the paddle in relation to the screen width
            // we first set the the rotation to its lowest rotation and then use the
            // ratio of the paddles position to add more rotation to it
            var rot:Number        = -_maxRot + (_paddle.x/sW)*(_maxRot*2);
            _paddle.rotation    = rot;
            _shadow.rotation    = rot;
        }
        
        // update balls motion
        private function moveBall():void
        {
            var time:Number    = Math.random()*1+1;            // create a random time for the ball to bounce up with
            var x:Number    = Math.random()*(sW-200)+100;    // create a random x position for the ball to bounce to
            var z:Number    = -200 * time;                    // use the time to dictate the height of the balls bounce
            
            // create the animation
            TweenMax.to(_ball, time,        { x: x, ease: Sine.easeOut, onComplete: checkCollison });
            TweenMax.to(_ball, time*.5,        { z: z, ease: Circ.easeOut });
            TweenMax.to(_ball, time*.5,        { z: 0, ease: Circ.easeIn, delay: time*.5 });
            
            TweenMax.to(_ballShadow, time,        { x: x, ease: Sine.easeOut });
            TweenMax.to(_ballShadow, time*.5,    { alpha: .6/time, scaleX: 1/time, scaleY: 1/time, ease: Quad.easeInOut });
            TweenMax.to(_ballShadow, time*.5,    { alpha: .6, scaleX: 1, scaleY: 1, ease: Quad.easeInOut, delay: time*.5 });
        }
        
        // check ball collision with the paddle
        private function checkCollison():void
        {
            // this is just a simple collision detection system where we are just checking the balls
            // position comes back with a positive hitTest with the paddle
            if (_paddle.hitTestPoint(_ball.x, _ball.y, true))
            {
                moveBall();        // we have hit the ball, lets send the ball on a new motion path
                _score++;        // increment score
                updateScore();    // update score display
            }
            else
            {
                // we have missed the ball, lets show a prompt asking the user to start again
                endGame();
            }
        }
        
        // update score
        private function updateScore():void
        {
            _scoreMC.tf_txt.text    = String(_score);
        }
        
        // resize and reflow elements when the stage resizes
        private function resize(e:Event=null):void
        {
            _ratioX            = sW/_w;    // update x / y ratios
            _ratioY            = sH/_h;
            _paddle.y        = sH*.5;    // update paddle y position
            _shadow.y        = sH*.55;    // update shadow y position
            _ball.y            = sH*.35;    // update ball y position
            _ballShadow.y    = sH*.35;    // update ball y position
        }
        
        // return stage width and height
        public function get sW():uint        { return stage.stageWidth; }
        public function get sH():uint        { return stage.stageHeight; }
    }
}