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.

*_*

Post a Comment

2 Comments

  1. 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?

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

    thank you

    ReplyDelete

Thanks for sharing your thoughts !