23 August 2010

AS3 Elevator System Simulation

I continue to rewrite older code to AS3. In April last year I posted small chunk of AS2 code needed for Elevator system simulation. This time AS3 version is much better and you can test it by yourself. Click on gray square buttons to call the elevator. While elevator is moving click on more buttons and check calling queue info.



When elevator reaches destination (callingQueue[0] element) it stops for a while; waits for people to come in :) then deletes that floor call and goes to next call. Just like in real life, at least like elevator in my building works.

Here is the code (CC license):

/*
* Elevator Simulation
* @author: http://flanture.blogspot.com
* @date: August 2010
* @license: Creative Commons Attribution-NonCommercial-ShareAlike 3.0
* ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
*/

/**
* Imports
*/

import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;

/**
* Variables
*/

var _numberOfFloors:uint = 6;
var _callingQueue:Array = new Array();
var _btnsArray:Array = new Array();
var _buildingGroundX:uint = 75;
var _buildingGroundY:uint = 350;
var _floorHeight:uint = 50;
var _currFloor:uint = 1;
var _waitSemaphore:Boolean = false;
var _waitCounter:int = 40;

/**
* Functions
*/

function startSimulation():void
{
currentFloorTF.text = _currFloor;
drawBuilding();
}

function drawBuilding():void
{
// add building and calling buttons
for(var i:uint = 0; i < _numberOfFloors; i++)
{
var floor:floorMC = new floorMC();
floor.x = _buildingGroundX;
floor.y = _buildingGroundY-(_floorHeight*i);
addChild(floor);

var bellBtn:bell = new bell();

// to which floor button is added
bellBtn.fn = i+1;
bellBtn.x = _buildingGroundX + 200;
bellBtn.y = _buildingGroundY-(_floorHeight*i)-10;
addChild(bellBtn);

bellBtn.addEventListener(Event.ENTER_FRAME, bellOnFrame);
function bellOnFrame(evt:Event):void
{
evt.target.stop();
}
bellBtn.addEventListener(MouseEvent.MOUSE_UP, bellOnUp);
function bellOnUp(evt:MouseEvent):void
{
if(evt.target.currentFrame == 1) {

// if elevator is working check if it can stop by
if (_callingQueue.length > 0)
{
var test:Boolean = isBetween(evt.target.fn, _currFloor,

_callingQueue[0]);

// if elevator can stop, add this floor to queue
if (test)
{
_callingQueue.splice(0, 0, evt.target.fn);
evt.target.gotoAndStop(2);
queueTF.text = _callingQueue;
} else {

var queueCounter:int = 0;
while (queueCounter < _callingQueue.length-1)
{
if (isBetween(evt.target.fn, _callingQueue

[queueCounter], _callingQueue[queueCounter+1]))
{
_callingQueue.splice

(queueCounter+1, 0, evt.target.fn);
queueCounter =

_callingQueue.length;
evt.target.gotoAndStop(2);
queueTF.text = _callingQueue;

} else {
queueCounter += 1;
}
}
if (queueCounter < _callingQueue.length)
{
_callingQueue.push(evt.target.fn);
evt.target.gotoAndStop(2);
queueTF.text = _callingQueue;
}
}
} else {

// if queue is empty add to queue if it's not same floor

if (!(evt.target.fn == _currFloor))
{
evt.target.gotoAndStop(2);

// update queue
_callingQueue.push(evt.target.fn);
queueTF.text = _callingQueue;
}
}
}
}
_btnsArray.push(bellBtn);
}

// add elevator
var elevator:elevatorMC = new elevatorMC;
elevator.x = _buildingGroundX + 50;
elevator.y = _buildingGroundY;
addChild(elevator);

elevator.addEventListener(Event.ENTER_FRAME, elevatorOnFrame);
function elevatorOnFrame(evt:Event):void
{
// if queue is not empty elevator should move
if (_callingQueue.length > 0)
{
// check if elevator needs to wait for a while
if((_waitSemaphore)&&(_waitCounter > 0))
{
_waitCounter -= 1;
if(_waitCounter == 0)
{
_waitSemaphore = false;
_waitCounter = 40;
}
} else {

// find current elevator floor
_currFloor = 1+Math.floor((_buildingGroundY-evt.target.y)/_floorHeight);

// elevator goes up
if (_callingQueue[0] > _currFloor)
{
evt.target.y -= 2;
}

// elevator goes down
if (_callingQueue[0] < _currFloor)
{
evt.target.y += 2;
}

// if elevator reached destination stop it and change variables
if (_callingQueue[0] == _currFloor)
{
if(evt.target.y < _buildingGroundY-(_currFloor-1)*_floorHeight)
{
evt.target.y += 2;
} else {
evt.target.y = _buildingGroundY-(_currFloor-1)

*_floorHeight;
var temp:uint = _callingQueue.splice(0, 1);
_btnsArray[_currFloor-1].gotoAndStop(1);
queueTF.text = _callingQueue;
_waitSemaphore = true;
}
}
currentFloorTF.text = _currFloor;
}
}
}
}

function isBetween(caller:int, currentPosition:int, destination:int):Boolean
{
if ( ( (caller < destination)&&(caller > currentPosition) )||
( (caller < currentPosition)&&(caller > destination) ) ) {
return true;
} else {
return false;
}
}

startSimulation();



Source file and additional help available via email request. I hope you find this useful.

*_*

2 comments:

NAS said...

This is such an awesome simulation! Hi, I wanted to request the source file for this, but can't locate your email address. Could I have your email address please?

flanture said...

send your request via flanture at gmail dot com or simply use online form at http://kontactr.com/user/flanture

thank you

 

template by blogger templates