bekovski

sg04_workingCpy2

Jun 1st, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.82 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. using System.Text.RegularExpressions;
  6.  
  7. public class LevelManager : MonoBehaviour {
  8.  
  9.     // singleton
  10.     public static LevelManager instance;
  11.  
  12.     // file prefix
  13.     private readonly string prefix = "Assets/Levels/";
  14.  
  15.     // player prefab
  16.     public Transform pacman;
  17.  
  18.     // player coods
  19.     int pacmanX;
  20.     int pacmanZ;
  21.  
  22.     // enemy prefabs
  23.     public Transform blinky;
  24.     public Transform pinky;
  25.     public Transform inky;
  26.     public Transform clyde;
  27.  
  28.     // enemy coords
  29.     int blinkyX;
  30.     int blinkyZ;
  31.     int pinkyX;
  32.     int pinkyZ;
  33.     int inkyX;
  34.     int inkyZ;
  35.     int clydeX;
  36.     int clydeZ;
  37.  
  38.     // tiles
  39.     public Transform corridor;
  40.     public Transform corner;
  41.     public Transform cross;
  42.     public Transform tCross;
  43.     public Transform deadEnd;
  44.  
  45.     // corresponding strings
  46.     readonly char sCorridorHorizontal = '-';
  47.     readonly char sCorridorVertical = '|';
  48.     readonly char sCross = '+';             // could be cross or tCross or corner
  49.  
  50.     // the level as a string
  51.     private List<string> level = new List<string> ();
  52.     private bool isReady;
  53.  
  54.     // a struct that helps setting the wayPoints
  55.     struct WayPointData {
  56.         public Transform tile;
  57.         public bool goUp;
  58.         public bool goDown;
  59.         public bool goLeft;
  60.         public bool goRight;
  61.     };
  62.     WayPointData[,] wayPointDataArray;  // 2D array
  63.     int rows = 0;                       // final # of rows
  64.     int cols = -1;                      // final # of columns
  65.     int r = 0;                          // row idx  (needed when filling in the array)
  66.     int c = 0;                          // col idx  (needed when filling
  67.  
  68.     // instantiated objects
  69.     List<Transform> createdTiles = new List<Transform>();
  70.     List<Transform> createdCharacters = new List<Transform>();
  71.  
  72.     void Awake() {
  73.         instance = this;
  74.     }
  75.  
  76.     void Update() {
  77.         if(isReady) {
  78.             wayPointDataArray = new WayPointData[rows, cols];
  79.             CreateLevel ();
  80.             SetWayPoints ();
  81.             SetAndInstantiateCharacters ();
  82.             isReady = false;
  83.         }
  84.     }
  85.  
  86.     /// <summary>
  87.     /// Reads the file. In doing so, it also destroys the current level and creates the data necessary for the new level.
  88.     /// While reading the file, syntax and semantic checks are done as well.
  89.     /// </summary>
  90.     /// <param name="fileName">File name.</param>
  91.     public void ReadFile(string fileName) {
  92.         Destroy ();
  93.  
  94.         string text = System.IO.File.ReadAllText (prefix + fileName);
  95.         SyntaxChecker.instance.errorMsg.text = "";
  96.         SemanticsChecker.instance.errorMsg.text = "";
  97.  
  98.         if(!SyntaxChecker.instance.IsSyntacticallyCorrect (text)) {
  99.             SyntaxChecker.instance.errorMsg.text = "Syntax Error!";
  100.             return;
  101.         }
  102.  
  103.         level.Clear ();
  104.         List<string> lines = new List<string>(Regex.Split (text, "\n"));
  105.  
  106.         rows = 0;
  107.         cols = -1;
  108.         r = 0;
  109.         c = 0;
  110.  
  111.         for(int i=0; i < lines.Count; ++i) {
  112.             string currentLine = lines[i].Trim();
  113.             string[] currentLineSplit = Regex.Split (currentLine, " ");
  114.  
  115.             // important note #1: we have to invert the provided z-value as the level grows downward but the z-axis points upward
  116.             // important note #2: the x-value is to be used in the 2nd dimension of the level-array (-> columns!)
  117.             // important note #3: as the z-value will be negative, we have to invert it again when accessing the level-array later on
  118.  
  119.             switch(currentLineSplit[0]) {
  120.             case "Pacman":
  121.                 pacmanX = int.Parse (currentLineSplit [1]);
  122.                 pacmanZ = -int.Parse (currentLineSplit [2]);
  123.                 break;
  124.             case "Blinky":
  125.                 blinkyX = int.Parse (currentLineSplit [1]);
  126.                 blinkyZ = -int.Parse (currentLineSplit [2]);
  127.                 break;
  128.             case "Pinky":
  129.                 pinkyX = int.Parse (currentLineSplit [1]);
  130.                 pinkyZ = -int.Parse (currentLineSplit [2]);
  131.                 break;
  132.             case "Inky":
  133.                 inkyX = int.Parse (currentLineSplit [1]);
  134.                 inkyZ = -int.Parse (currentLineSplit [2]);
  135.                 break;
  136.             case "Clyde":
  137.                 clydeX = int.Parse (currentLineSplit [1]);
  138.                 clydeZ = -int.Parse (currentLineSplit [2]);
  139.                 break;
  140.             default:
  141.                 // else it must be some level object
  142.                 level.Add (currentLine);
  143.                 rows++;
  144.                 if(cols == -1) {
  145.                     // assumes that each row is of the same length
  146.                     cols = currentLine.Length;
  147.                 }
  148.                 break;
  149.             } // switch()
  150.         } // for()
  151.            
  152.         if(!SemanticsChecker.instance.IsSemanticallyCorrect (lines, rows, cols)) {
  153.             SemanticsChecker.instance.errorMsg.text = "Semantics Error!";
  154.             return;
  155.         }
  156.  
  157.         isReady = true;
  158.     } // ReadFile()
  159.        
  160.  
  161.     /// <summary>
  162.     /// Destroys the level and the characters.
  163.     /// </summary>
  164.     void Destroy() {
  165.         foreach(Transform character in createdCharacters) {
  166.             if(character != null) {
  167.                 Destroy (character.gameObject);
  168.             }
  169.         }
  170.  
  171.         foreach(Transform tile in createdTiles) {
  172.             if(tile != null) {
  173.                 Destroy (tile.gameObject);
  174.             }
  175.         }
  176.  
  177.         createdCharacters.Clear ();
  178.         createdTiles.Clear ();
  179.     }
  180.        
  181.  
  182.     /// <summary>
  183.     /// Creates the level by instantiating the tiles in the correct position and rotation.
  184.     /// </summary>
  185.     void CreateLevel() {
  186.         float startX = 0f;
  187.  
  188.         float x = startX;
  189.         float y = 0f;
  190.         float z = 0f;
  191.  
  192.         Transform tile;
  193.  
  194.         for(int i=0; i < level.Count; ++i) {
  195.             for(int j=0; j < level[i].Length; ++j) {
  196.                 Vector3 vec = new Vector3 (x, y, z);
  197.  
  198.  
  199.                 if(level[i][j] == sCorridorHorizontal) {
  200.                     bool isDeadEndLeft  = (j == 0) || level[i][j-1] == sCorridorVertical;
  201.                     bool isDeadEndRight = (j == level[i].Length-1) || level[i][j+1] == sCorridorVertical;
  202.  
  203.                     if(isDeadEndLeft) {
  204.                         tile = InstantiateWithRotationAndCreateWayPointData(deadEnd, vec, -90f, false, false, false, true);
  205.                         createdTiles.Add (tile);
  206.                     }
  207.                     else if(isDeadEndRight) {
  208.                         tile = InstantiateWithRotationAndCreateWayPointData(deadEnd, vec, 90f, false, false, true, false);
  209.                         createdTiles.Add (tile);
  210.                     }
  211.                     else {
  212.                         tile = InstantiateWithRotationAndCreateWayPointData(corridor, vec, 90f, false, false, true, true);
  213.                         createdTiles.Add (tile);
  214.                     }
  215.  
  216.                 }
  217.                 else if(level[i][j] == sCorridorVertical) {
  218.                     bool isDeadEndUp    = (i == 0) || level[i-1][j] == sCorridorHorizontal;
  219.                     bool isDeadEndDown  = (i == level.Count-1) || level[i+1][j] == sCorridorHorizontal;
  220.  
  221.                     if(isDeadEndUp) {
  222.                         tile = InstantiateWithRotationAndCreateWayPointData(deadEnd, vec, 0f, false, true, false, false);
  223.                         createdTiles.Add (tile);
  224.                     }
  225.                     else if(isDeadEndDown) {
  226.                         tile = InstantiateWithRotationAndCreateWayPointData(deadEnd, vec, 180f, true, false, false, false);
  227.                         createdTiles.Add (tile);
  228.                     }
  229.                     else {
  230.                         tile = InstantiateWithRotationAndCreateWayPointData(corridor, vec, 0f, true, true, false, false);
  231.                         createdTiles.Add (tile);
  232.                     }
  233.                 }
  234.  
  235.                 char empty = ' ';
  236.                 if(level[i][j] == sCross) {
  237.                     char up     = ((i - 1) >= 0)                ? level [i - 1] [j] : empty;
  238.                     char down   = ((i + 1) < level.Count)       ? level [i + 1] [j] : empty;
  239.                     char left   = ((j - 1) >= 0)                ? level [i] [j - 1] : empty;
  240.                     char right  = ((j + 1) < level [i].Length)  ? level [i] [j + 1] : empty;
  241.  
  242.                     bool isLeftTopCorner        = (up == empty && left == empty && right != empty && down != empty);
  243.                     bool isLeftBottomCorner     = (up != empty && left == empty && right != empty && down == empty);
  244.                     bool isRightTopCorner       = (up == empty && left != empty && right == empty && down != empty);
  245.                     bool isRightBottomCorner    = (up != empty && left != empty && right == empty && down == empty);
  246.  
  247.                     bool isLeftTCross           = (up != empty && left == empty && right != empty && down != empty);
  248.                     bool isRightTCross          = (up != empty && left != empty && right == empty && down != empty);
  249.                     bool isTopTCross            = (up == empty && left != empty && right != empty && down != empty);
  250.                     bool isBottomTCross         = (up != empty && left != empty && right != empty && down == empty);
  251.  
  252.                     bool isCenterCross          = (up != empty && left != empty && right != empty && down != empty);
  253.  
  254.                     if(isLeftTopCorner) {
  255.                         tile = InstantiateWithRotationAndCreateWayPointData(corner, vec, -90f, false, true, false, true);
  256.                         createdTiles.Add (tile);
  257.                     }
  258.                     else if(isLeftBottomCorner) {
  259.                         tile = InstantiateWithRotationAndCreateWayPointData(corner, vec, 180f, true, false, false, true);
  260.                         createdTiles.Add (tile);
  261.                     }
  262.                     else if(isRightTopCorner) {
  263.                         tile = InstantiateWithRotationAndCreateWayPointData(corner, vec, 0f, false, true, true, false);
  264.                         createdTiles.Add (tile);
  265.                     }
  266.                     else if(isRightBottomCorner) {
  267.                         tile = InstantiateWithRotationAndCreateWayPointData(corner, vec, 90f, true, false, true, false);
  268.                         createdTiles.Add (tile);
  269.                     }
  270.                     else if(isLeftTCross) {
  271.                         tile = InstantiateWithRotationAndCreateWayPointData(tCross, vec, 0f, true, true, false, true);
  272.                         createdTiles.Add (tile);
  273.                     }
  274.                     else if(isRightTCross) {
  275.                         tile = InstantiateWithRotationAndCreateWayPointData(tCross, vec, 180f, true, true, true, false);
  276.                         createdTiles.Add (tile);
  277.                     }
  278.                     else if(isTopTCross) {
  279.                         tile = InstantiateWithRotationAndCreateWayPointData(tCross, vec, 90f, false, true, true, true);
  280.                         createdTiles.Add (tile);
  281.                     }
  282.                     else if(isBottomTCross) {
  283.                         tile = InstantiateWithRotationAndCreateWayPointData(tCross, vec, -90f, true, false, true, true);
  284.                         createdTiles.Add (tile);
  285.                     }
  286.                     else if(isCenterCross) {
  287.                         tile = InstantiateWithRotationAndCreateWayPointData(cross, vec, 0f, true, true, true, true);
  288.                         createdTiles.Add (tile);
  289.                     }
  290.                 }
  291.  
  292.                 x += 1f;    // advance to the right
  293.             } // for(j)
  294.             z -= 1f;        // advance down
  295.             x = startX;     // start from the left
  296.         } // for(i)
  297.     } // CreateLevel()
  298.  
  299.  
  300.     /// <summary>
  301.     /// Instantiates the given Transform object (a tile) at position 'vec', rotated by 'deg' degrees.
  302.     /// The boolean parameters are used to store the necessary information to create the WayPoint data for each tile later on.
  303.     /// </summary>
  304.     /// <returns>The instantiated object at position 'vec', rotated by 'deg' degrees.</returns>
  305.     /// <param name="obj">The Transform to be instantiated.</param>
  306.     /// <param name="vec">The Position at which the object is instantiated.</param>
  307.     /// <param name="deg">The degree by which the object is rotated.</param>
  308.     /// <param name="goUp">If set to <c>true</c> it's possible to go up.</param>
  309.     /// <param name="goDown">If set to <c>true</c> it's possible to go down.</param>
  310.     /// <param name="goLeft">If set to <c>true</c> it's possible to go left.</param>
  311.     /// <param name="goRight">If set to <c>true</c> it's possible to go right.</param>
  312.     Transform InstantiateWithRotationAndCreateWayPointData(Transform obj, Vector3 vec, float deg, bool goUp, bool goDown, bool goLeft, bool goRight) {
  313.         Vector3 rot = obj.transform.eulerAngles;
  314.         rot = new Vector3 (rot.x, rot.y + deg, rot.z);
  315.         Transform result = Instantiate (obj, vec, Quaternion.Euler (rot));
  316.  
  317.         WayPointData temp;
  318.         temp.tile = result;
  319.         temp.goUp = goUp;
  320.         temp.goDown = goDown;
  321.         temp.goLeft = goLeft;
  322.         temp.goRight = goRight;
  323.  
  324.         if(r < rows && c < cols) {
  325.             wayPointDataArray [r, c++] = temp;
  326.  
  327.             if(c == cols) {
  328.                 r++;
  329.                 c = 0;
  330.             }
  331.         }
  332.  
  333.         return result;
  334.     } // InstantiateWithRotationAndCreateWayPointData()
  335.  
  336.     /// <summary>
  337.     /// Sets the way points of each tile in the level.
  338.     /// </summary>
  339.     void SetWayPoints() {
  340.         // map
  341.         for(int i=0; i < rows; ++i) {
  342.             for(int j=0; j < cols; ++j) {
  343.                 WayPointData temp = wayPointDataArray [i, j];
  344.                 Transform obj = temp.tile;
  345.  
  346.                 if(obj != null) {
  347.                     WayPoint wp = obj.GetComponent<WayPoint> ();
  348.                     if(temp.goUp) {
  349.                         wp.upWaypoint = wayPointDataArray [i - 1, j].tile.GetComponent<WayPoint> ();
  350.                     }
  351.                     if(temp.goDown) {
  352.                         wp.downWaypoint = wayPointDataArray [i + 1, j].tile.GetComponent<WayPoint> ();
  353.                     }
  354.                     if(temp.goLeft) {
  355.                         wp.leftWaypoint = wayPointDataArray [i, j - 1].tile.GetComponent<WayPoint> ();
  356.                     }
  357.                     if(temp.goRight) {
  358.                         wp.rightWaypoint = wayPointDataArray [i, j + 1].tile.GetComponent<WayPoint> ();
  359.                     }
  360.                 }
  361.             } // for(j)
  362.         } // for(i)
  363.     } // SetWayPoints()
  364.  
  365.  
  366.     /// <summary>
  367.     /// Sets the necessary data (currentWayPoint and position) of each character and instantiates them.
  368.     /// </summary>
  369.     void SetAndInstantiateCharacters() {
  370.         int x;
  371.         int z;
  372.         Transform tile;
  373.         WayPoint wp;
  374.         Transform character;
  375.  
  376.         x = pacmanX;
  377.         z = -pacmanZ;
  378.         tile = wayPointDataArray [z, x].tile;
  379.         if(tile != null) {
  380.             wp = tile.GetComponent<WayPoint> ();
  381.             pacman.GetComponent<PlayerControlScript> ().currentWaypoint = wp;
  382.             character = Instantiate (pacman, new Vector3 (pacmanX, pacman.transform.position.y, pacmanZ), Quaternion.identity);
  383.             createdCharacters.Add (character);
  384.         }
  385.  
  386.         x = blinkyX;
  387.         z = -blinkyZ;
  388.         tile = wayPointDataArray [z, x].tile;
  389.         if(tile != null) {
  390.             wp = tile.GetComponent<WayPoint> ();
  391.             blinky.GetComponent<EnemyBehaviourScript> ().currentWaypoint = wp;
  392.             character = Instantiate (blinky, new Vector3 (blinkyX, blinky.transform.position.y, blinkyZ), Quaternion.identity);
  393.             createdCharacters.Add (character);
  394.         }
  395.  
  396.         x = pinkyX;
  397.         z = -pinkyZ;
  398.         tile = wayPointDataArray [z, x].tile;
  399.         if(tile != null) {
  400.             wp = tile.GetComponent<WayPoint> ();
  401.             pinky.GetComponent<EnemyBehaviourScript> ().currentWaypoint = wp;
  402.             character = Instantiate (pinky, new Vector3 (pinkyX, pinky.transform.position.y, pinkyZ), Quaternion.identity);
  403.             createdCharacters.Add (character);
  404.         }
  405.  
  406.         x = inkyX;
  407.         z = -inkyZ;
  408.         tile = wayPointDataArray [z, x].tile;
  409.         if(tile != null) {
  410.             wp = tile.GetComponent<WayPoint> ();
  411.             inky.GetComponent<EnemyBehaviourScript> ().currentWaypoint = wp;
  412.             character = Instantiate (inky, new Vector3 (inkyX, inky.transform.position.y, inkyZ), Quaternion.identity);
  413.             createdCharacters.Add (character);
  414.         }
  415.  
  416.         x = clydeX;
  417.         z = -clydeZ;
  418.         tile = wayPointDataArray [z, x].tile;
  419.         if(tile != null) {
  420.             wp = tile.GetComponent<WayPoint> ();
  421.             clyde.GetComponent<EnemyBehaviourScript> ().currentWaypoint = wp;
  422.             character = Instantiate (clyde, new Vector3 (clydeX, clyde.transform.position.y, clydeZ), Quaternion.identity);
  423.             createdCharacters.Add (character);
  424.         }
  425.     } // SetAndInstantiateCharacters()
  426. }
Advertisement
Add Comment
Please, Sign In to add comment