GameWorld.as – Game World Display


// Authors: Team 2: Andrew Bertino, Aaron Sagan, Matt Bloise, Michael Luongo
// Email: abertino@fiea.ucf.edu, asagan@fiea.ucf.edu, mbloise@fiea.ucf.edu, mluongo@fiea.ucf.edu
// File: GameWorld.as
// parses in selected stage objects and initalizes controls.

package
{
     import net.flashpunk.Entity;
     import net.flashpunk.FP;
     import net.flashpunk.graphics.Text;
     import net.flashpunk.World;
     import net.flashpunk.utils.Input;
     import net.flashpunk.utils.Key;
     import flash.geom.Point;
     import net.flashpunk.Sfx;
     import flash.xml.XMLNode;
     import net.flashpunk.graphics.Backdrop;
     import Sounds;

     public class GameWorld extends World
     {
          // Member variables
          private var warlord:Warlord; 
          private var gameOverScreen:GameOver = new GameOver;
          private var gameWinScreen:GameWin = new GameWin;
          private var gameWinText:GameWinText;
          private var handCursorRef:HandCursor;
          private var gameIsFinished:Boolean = false;
          private var manUnitsUsed:uint = 0;
          private var maxGuards:uint = 999;
          private var gameOverBeingDisplayed:Boolean = false;
          public var totalManUnits:Number = 0;
          private var levelOneManUnitsCount:uint = 0;
          private var levelTwoManUnitsCount:uint = 0;
          public static var levelHeight:Number = 0;
          public static var spawnType:uint = 1;
          private var currentLevel:uint = 1;
          private var orderingUnitsLeft:Boolean = false;
          private var orderingUnitsRight:Boolean = false;
          private var warlordCamEnabled:Boolean = false;
          private var levelTransitioning:Boolean = false;
          private var endLevelCounter:uint = 0;
          private var initials:InputInitials = new InputInitials;
          private var initHeader:InitialsHeader = new InitialsHeader;
     
          //Sound Variables
          private var BGM:Sfx = new Sfx(Sounds.BGM);
          private var DEFEAT:Sfx = new Sfx (Sounds.DEFEAT);
          private var VICTORY:Sfx = new Sfx (Sounds.VICTORY);
          
          // Embeds
          [Embed(source = "../assets/levels/manunitslevel3.oel", mimeType = "application/octet-stream")]
          private static const LEVEL_01:Class;
          [Embed(source = "../assets/levels/manunitslevel2.oel", mimeType = "application/octet-stream")]
          private static const LEVEL_02:Class;
          [Embed(source = "../assets/levels/manunitslevel4.oel", mimeType = "application/octet-stream")]
          private static const LEVEL_03:Class;
          
          //globals
          private static const ORDER_MOVEMENT_DISTANCE:uint = 90;
          private static const GUARDS_PER_BARRACKS:uint = 6;
          public static const HEALTH_BAR_DISTANCE_FROM_UNIT:uint = 30;
          public static var CAMERA_START:Number = 0;
          public static var CAMERA_OFFSET:Number = 632;
          public static var TURN_OFF_HUD_SELECTING:Boolean = false;
          
          //random numbers for deciding units going left/right, global, avoided using flashpunk for being "not random enough"
          public static var MINIMUM:int = 1;
          public static var MAXIMUM:int = 2;
          
          public function GameWorld()
          {
               //World constructor - nothing to do here; use begin() instead
               //FP.console.enable();
          }
          
          override public function begin():void
          {
               //trace("Hello World!");
               getTheLevel();
               
               BGM.loop(0.03);
               
               //sets the camera at the bottom of the level
               CAMERA_START = levelHeight - CAMERA_OFFSET;
               FP.camera.y = CAMERA_START;
               
               //Place a test object
               //add(new Barracks(new Point(650, 1730), this));
               
               gameWinText = new GameWinText(this);
          }

          override public function update():void
          {
               
               super.update();
               
               ///////FUNCTIONS EVERY FRAME///////
               
               if (levelTransitioning == false)
               {
                    checkForInput();
                    
                    controlCameraScrolling();
                    
                    if ( (warlord) && (warlord.getDeathState()) )
                    {
                         //Warlord dead
                         gameOver();
                    }
                    
                    if (endLevelCounter > 0)
                    {
                         endLevelCounter--;
                         
                         if (endLevelCounter == 1)
                         {
                              endLevel();
                         }
                    }
               }
               
               ///////END FUNCTIONS EVERY FRAME///////
          }
          
          private function controlCameraScrolling():void
          {
               if (warlordCamEnabled == false)
               {
                    if (Input.mouseY < 110)
                    {
                         //Move camera up (shifts everything down)
                         //Extra cam movement closer to edge
                         if (Input.mouseY < 50) { FP.camera.y -= Math.abs(Input.mouseY - 100) / 32; }
                         if (Input.mouseY < 20) { FP.camera.y -= Math.abs(Input.mouseY - 100) / 24; }
                         
                         FP.camera.y -= Math.abs(Input.mouseY - 100) / 40;
                         
                         if (FP.camera.y <= 0)
                         {
                              FP.camera.y = 0;
                         }
                    }
                    else if (Input.mouseY > 490)
                    {
                         if (Input.mouseY > 550) { FP.camera.y += Math.abs(Input.mouseY - 100) / 120; }
                         if (Input.mouseY > 580) { FP.camera.y += Math.abs(Input.mouseY - 100) / 120; }
                         
                         FP.camera.y += Math.abs(Input.mouseY - 100) / 120;
                         
                         if (FP.camera.y > CAMERA_START) 
                         { 
                              FP.camera.y = CAMERA_START; 
                         }
                    }
               }
               else
               {
                    if (warlord)
                    {
                         if (warlord.y < levelHeight - (CAMERA_OFFSET / 2))
                         {
                              FP.camera.y = warlord.y - (CAMERA_OFFSET / 2);
                         }
                         
                         if (FP.camera.y <= 0)
                         {
                              FP.camera.y = 0;
                         }
                    }
               }
          }
          
          private function checkForInput():void
          {
               if (TURN_OFF_HUD_SELECTING == false) {
                    
                    //MOUSE
                    if (Input.mousePressed)
                    {
                         //Mouse click
                         createUnit();
                    }
                    //KEYBOARD
                    
                    //Test for reset
                    if (Input.pressed(Key.SPACE))
                    {
                         if (gameOverBeingDisplayed == true)
                         {
                              //Reset
                              removeAll();
                              
                              //Stop playing end music
                              DEFEAT.stop();
                              
                              resetGame();
                         }
                         else
                         {
                              //FOR TESTING PURPOSES ONLY
                              endLevel();
                         }
                    }
                    
                    //Unit movement order keys
                    if (Input.check(Key.Q))
                    {
                         orderingUnitsLeft = true;
                    }
                    else
                    {
                         orderingUnitsLeft = false;
                    }
                    
                    if (Input.check(Key.E))
                    {
                         orderingUnitsRight = true;
                    }
                    else
                    {
                         orderingUnitsRight = false;
                    }
               }
          }
          
          public function currentCursorStatus():int
          {
               //Returns 0 if player not ordering unit movement; 1 for left, 2 for right
               if (orderingUnitsLeft == true && orderingUnitsRight == true)
               {
                    return 0;
               }
               else if (orderingUnitsLeft == true)
               {
                    return 1;
               }
               else if (orderingUnitsRight == true)
               {
                    return 2;
               }
               else
               {
                    return 0;
               }
          }
          
          public function checkForMovementOrder(xPosOfUnit:Number, yPosOfUnit:Number):int
          {
               if ((orderingUnitsLeft == true && orderingUnitsRight == true) || (orderingUnitsLeft == false && orderingUnitsRight == false))
               {
                    //If both order commands are true OR both are false, no orders are to be given
                    return 0;
               }
               
               var distBetweenCursorAndUnit:Number = Math.sqrt( ( handCursorRef.x - xPosOfUnit ) * ( handCursorRef.x - xPosOfUnit ) + ( handCursorRef.y - yPosOfUnit ) * ( handCursorRef.y - yPosOfUnit ) );
               
               if (distBetweenCursorAndUnit <= ORDER_MOVEMENT_DISTANCE)
               {
                    //Cursor is within range and an order is set; now find which order to send
                    if (orderingUnitsLeft == true) { return 1; }
                    else if (orderingUnitsRight == true) { return 2; }
               }

               //If it reaches this point, distance is too far; return no order
               return 0;
          }
          
          private function resetGame():void
          {     
               FP.world = new GameWorld();
               spawnType = 1;
          }
          
          private function createUnit():void
          {
               //Create a health bar that will be sent to the unit being added
               var healthBarToMake:HealthBar = createHealthBar();
               
               if (spawnType == 1)
               {
                    add(new Barbarian(Input.mouseX - 20, healthBarToMake, this));
               }
               else if (spawnType == 2)
               {
                    add(new Destroyer(Input.mouseX - 20, healthBarToMake, this));
               }
               else if (spawnType == 3)
               {
                    add(new Axeman(Input.mouseX - 20, healthBarToMake, this));
               }
               else if ( (spawnType == 4) && (!warlord) )
               {
                    warlord = new Warlord(Input.mouseX - 20, healthBarToMake, this);
                    add(warlord);
                    
                    warlordCamEnabled = true;
                    
                    //Move cam to bottom where warlord is spawning
                    FP.camera.y = CAMERA_START;
                    
                    //Text pop-up type 1 (Warlord released)
                    add(new TextGraphic(1, warlord.x - 120, warlord.y - 150, this));
                    
                    trace ("Warlord Used!");
               }
               
               //Increment man units used
               manUnitsUsed++;
               
               if (manUnitsUsed > 999) { manUnitsUsed = 999; }
               
               // Updates the database to modify the number of man units used by 1
               //Main.myDBComm.modVariable("manUnitsUsed", 1, Main.mainUserID);
          } 
          
          public function createGuard(xLocToSend:Number, yLocToSend:Number):void
          {
               if (super.classCount(BarracksGuard) < maxGuards)
               {
                    var healthBarToMake:HealthBar = createHealthBar(true);
                    
                    add(new BarracksGuard(xLocToSend, yLocToSend, healthBarToMake, this));
               }
               else { trace("Max guards present"); }
               
               calculateMaxGuards();
          }
          
          public function createHealthBar(makeAGreenBar:Boolean = false):HealthBar
          {
               var healthBarToAdd:HealthBar;
               
               if (makeAGreenBar == false)
               {
                    healthBarToAdd = new HealthBar();
               }
               else
               {
                    healthBarToAdd = new HealthBar(true);
               }
               
               add(healthBarToAdd);
               
               return healthBarToAdd;
          }
          
          public function getManUnitCount():uint
          {
               return manUnitsUsed;
          }
          
          public function prepareEndLevel(warlordX:Number, warlordY:Number):void
          {
               //Text pop-up type 2 (Castle penetrated)
               add(new TextGraphic(2, warlordX - 120, warlordY, this));
               
               endLevelCounter = 80;
          }
          
          private function endLevel():void
          {
               //Reset counter
               endLevelCounter = 0;
               
               removeAll();
               
               if (currentLevel == 1)
               {
                    trace("LEVEL ONE ENDING");
                    
                    levelOneManUnitsCount = manUnitsUsed;
                    Main.myDBComm.modVariable("levelOneManUnitsCount", levelOneManUnitsCount, Main.mainUserID);
                    
                    currentLevel++;
                    
                    //Load level 2
                    getTheLevel();
               }
               else if (currentLevel == 2)
               {
                    trace("LEVEL TWO ENDING");
                    
                    levelTwoManUnitsCount = manUnitsUsed - levelOneManUnitsCount;
                    Main.myDBComm.modVariable("levelTwoManUnitsCount", levelTwoManUnitsCount, Main.mainUserID);
                    
                    currentLevel++;
                    
                    //Load level 3
                    getTheLevel();
               }
               else if (currentLevel == 3)
               {
                    trace("LEVEL THREE ENDING");
                    
                    //Store final score
                    totalManUnits = manUnitsUsed;
                    Main.myDBComm.modVariable("totalManUnits", totalManUnits, Main.mainUserID);
                    
                    //Game end
                    endGame();
               }
          }
          
          private function endGame():void
          {
               //Win game here
               add(gameWinScreen);
               add(gameWinText);
               
               //A conditional here would be ideal to determine if the player qualifies for inputting a high score:
               add(initials);
               add(initHeader);
               
               TURN_OFF_HUD_SELECTING = true;
               
               
               // INITIALS CODE HERE JUST NEED A VARIABLE to pass to setVariable
               
               
               // Sets the user intials in the database from the text input
               Main.myDBComm.setVariable("userInitials", "AAA", Main.mainUserID);
               
               BGM.stop();
               VICTORY.play(.75);
               
               gameOverBeingDisplayed = true;
          }
          
          private function getTheLevel():void
          {
               FP.camera.y = CAMERA_START;
               
               warlordCamEnabled = false;

               //Replace HUD pieces that were removed on level end
               add(new HUD);
               add(new HUDTwo);
               add(new HUDTwoText(this));
               
               spawnType = 1;
               warlord = null;
               
               handCursorRef = new HandCursor(this);
               add(handCursorRef);
               
               var dataList:XMLList;
               var dataElement:XML;
               
               var loadLevel:Level;
               
               trace("Loading level " + currentLevel);
               
               //Select which level to load
               if (currentLevel == 1) { loadLevel = Level(add(new Level(LEVEL_01))); }
               else if (currentLevel == 2) { loadLevel = Level(add(new Level(LEVEL_02))); }
               else if (currentLevel == 3) { loadLevel = Level(add(new Level(LEVEL_03))); }
               
               //Load level layers from chosen Ogmo file
               dataList = loadLevel.levelXML.Turret.Turret;
               for each (dataElement in dataList) {
                         add(new Tower(new Point(int(dataElement.@x), int(dataElement.@y))));
                    }
               dataList = loadLevel.levelXML.BrickWall.BrickWall; 
               if (dataList != null) {
                    for each (dataElement in dataList) {
                         add (new Wall(new Point(int(dataElement.@x), int(dataElement.@y))));
                         }
                    }
               dataList = loadLevel.levelXML.BarracksGenerator.BarracksGenerator;
               if (dataList != null) {
                    for each (dataElement in dataList) {
                         add (new Barracks(new Point(int(dataElement.@x), int(dataElement.@y)), this));
                    }
               }
               dataList = loadLevel.levelXML.Itsatrap.Itsatrap;
               if (dataList != null) {
                    for each (dataElement in dataList) {
                         add (new Trap(new Point(int(dataElement.@x), int(dataElement.@y))));
                    }
               }
               dataList = loadLevel.levelXML.TheThroneHouse.TheThroneHouse;
               if (dataList != null) {
                    for each (dataElement in dataList) {
                         add (new ThroneHouse(new Point(int(dataElement.@x), int(dataElement.@y))));
                    }
               }
               
               levelHeight = loadLevel.levelXML.height;
               
               //Begin transition screen
               if (currentLevel == 1) { add(new LevelTransition(1, this)); }
               else if (currentLevel == 2) { add(new LevelTransition(2, this)); }
               else if (currentLevel == 3) { add(new LevelTransition(3, this)); }
          
               levelTransitioning = true;
          }
          
          public function getLevelHeight():Number
          {
               return levelHeight - CAMERA_OFFSET;
          }
          
          public function finishLevelTransition():void
          {
               levelTransitioning = false;
          }
          
          private function calculateMaxGuards():void
          {
               maxGuards = GUARDS_PER_BARRACKS * super.classCount(Barracks);
               //trace("Max guards calculated to be: " + maxGuards);
          }
          
          private function gameOver():void
          {
               if (gameIsFinished == false)
               {
                    trace("You lose!");
                    //removeAll();
                    GameIsFinished = true;
                    DEFEAT.play(.75);
                    BGM.stop();
                    add(gameOverScreen);
                    gameOverBeingDisplayed = true;
               }
          }
          

     }

}