Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using MonoGame.Extended;
- using MonoRogue.Cells;
- using MonoRogue.Entities;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using Myra.Graphics2D.UI;
- using Myra;
- using Microsoft.Xna.Framework.Content;
- using MonoRogue.UI;
- using System.Text.RegularExpressions;
- namespace MonoRogue
- {
- /// <summary>
- /// This is the main type for your game.
- /// </summary>
- public enum Scene { MainMenu, Game };
- public enum Direction { North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest };
- public class Game1 : Game
- {
- private readonly string version = "0.0.0";
- private Scene currentScene;
- private readonly Random rng = new Random();
- private readonly GraphicsDeviceManager graphicsManager;
- private SpriteBatch spriteBatch;
- private RenderTarget2D mapRenderTarget;
- private MapObject cameraTarget;
- private KeyboardState currentKeyboardState;
- private KeyboardState previousKeyboardState;
- private MouseState currentMouseState;
- private MouseState previousMouseState;
- private TextConsole textConsole;
- private Desktop myraDesktop;
- // Managers
- private FactionManager factionManager;
- // Settings
- private bool showDebug;
- // Fonts
- private SpriteFont font_bigblue_12;
- //private SpriteFont font_trenchthin_12;
- // Textures
- private List<Texture2D> NoiseTextures;
- // Maps
- private Map currentMap;
- // Entities
- private Player player;
- public Scene CurrentScene { get => currentScene; set => currentScene = value; }
- public void LoadMap(string mapName)
- {
- currentMap = new Map(graphicsManager.GraphicsDevice ,Content, $"Maps/{mapName}.txt", factionManager);
- if (player == null)
- {
- player = new Player(Content, currentMap.GetRandomEmptyFloor(), new List<Faction> { factionManager.PlayerFaction });
- }
- else
- {
- player.ParentMap = currentMap;
- Cell spawnPoint = currentMap.GetRandomEmptyFloor();
- player.ParentCell = spawnPoint;
- spawnPoint.Entity = player;
- player.X = spawnPoint.X;
- player.Y = spawnPoint.Y;
- }
- currentMap.UpdateCellVisibility(player);
- }
- public Game1()
- {
- graphicsManager = new GraphicsDeviceManager(this)
- {
- PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width,
- PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height,
- PreferMultiSampling = false,
- IsFullScreen = true,
- };
- IsMouseVisible = true;
- Content.RootDirectory = "Content";
- //IsFixedTimeStep = true;
- //TargetElapsedTime = TimeSpan.
- }
- /// <summary>
- /// Allows the game to perform any initialization it needs to before starting to run.
- /// This is where it can query for any required services and load any non-graphic
- /// related content. Calling base.Initialize will enumerate through any components
- /// and initialize them as well.
- /// </summary>
- protected override void Initialize()
- {
- // Add your initialization logic here
- graphicsManager.PreferredBackBufferWidth = 1920;
- graphicsManager.PreferredBackBufferHeight = 1080;
- graphicsManager.ApplyChanges();
- CurrentScene = Scene.Game;
- factionManager = new FactionManager();
- base.Initialize();
- }
- /// <summary>
- /// LoadContent will be called once per game and is the place to load
- /// all of your content.
- /// </summary>
- protected override void LoadContent()
- {
- // Create a new SpriteBatch, which can be used to draw textures
- spriteBatch = new SpriteBatch(GraphicsDevice);
- // Use this.Content to load your game content below
- // Fonts
- font_bigblue_12 = Content.Load<SpriteFont>("Fonts/BigBlue TerminalPlus 12");
- // font_trenchthin_12 = Content.Load<SpriteFont>("Fonts/Trench Thin 12");
- // Procedurally generated textures.
- NoiseTextures = new List<Texture2D>();
- for (int i = 0; i < 32; i++)
- {
- NoiseTextures.Add(TextureUtility.GenerateNoiseTexture(graphicsManager.GraphicsDevice, 16, 16));
- }
- // Map initialization
- LoadMap("pacman");
- // Myra
- MyraEnvironment.Game = this;
- var consolePanel = new Panel();
- var consoleGrid = new Grid
- {
- RowSpacing = 8,
- ColumnSpacing = 8
- };
- var consoleLabel = new Label
- {
- Id = "label",
- Text = ""
- };
- var consoleTextBox = new TextBox()
- {
- };
- textConsole = new TextConsole(consoleLabel, consoleTextBox, "grave.txt", 8);
- consolePanel.Top = (GraphicsDevice.Viewport.Height - 189);
- consolePanel.Width = GraphicsDevice.Viewport.Width;
- consoleGrid.ColumnsProportions.Add(new Proportion(ProportionType.Auto));
- consoleGrid.RowsProportions.Add(new Proportion(ProportionType.Auto));
- consoleTextBox.Top = 168;
- consoleTextBox.Width = GraphicsDevice.Viewport.Width;
- consoleLabel.Width = GraphicsDevice.Viewport.Width;
- consoleGrid.Widgets.Add(consoleLabel);
- consoleGrid.Widgets.Add(consoleTextBox);
- consolePanel.Widgets.Add(consoleGrid);
- // Add it to the desktop
- myraDesktop = new Desktop
- {
- Root = consolePanel,
- // Inform Myra that external text input is available
- // So it stops translating Keys to chars
- HasExternalTextInput = true
- };
- // Provide that text input
- Window.TextInput += (s, a) =>
- {
- myraDesktop.OnChar(a.Character);
- };
- }
- /// <summary>
- /// UnloadContent will be called once per game and is the place to unload
- /// game-specific content.
- /// </summary>
- protected override void UnloadContent()
- {
- // Unload any non ContentManager content here
- }
- /// <summary>
- /// Allows the game to run logic such as updating the world,
- /// checking for collisions, gathering input, and playing audio.
- /// </summary>
- /// <param name="gameTime">Provides a snapshot of timing values.</param>
- protected override void Update(GameTime gameTime)
- {
- /*
- if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
- Exit();
- */
- // Add your update logic here
- UpdateGame(gameTime);
- }
- private void UpdateGame(GameTime gameTime)
- {
- currentMap.UpdateCellVisibility(player);
- cameraTarget = player;
- currentKeyboardState = Keyboard.GetState();
- currentMouseState = Mouse.GetState();
- HandleKeyboardInput();
- HandleMouseInput();
- base.Update(gameTime);
- previousKeyboardState = currentKeyboardState;
- previousMouseState = currentMouseState;
- // Helpers
- void HandleKeyboardInput()
- {
- switch(CurrentScene)
- {
- default:
- case Scene.MainMenu:
- break;
- case Scene.Game:
- foreach (Keys key in currentKeyboardState.GetPressedKeys())
- {
- if (textConsole.MyraTextBox.IsKeyboardFocused == false)
- {
- if (previousKeyboardState.IsKeyUp(key))
- {
- switch (key)
- {
- case Keys.Up:
- case Keys.NumPad8:
- player.MoveDirection(Direction.North);
- currentMap.Tick();
- break;
- case Keys.Down:
- case Keys.NumPad2:
- player.MoveDirection(Direction.South);
- currentMap.Tick();
- break;
- case Keys.Left:
- case Keys.NumPad4:
- player.MoveDirection(Direction.West);
- currentMap.Tick();
- break;
- case Keys.Right:
- case Keys.NumPad6:
- player.MoveDirection(Direction.East);
- currentMap.Tick();
- break;
- case Keys.NumPad9:
- player.MoveDirection(Direction.NorthEast);
- currentMap.Tick();
- break;
- case Keys.NumPad3:
- player.MoveDirection(Direction.SouthEast);
- currentMap.Tick();
- break;
- case Keys.NumPad1:
- player.MoveDirection(Direction.SouthWest);
- currentMap.Tick();
- break;
- case Keys.NumPad7:
- player.MoveDirection(Direction.NorthWest);
- currentMap.Tick();
- break;
- case Keys.NumPad5:
- currentMap.Tick();
- break;
- #if DEBUG
- case Keys.F1:
- showDebug = !showDebug;
- if (showDebug)
- {
- textConsole.Write("\\c[#FFFFFF]Debug ON");
- }
- else
- {
- textConsole.Write("\\c[#FFFFFF]Debug OFF");
- }
- break;
- case Keys.F2:
- if (player.FOVRadius < 255)
- {
- player.FOVRadius = 255;
- textConsole.Write("\\c[#FFFFFF]Farsight ON");
- }
- else
- {
- player.FOVRadius = 8;
- textConsole.Write("\\c[#FFFFFF]Farsight OFF");
- }
- break;
- case Keys.F3:
- if (player.FOVRadius < 255)
- {
- player.FOVRadius = 255;
- foreach(Cell cell in currentMap.CellArray)
- {
- cell.BlocksFOV = false;
- }
- textConsole.Write("\\c[#FFFFFF]Fullsight ON");
- }
- break;
- case Keys.F4:
- Blinky blinky = new Blinky(Content, currentMap.GetCell(12, 14), new List<Faction> { factionManager.EnemyFaction }, player);
- //Pinky pinky = new Pinky(Content, currentMap.GetCell(13, 14), new List<Faction> { factionManager.EnemyFaction }, player);
- //Inky inky = new Inky(Content, currentMap.GetCell(14, 14), new List<Faction> { factionManager.EnemyFaction });
- //Clyde clyde = new Clyde(Content, currentMap.GetCell(15, 14), new List<Faction> { factionManager.EnemyFaction });
- break;
- case Keys.F11:
- graphicsManager.ToggleFullScreen();
- graphicsManager.PreferredBackBufferWidth = GraphicsDevice.Viewport.Width;
- graphicsManager.PreferredBackBufferHeight = GraphicsDevice.Viewport.Height;
- graphicsManager.ApplyChanges();
- break;
- default:
- return;
- #endif
- }
- }
- }
- // Text box is focused
- else
- {
- if (previousKeyboardState.IsKeyUp(key))
- {
- switch (key)
- {
- case Keys.Enter:
- if (textConsole.MyraTextBox.IsKeyboardFocused)
- {
- ParseConsoleCommand(textConsole.MyraTextBox.Text);
- textConsole.MyraTextBox.Text = "";
- }
- break;
- }
- }
- }
- }
- break;
- }
- }
- void HandleMouseInput()
- {
- // TODO
- switch (CurrentScene)
- {
- case Scene.Game:
- break;
- }
- }
- void ParseConsoleCommand(string command)
- {
- if (Regex.IsMatch(command, "^loadmap [a-zA-Z0-9]+$", RegexOptions.IgnoreCase))
- {
- string mapName = command.Split(' ')[1];
- if (System.IO.File.Exists($"Maps/{mapName}.txt"))
- {
- LoadMap(mapName);
- }
- else
- {
- textConsole.Write("\\c[#FFFFFF]Invalid map name");
- }
- }
- else if (Regex.IsMatch(command, "^clear$", RegexOptions.IgnoreCase) || Regex.IsMatch(command, "^cs$", RegexOptions.IgnoreCase))
- {
- textConsole.RecentLines.Clear();
- textConsole.UpdateText();
- }
- else if (Regex.IsMatch(command, "^Get ye flask$", RegexOptions.IgnoreCase))
- {
- textConsole.Write("\\c[#06e50f]You can't get ye flask!");
- }
- else
- {
- textConsole.Write("\\c[#FFFFFF]Syntax error");
- }
- }
- }
- /// <summary>
- /// This is called when the game should draw itself.
- /// </summary>
- /// <param name="gameTime">Provides a snapshot of timing values.</param>
- protected override void Draw(GameTime gameTime)
- {
- float fps = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds;
- switch(CurrentScene)
- {
- default:
- case Scene.MainMenu:
- break;
- case Scene.Game:
- mapRenderTarget = new RenderTarget2D(GraphicsDevice, currentMap.Width * 16, currentMap.Height * 16, false, SurfaceFormat.Color, DepthFormat.None);
- RenderCurrentMap(mapRenderTarget);
- GraphicsDevice.Clear(Color.Black);
- spriteBatch.Begin();
- DrawMap();
- DrawUI();
- DrawText();
- spriteBatch.End();
- spriteBatch.Begin();
- myraDesktop.Render(); // Myra requires a new spriteBatch to draw on top.
- spriteBatch.End();
- base.Draw(gameTime);
- break;
- }
- void DrawMap()
- {
- // Draw map centered on cameraTarget (usually the player)
- spriteBatch.Draw(mapRenderTarget, new Rectangle(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2, currentMap.Width * 16, currentMap.Height * 16),
- null, Color.White, 0f, new Vector2(cameraTarget.X * 16, cameraTarget.Y * 16), SpriteEffects.None, 0f);
- }
- void DrawUI()
- {
- // Cell mouseover highlight
- foreach (Cell c in player.GetVisibleCells())
- {
- if (RenderedCellRectangle(currentMap.CellArray[c.X, c.Y]).Contains(new Point(currentMouseState.X, currentMouseState.Y)))
- {
- spriteBatch.Draw(Content.Load<Texture2D>("Textures/highlight/00"), RenderedCellRectangle(currentMap.CellArray[c.X, c.Y]), Color.White);
- }
- }
- }
- void DrawText()
- {
- // Entity mouseover text
- foreach (Entity e in player.GetVisibleEntities())
- {
- if (RenderedCellRectangle(currentMap.CellArray[e.X, e.Y]).Contains(new Point(currentMouseState.X, currentMouseState.Y)))
- {
- spriteBatch.DrawString(font_bigblue_12, e.Name, new Vector2(currentMouseState.X + 12, currentMouseState.Y), Color.White);
- }
- }
- // Debug information
- if (showDebug == true)
- {
- spriteBatch.DrawString(font_bigblue_12, "FPS = " + (int)(fps + 0.5f), new Vector2(0, font_bigblue_12.LineSpacing * 0), Color.White);
- spriteBatch.DrawString(font_bigblue_12, "Mouse X, Y = " + currentMouseState.X + ", " + currentMouseState.Y, new Vector2(0, font_bigblue_12.LineSpacing * 1), Color.White);
- foreach (Cell c in currentMap.CellArray)
- {
- if (RenderedCellRectangle(currentMap.CellArray[c.X, c.Y]).Contains(new Point(currentMouseState.X, currentMouseState.Y)))
- {
- if (c.Entity != null)
- {
- spriteBatch.DrawString(font_bigblue_12, c.X + ", " + c.Y, new Vector2(currentMouseState.X + 12, currentMouseState.Y + font_bigblue_12.LineSpacing), Color.White);
- }
- else
- {
- spriteBatch.DrawString(font_bigblue_12, c.X + ", " + c.Y, new Vector2(currentMouseState.X + 12, currentMouseState.Y), Color.White);
- }
- }
- }
- }
- }
- void RenderCurrentMap(RenderTarget2D mapRenderTarget)
- {
- // Set the render target
- GraphicsDevice.SetRenderTarget(mapRenderTarget);
- GraphicsDevice.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };
- // Draw the scene
- GraphicsDevice.Clear(Color.Black);
- // Add your drawing code here
- spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp);
- DrawCells();
- DrawItems();
- DrawEntities();
- AdvanceAnimations();
- spriteBatch.End();
- // Drop the render target
- GraphicsDevice.SetRenderTarget(null);
- void DrawCells()
- {
- foreach (Cell cell in currentMap.CellArray)
- {
- float opacity = 1f;
- if (cell.IsExplored)
- {
- opacity = 0.5f;
- }
- if (cell.IsInFOV)
- {
- opacity = 1f;
- }
- if (cell is Cells.Void)
- {
- opacity = 1f;
- spriteBatch.Draw(Content.Load<Texture2D>("Textures/void"), new Rectangle(cell.X * 16, cell.Y * 16, 16, 16), Color.White * opacity);
- }
- if (cell.IsExplored == false && !(cell is Cells.Void))
- {
- spriteBatch.Draw(NoiseTextures[rng.Next(NoiseTextures.Count - 1)], new Rectangle((cell.X * 16), (cell.Y * 16), 16, 16), Color.White * opacity);
- continue;
- }
- else if (cell.CurrentAnimation != null)
- {
- spriteBatch.Draw(cell.CurrentAnimation.CurrentFrame(), new Rectangle(cell.X * 16, cell.Y * 16, 16, 16), Color.White * opacity);
- }
- else if (cell.Texture != null)
- {
- spriteBatch.Draw(cell.Texture, new Rectangle(cell.X * 16, cell.Y * 16, 16, 16), Color.White * opacity);
- }
- else
- {
- spriteBatch.Draw(Content.Load<Texture2D>("Textures/placeholder"), new Rectangle(cell.X * 16, cell.Y * 16, 16, 16), Color.White * opacity);
- }
- }
- }
- void DrawItems()
- {
- foreach (Item item in currentMap.GetAllItems())
- {
- if (item.ParentCell.IsInFOV)
- {
- if (item.CurrentAnimation != null)
- {
- spriteBatch.Draw(item.CurrentAnimation.CurrentFrame(), new Rectangle(item.X * 16, item.Y * 16, 16, 16), Color.White);
- }
- else if (item.Texture != null)
- {
- spriteBatch.Draw(item.Texture, new Rectangle(item.X * 16, item.Y * 16, 16, 16), Color.White);
- }
- else
- {
- spriteBatch.Draw(Content.Load<Texture2D>("Textures/placeholder"), new Rectangle(item.X * 16, item.Y * 16, 16, 16), Color.White);
- }
- }
- }
- }
- void DrawEntities()
- {
- foreach (Entity entity in currentMap.GetAllEntities())
- {
- if (entity.ParentCell.IsInFOV)
- {
- if (entity.CurrentAnimation != null)
- {
- spriteBatch.Draw(entity.CurrentAnimation.CurrentFrame(), new Rectangle(entity.X * 16, entity.Y * 16, 16, 16), Color.White);
- }
- else if (entity.Texture != null)
- {
- spriteBatch.Draw(entity.Texture, new Rectangle(entity.X * 16, entity.Y * 16, 16, 16), Color.White);
- }
- else
- {
- spriteBatch.Draw(Content.Load<Texture2D>("Textures/placeholder"), new Rectangle(entity.X * 16, entity.Y * 16, 16, 16), Color.White);
- }
- }
- }
- }
- void AdvanceAnimations()
- {
- foreach (Cell cell in currentMap.CellArray)
- {
- if (cell.CurrentAnimation != null && (int)gameTime.TotalGameTime.TotalMilliseconds % cell.CurrentAnimation.TimePerFrame == 0)
- {
- cell.CurrentAnimation.AdvanceFrame();
- }
- }
- foreach(Entity entity in currentMap.GetAllEntities())
- {
- if (entity.CurrentAnimation != null && (int)gameTime.TotalGameTime.TotalMilliseconds % entity.CurrentAnimation.TimePerFrame == 0)
- {
- entity.CurrentAnimation.AdvanceFrame();
- }
- }
- }
- }
- /// <summary>
- /// Calculates the final on-screen position of a cell's texture after RenderTarget transformations.
- /// </summary>
- Rectangle RenderedCellRectangle(Cell cell)
- {
- Point center = new Point(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2);
- Point mapTopLeft = new Point(center.X - player.X * 16, center.Y - player.Y * 16);
- Point cellTopLeft = new Point(mapTopLeft.X + cell.X * 16, mapTopLeft.Y + cell.Y * 16);
- return new Rectangle(cellTopLeft, new Point(16, 15));
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement