Skip to content


APE Project – Step 7 – Rotating Rectangle Particles – Fix

Well, I always knew that the best debugging practice is to walk away and revisit the issue at a later time – and with the extra spare time it is best to get some rest, drink some beer, or just watch my girlfriend decorate our house with her designer handmade crafts. Anyways, I have found my issue which was my lack of control of event listeners – when the user clicked the rectangle to rotate it the movie was also thinking that another rectangle would like to be drawn.

The fix for this is that I added a variable called ‘canDraw’ which is enabled when you hold down the shift and drag your mouse across the stage to create a rectangle. To rotate the rectangle you simply click the rectangle that you drew and it will rotate by .5 radians. For now you can only rotate the latest created rectangle.

Here is just the new Main document class:

package {
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.ui.Keyboard;
	import flash.events.MouseEvent;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import fl.controls.Button;
	import org.cove.ape.*;

	public class Main extends Sprite {

		private var beginX:Number; // top left x position
		private var beginY:Number; // top left y position
       	private var endX:Number; // bottom right x position
       	private var endY:Number; // bottom right y position  

		private var dynRect:RectangleParticle;
		private var canDraw:Boolean = false; // this allows the drawing of rectangles
		private var circle:CircleParticle;
		private var circleGroup:Group;
        private var defaultGroup:Group;

		private var car:Car;
		private var btnCar:Button;

		// rectangle particle dimensions
		private var _xpos:Number;
		private var _ypos:Number;
		private var _rwidth:Number;
		private var _rheight:Number;
		private var _rrotation:Number = 0;

		public function Main()
		{
			init();
		}

		private function init():void
		{
			stage.frameRate = 55;

            // Initialize the engine. The argument here is the time step value.
            // Higher values scale the forces in the sim, making it appear to run
            // faster or slower. Lower values result in more accurate simulations.
            APEngine.init(1/4);  

            // set up the default diplay container
            APEngine.container = this;  

            APEngine.addMasslessForce(new Vector(0,8));  

            defaultGroup = new Group();  

            defaultGroup.collideInternal = true;

			circleGroup = new Group();
			circleGroup.collideInternal = true;

			// this is the bottom
			var rect:RectangleParticle = new RectangleParticle(345, 680, 710, 40, 0, true);
            defaultGroup.addParticle(rect);  

			var l:RectangleParticle = new RectangleParticle(0, stage.stageHeight / 2 - 20, 10, stage.stageHeight-40, 0, true);
            defaultGroup.addParticle(l);

			var r:RectangleParticle = new RectangleParticle(stage.stageWidth, stage.stageHeight / 2 - 20, 10, stage.stageHeight-40, 0, true);
            defaultGroup.addParticle(r);

            APEngine.addGroup(defaultGroup);
			APEngine.addGroup(circleGroup);

			// make the groups collidable
			defaultGroup.addCollidable(circleGroup);

			addEventListener(Event.ENTER_FRAME, run);

			stage.addEventListener(KeyboardEvent.KEY_DOWN, allowDraw);
			stage.addEventListener(KeyboardEvent.KEY_UP, disallowDraw);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, beginRectDraw);
			stage.addEventListener(MouseEvent.MOUSE_UP, stopRectDraw);

			// build the UI
			buildUI();
		}

		function allowDraw(event:KeyboardEvent):void
		{
			if ( event.keyCode == 16 )
			{
            	canDraw = true;
			}
        }

		function disallowDraw(event:KeyboardEvent):void {
            if ( canDraw ) canDraw = false;
        }

		private function beginRectDraw(m:MouseEvent):void
       	{
			beginX = mouseX;
			beginY = mouseY;
       	}

		private function stopRectDraw(m:MouseEvent):void
       	{
			// set the end points
           	endX = mouseX;
		   	endY = mouseY;

			// now draw the rectangle
			if ( canDraw ) drawRectangle();
		}

		private function drawRectangle():void
		{
			if ( beginY < 660 && endY < 660 )
			{
				// store the data
				_xpos = beginX + ((endX - beginX)/2);
				_ypos = beginY + ((endY - beginY)/2);
				_rwidth = endX - beginX;
				_rheight = endY - beginY;
				_rrotation = 0;

				dynRect = new RectangleParticle(_xpos, _ypos, _rwidth, _rheight, _rrotation, true);
            	defaultGroup.addParticle(dynRect);

				dynRect.sprite.addEventListener ( MouseEvent.MOUSE_DOWN, rotateRectangle );
			}
		}

		private function rotateRectangle( m:MouseEvent ):void
		{
			if ( !canDraw )
			{
				// increment the angle
				_rrotation += .05;

				// rid of the particle
				defaultGroup.removeParticle(dynRect);

				// redraw the particle
				dynRect = new RectangleParticle(_xpos, _ypos, _rwidth, _rheight, _rrotation, true);
            	defaultGroup.addParticle(dynRect);

				dynRect.sprite.addEventListener ( MouseEvent.MOUSE_DOWN, rotateRectangle );
			}
		}

		private function addBall( m:MouseEvent ):void
        {
            circle = new CircleParticle(Math.random() * stage.stageWidth, Math.random() * 100, Math.random() * 25 + 5);
            circleGroup.addParticle(circle);
        }

		private function addCar ( m:MouseEvent ):void
		{
			btnCar.removeEventListener(MouseEvent.CLICK, addCar);

			car = new Car(Math.random() * 0xffffff,Math.random() * 0xffffff);
            APEngine.addGroup(car);
			defaultGroup.addCollidable(car);
			circleGroup.addCollidable(car);

			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);

			// change the type of the button
			btnCar.label = "Remove Car";

			btnCar.addEventListener(MouseEvent.CLICK, removeCar);
		}

		private function removeCar ( m:MouseEvent ):void
		{
			btnCar.removeEventListener(MouseEvent.CLICK, removeCar);

			// remove the car
			APEngine.removeGroup(car);

			// change the label
			btnCar.label = "Add Car";

			// change the button action
			btnCar.addEventListener(MouseEvent.CLICK, addCar);
		}

		private function run(e:Event):void
        {
            APEngine.step();
            APEngine.paint();
        }

		private function removeLastBall( m:MouseEvent ):void
		{
			if ( circle ) circle.cleanup();
		}

		private function clearBoard( m:MouseEvent ):void
		{
			APEngine.removeGroup(defaultGroup);
			APEngine.removeGroup(circleGroup);
			APEngine.removeGroup(car);
			init();

		}

		function keyPressed(event:KeyboardEvent):void {
            var keySpeed:Number = 0.8;  

            if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.RIGHT)
            {
                car.speed = keySpeed;
            }  

            if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.LEFT)
            {
                car.speed = -keySpeed;
            }
        }  

        function keyReleased(event:KeyboardEvent):void
        {
            car.speed = 0;
        }  

		private function buildUI():void
		{

			// NEW BUTTONS
            var btnAddBall:Button = new Button();
            btnAddBall.width = 65;
            btnAddBall.height = 25;
            btnAddBall.move ( 5, stage.stageHeight - 20 - btnAddBall.height / 2 );
            btnAddBall.label = "Add Ball";      

            addChild(btnAddBall);      

            btnAddBall.addEventListener(MouseEvent.CLICK, addBall);  

			var btnRemoveBall:Button = new Button();
            btnRemoveBall.width = 120;
            btnRemoveBall.height = 25;
            btnRemoveBall.move ( 75, stage.stageHeight - 20 - btnRemoveBall.height / 2 );
            btnRemoveBall.label = "Remove Last Ball";      

            addChild(btnRemoveBall);

            btnRemoveBall.addEventListener(MouseEvent.CLICK, removeLastBall);

			btnCar = new Button();
            btnCar.width = 100;
            btnCar.height = 25;
            btnCar.move ( 200, stage.stageHeight - 20 - btnCar.height / 2 );
            btnCar.label = "Add Car";      

            addChild(btnCar);

            btnCar.addEventListener(MouseEvent.CLICK, addCar);

			var btnClearBoard:Button = new Button();
            btnClearBoard.width = 120;
            btnClearBoard.height = 25;
            btnClearBoard.move ( 575, stage.stageHeight - 20 - btnClearBoard.height / 2 );
            btnClearBoard.label = "Clear Board";      

            addChild(btnClearBoard);

            btnClearBoard.addEventListener(MouseEvent.CLICK, clearBoard);
		}
	}
}

Posted in APE - Actionscript Physics Engine, Actionscript 3.


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.