/// <summary> /// Shows the current screen state /// TODO: make the draw functions return the differences, and add an enum so there can be different ways to show /// </summary> /// <param name="compareWithLast">Should it compare to the last screen to improve performance</param> public void Show(bool compareWithLast = true) { // If the the flag was left on if (compareWithLast) { // Gets the differences from the current and last map state List <Tuple <int, int> > differenceList = ConsoleBlockMap.Differences(_Map, _LastMap); int index; // Iterates through each difference foreach (Tuple <int, int> difference in differenceList) { for (index = difference.Item1; index < difference.Item2; index++) { // And updates only the different blocks from the screen Console.SetCursorPosition(index % _Map.Width, index / _Map.Width); _Map[index].Show(); } } } // If it was NOT else { // Then get yourself ready Console.SetCursorPosition(0, 0); // For the lag _Map.Show(); } // Updates the last map state _LastMap.CopyFrom(_Map); }
/// <summary> /// Creates a new console screen manager /// </summary> /// <param name="width">Screen width</param> /// <param name="height">Screen height</param> public ConsoleScreen(int width, int height) { // Increases the height to avoid annoying screen scrollings // TODO: figure out a way to avoid screen scrolling without having to do this ++height; // Sets the screen size Console.SetWindowSize(width, height); Console.SetBufferSize(width, height); // Hides the ugly cursor Console.CursorVisible = false; // Restores the given height --height; // Creates a map for drawing _Map = new ConsoleBlockMap(width, height); _LastMap = _Map.Clone; // Prints it entirely on the console Show(false); }
/// <summary> /// Draws a map on the screen /// </summary> /// <param name="offsetX">Horizontal offset</param> /// <param name="offsetY">Vertical offset</param> /// <param name="map">Map to be drawn</param> /// <param name="function">Function that merges the blocks</param> public void DrawMap( int offsetX, int offsetY, ConsoleBlockMap map, Func < int, int, int, ConsoleBlock, int, int, int, ConsoleBlock, ConsoleBlock > function = null ) { if (function == null) { function = Utils.BlockJustReplaceIfNotEmpty; } _Map.Merge(offsetX, offsetY, map, function); }
/// <summary> /// Clears the screen with a given background /// </summary> /// <param name="background">Background</param> public void Clear(ConsoleBlockMap background) { _Map.CopyFrom(background); }
/// <summary> /// Turns a string into a console block map /// </summary> /// <param name="input">Source string</param> /// <param name="function">Function that generates the blocks</param> /// <returns></returns> public static ConsoleBlockMap FromString( string input, Func < int, // Line character index int, // Line index int, // Map index char, // Line character bool, // Is this character a padding character ConsoleBlock // Generated block > function ) { // Saves the string length for later use int inputLength = input.Length; // It's necessary to check if the source string is not empty if (inputLength == 0) { // Because if it is, it's not possible to create a map out of it throw new ArgumentException(); } // Get some more variables declared for later use char inputChar; StringBuilder stringBuilder = new StringBuilder(); string line; List <string> lineList = new List <string>(); int lineLength = 0; int x; int y; int mapWidth = 0; int mapHeight = 0; ConsoleBlockMap output; // To avoid having the same exact code at two spots, an action was declared to make the code pretty Action endLine = () => { // This function basically gets the completely built line line = stringBuilder.ToString(); // And if it's size is bigger than the biggest one if (lineLength > mapWidth) { // Updates the map width mapWidth = lineLength; } // Increases the map height, so there's space for the next line ++mapHeight; // Saves the built line to the list lineList.Add(line); // Clears the buffer from the builder stringBuilder.Clear(); }; // Iterates through the text for (x = 0; x < inputLength; x++) { // Gets the current text character inputChar = input[x]; // If it's a "break line" character if (inputChar == '\n') { // Then just go to the next line endLine(); // Resets the line length to 0 lineLength = 0; } // If it's not a "break line" else { // Then build the line stringBuilder.Append(inputChar); // And increases the line length ++lineLength; } } // It may happen that a line goes all the way to the end, so the action is called again to make sure nothing is missing endLine(); // Now that the required map size is known, creates it output = new ConsoleBlockMap(mapWidth, mapHeight); // And start filling it for (y = 0; y < mapHeight; y++) { // Goes through each line and get their length line = lineList[y]; lineLength = line.Length; // Goes through each character of each line for (x = 0; x < mapWidth; x++) { // Not all line shave the same size, so if the current character index is in the line length limit if (x < lineLength) { // Then just generate a block normally output[x, y] = function(x, y, x + y * mapWidth, line[x], false); } // If it's beyond that limit else { // Then just generate a padding block output[x, y] = function(x, y, x + y * mapWidth, ' ', true); } } } // Returns the completely filled console block map return(output); }