Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 29.90 KB | None | 0 0
  1. //Game1.cs :
  2. /// <summary>
  3. /// Copyright (c) 2010 Resseguier Valentin
  4. /// All rights reserved.
  5. ///
  6. /// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  7. ///
  8. /// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  9. /// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  10. /// * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  11. ///
  12. /// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13. /// </summary>
  14.  
  15.  
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using Microsoft.Xna.Framework;
  20. using Microsoft.Xna.Framework.Audio;
  21. using Microsoft.Xna.Framework.Content;
  22. using Microsoft.Xna.Framework.GamerServices;
  23. using Microsoft.Xna.Framework.Graphics;
  24. using Microsoft.Xna.Framework.Input;
  25. using Microsoft.Xna.Framework.Media;
  26.  
  27. using IsoRender;
  28.  
  29. namespace Open_RollerCoasterTycoon
  30. {
  31.     /// <summary>
  32.     /// This is the main type for your game
  33.     /// </summary>
  34.     public class Game1 : Microsoft.Xna.Framework.Game
  35.     {
  36.         GraphicsDeviceManager graphics;
  37.         SpriteBatch spriteBatch;
  38.         Texture2D floor;
  39.         Texture2D house;
  40.         Texture2D road;
  41.         Map map;
  42.         int ScreenWidth;
  43.         int ScreenHeight;
  44.         Point Location;
  45.         SpriteFont text;
  46.         float CumulativeFrameTime, currentTime;
  47.         int NumFrames;
  48.         int FramesPerSecond;
  49.         Vector2 PositionMouse;
  50.         Song GameMusic1;
  51.  
  52.         public Game1()
  53.         {
  54.             graphics = new GraphicsDeviceManager(this);
  55.             graphics.IsFullScreen = false;
  56.             graphics.PreferredBackBufferHeight = 768;
  57.             graphics.PreferredBackBufferWidth = 1024;
  58.             IsMouseVisible = true;
  59.             ScreenWidth = graphics.PreferredBackBufferWidth;
  60.             ScreenHeight = graphics.PreferredBackBufferHeight;
  61.             Content.RootDirectory = "Content";
  62.         }
  63.  
  64.         /// <summary>
  65.         /// Allows the game to perform any initialization it needs to before starting to run.
  66.         /// This is where it can query for any required services and load any non-graphic
  67.         /// related content.  Calling base.Initialize will enumerate through any components
  68.         /// and initialize them as well.
  69.         /// </summary>
  70.         protected override void Initialize()
  71.         {
  72.             // TODO: Add your initialization logic here
  73.  
  74.             base.Initialize();
  75.         }
  76.  
  77.         /// <summary>
  78.         /// LoadContent will be called once per game and is the place to load
  79.         /// all of your content.
  80.         /// </summary>
  81.         protected override void LoadContent()
  82.         {
  83.             // Create a new SpriteBatch, which can be used to draw textures.
  84.             spriteBatch = new SpriteBatch(GraphicsDevice);
  85.  
  86.             // TODO: use this.Content to load your game content here
  87.             GraphicsDevice.PresentationParameters.PresentationInterval = PresentInterval.Immediate;
  88.             GraphicsDevice.Reset();
  89.  
  90.             floor = Content.Load<Texture2D>("Map/Texture/Herbe32");
  91.             house = Content.Load<Texture2D>("Object/House/House32");
  92.             road = Content.Load<Texture2D>("Object/Road/Road32");
  93.             /*floor32 = Content.Load<Texture2D>("Map/Texture/Herbe32");
  94.             floor16 = Content.Load<Texture2D>("Map/Texture/Herbe16");
  95.             floor8 = Content.Load<Texture2D>("Map/Texture/Herbe8");*/
  96.             text = Content.Load<SpriteFont>("Text/text");
  97.             GameMusic1 = Content.Load<Song>("Music/GameMusic1");
  98.             MediaPlayer.IsRepeating = true;
  99.             if (MediaPlayer.State == MediaState.Stopped)
  100.                 MediaPlayer.Play(GameMusic1);
  101.         }
  102.  
  103.         /// <summary>
  104.         /// UnloadContent will be called once per game and is the place to unload
  105.         /// all content.
  106.         /// </summary>
  107.         protected override void UnloadContent()
  108.         {
  109.             // TODO: Unload any non ContentManager content here
  110.             MediaPlayer.Stop();
  111.         }
  112.  
  113.         /// <summary>
  114.         /// Allows the game to run logic such as updating the world,
  115.         /// checking for collisions, gathering input, and playing audio.
  116.         /// </summary>
  117.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  118.         protected override void Update(GameTime gameTime)
  119.         {
  120.             // Allows the game to exit
  121.             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  122.                 this.Exit();
  123.  
  124.             // TODO: Add your update logic here
  125.             if (map == null)
  126.             {
  127.                 map = new Map();
  128.                 map.Initialize(40, 40, floor);
  129.                 map.FloorTileWidthHalf = 32;
  130.                 map.FloorTileHeightHalf = 16;
  131.                 MapGrid mg;
  132.                 for (int i = 0; i < map.Width; i++)
  133.                     for (int j = 0; j < map.Height; j++)
  134.                     {
  135.                         mg = map.GetGrid(i, j);
  136.                     }
  137.  
  138.                 Random rnd = new Random();
  139.                 MapObject mo = new MapObject(2, 2, house);
  140.                 mo.Location.X = 38;
  141.                 mo.Location.Y = 17;
  142.                 mo.SetLocation(mo.Location, map);
  143.                 mo = new MapObject(2, 2, road);
  144.                 mo.Location.X = 38;
  145.                 mo.Location.Y = 18;
  146.                 mo.SetLocation(mo.Location, map);
  147.                 mo = new MapObject(2, 2, road);
  148.                 mo.Location.X = 37;
  149.                 mo.Location.Y = 18;
  150.                 mo.SetLocation(mo.Location, map);
  151.                 mo = new MapObject(2, 2, road);
  152.                 mo.Location.X = 36;
  153.                 mo.Location.Y = 18;
  154.                 mo.SetLocation(mo.Location, map);
  155.                 mo = new MapObject(2, 2, road);
  156.                 mo.Location.X = 35;
  157.                 mo.Location.Y = 18;
  158.                 mo.SetLocation(mo.Location, map);
  159.                 mo = new MapObject(2, 2, road);
  160.                 mo.Location.X = 34;
  161.                 mo.Location.Y = 18;
  162.                 mo.SetLocation(mo.Location, map);
  163.             }
  164.  
  165.             if (Keyboard.GetState().IsKeyDown(Keys.Down))
  166.             {
  167.                 Location.X++;
  168.                 Location.Y++;
  169.             }
  170.             else if (Keyboard.GetState().IsKeyDown(Keys.Up))
  171.             {
  172.                 Location.X--;
  173.                 Location.Y--;
  174.             }
  175.             if (Keyboard.GetState().IsKeyDown(Keys.Left))
  176.             {
  177.                 Location.X--;
  178.                 Location.Y++;
  179.             }
  180.             else if (Keyboard.GetState().IsKeyDown(Keys.Right))
  181.             {
  182.                 Location.X++;
  183.                 Location.Y--;
  184.             }
  185.  
  186.             /*if (Keyboard.GetState().IsKeyDown(Keys.Add))
  187.             {
  188.                 if (map.FloorTileWidthHalf == 32)
  189.                 {
  190.                 }
  191.                 else if (map.FloorTileWidthHalf == 8)
  192.                 {
  193.                     floor = Content.Load<Texture2D>("Map/Texture/Herbe16");
  194.                     map.Initialize(40, 40, floor);
  195.                     map.FloorTileWidthHalf = map.FloorTileWidthHalf * 2;
  196.                     map.FloorTileHeightHalf = map.FloorTileHeightHalf * 2;
  197.  
  198.                 }
  199.                 else if (map.FloorTileWidthHalf == 16)
  200.                 {
  201.                     floor = Content.Load<Texture2D>("Map/Texture/Herbe32");
  202.                     map.Initialize(40, 40, floor);
  203.                     map.FloorTileWidthHalf = map.FloorTileWidthHalf * 2;
  204.                     map.FloorTileHeightHalf = map.FloorTileHeightHalf * 2;
  205.                 }
  206.             }
  207.             else if (Keyboard.GetState().IsKeyDown(Keys.Subtract))
  208.             {
  209.                 if (map.FloorTileWidthHalf == 8)
  210.                 {
  211.                 }
  212.                 else if (map.FloorTileWidthHalf == 32)
  213.                 {
  214.                     floor = Content.Load<Texture2D>("Map/Texture/Herbe16");
  215.                     map.Initialize(40, 40, floor);
  216.                     map.FloorTileWidthHalf = map.FloorTileWidthHalf / 2;
  217.                     map.FloorTileHeightHalf = map.FloorTileHeightHalf / 2;
  218.                 }
  219.                 else if (map.FloorTileWidthHalf == 16)
  220.                 {
  221.                     floor = Content.Load<Texture2D>("Map/Texture/Herbe8");
  222.                     map.Initialize(40, 40, floor);
  223.                     map.FloorTileWidthHalf = map.FloorTileWidthHalf / 2;
  224.                     map.FloorTileHeightHalf = map.FloorTileHeightHalf / 2;
  225.                 }
  226.             }*/
  227.  
  228.  
  229.             if (Keyboard.GetState().IsKeyDown(Keys.F1))
  230.             {
  231.                 currentTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
  232.                 if(currentTime >= 75)
  233.                 {
  234.                 graphics.ToggleFullScreen();
  235.                 currentTime = 0;
  236.                 }
  237.                
  238.             }
  239.  
  240.             if (Keyboard.GetState().IsKeyDown(Keys.Escape))
  241.             {
  242.                 this.Exit();
  243.             }
  244.  
  245.             if (Location.X < 0) Location.X = 0;
  246.             if (Location.Y < 0) Location.Y = 0;
  247.             if (Location.X >= map.Width) Location.X = map.Width - 1;
  248.             if (Location.Y >= map.Height) Location.Y = map.Height - 1;
  249.  
  250.             base.Update(gameTime);
  251.         }
  252.  
  253.         /// <summary>
  254.         /// This is called when the game should draw itself.
  255.         /// </summary>
  256.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  257.         protected override void Draw(GameTime gameTime)
  258.         {
  259.             GraphicsDevice.Clear(Color.CornflowerBlue);
  260.  
  261.             // TODO: Add your drawing code here
  262.             if (map != null)
  263.             {
  264.                 map.Render(spriteBatch, ref Location, 40, 40, ScreenWidth, ScreenHeight);
  265.             }
  266.  
  267.             spriteBatch.Begin();
  268.             CumulativeFrameTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000f;
  269.             NumFrames++;
  270.             if (CumulativeFrameTime >= 1f)
  271.             {
  272.                 FramesPerSecond = NumFrames;
  273.                 NumFrames = 0;
  274.                 CumulativeFrameTime -= 1f;
  275.             }
  276.             spriteBatch.DrawString(text, FramesPerSecond.ToString(), Vector2.One * 5, Color.White);
  277.             //spriteBatch.DrawString(text, string.Format("{0},{1}", Location.X, Location.Y), Vector2.One * 5 + Vector2.UnitY * 20, Color.White);
  278.             spriteBatch.End();
  279.  
  280.             base.Draw(gameTime);
  281.         }
  282.     }
  283. }
  284.  
  285. // IsoRender.cs :
  286. using System;
  287. using System.Collections.Generic;
  288. using Microsoft.Xna.Framework;
  289. using Microsoft.Xna.Framework.Graphics;
  290.  
  291. namespace IsoRender
  292. {
  293.     public class MapObject
  294.     {
  295.         public Point Location;
  296.         public Map Map;
  297.         public int Width;
  298.         public int Height;
  299.         public Texture2D Texture;
  300.  
  301.         public MapObject(int w, int h, Texture2D t)
  302.         {
  303.             Width = w;
  304.             Height = h;
  305.             Texture = t;
  306.  
  307.             return;
  308.         }
  309.  
  310.         public void SetLocation(Point p)
  311.         {
  312.             if (Map != null) Map.SetObjectLocation(this, p);
  313.  
  314.             return;
  315.         }
  316.  
  317.         public void SetLocation(int x, int y)
  318.         {
  319.             if (Map != null) Map.SetObjectLocation(this, new Point(x, y));
  320.  
  321.             return;
  322.         }
  323.  
  324.         public void SetLocation(Point p, Map m)
  325.         {
  326.             if (m != null) m.SetObjectLocation(this, p);
  327.  
  328.             return;
  329.         }
  330.  
  331.         public void SetLocation(int x, int y, Map m)
  332.         {
  333.             if (m != null) m.SetObjectLocation(this, new Point(x, y));
  334.  
  335.             return;
  336.         }
  337.     }
  338.  
  339.     public class MapGrid
  340.     {
  341.         public Point Coordinate;
  342.         public uint ProcessID;
  343.         public Texture2D Texture;
  344.         public MapObject Object;
  345.  
  346.         public MapGrid(int x, int y)
  347.         {
  348.             Coordinate.X = x;
  349.             Coordinate.Y = y;
  350.  
  351.             return;
  352.         }
  353.  
  354.         public MapGrid(int x, int y, Texture2D t)
  355.         {
  356.             Coordinate.X = x;
  357.             Coordinate.Y = y;
  358.             Texture = t;
  359.  
  360.             return;
  361.         }
  362.     }
  363.  
  364.     public class NoRenderArea
  365.     {
  366.         public int x, y; // the coordinates of the upper-left most grid that this area covers
  367.         public int w, h; // the width and height of the
  368.         public bool bLeftEdge, bRightEdge;
  369.         public MapObject Object;
  370.     }
  371.  
  372.     public class Map
  373.     {
  374.         private uint ProcessID = 0;
  375.  
  376.         protected MapGrid[,] Grids;
  377.         private int _mapwidth;
  378.         public int Width { get { return _mapwidth; } }
  379.         private int _mapheight;
  380.         public int Height { get { return _mapheight; } }
  381.  
  382.         protected List<MapGrid> DeferredGrids = new List<MapGrid>();
  383.         protected ObjectPool<NoRenderArea> NRAPool = new ObjectPool<NoRenderArea>(0, 0);
  384.         protected List<NoRenderArea> NoRenderAreas = new List<NoRenderArea>();
  385.  
  386.         public int FloorTileWidthHalf;
  387.         public int FloorTileHeightHalf;
  388.  
  389.         public Map()
  390.         {
  391.         }
  392.        
  393.         public void Initialize(int w, int h, Texture2D deftex)
  394.         {
  395.             _mapwidth = w;
  396.             _mapheight = h;
  397.             Grids = new MapGrid[w, h];
  398.             for (int j = 0; j < h; j++)
  399.                 for (int i = 0; i < w; i++)
  400.                     Grids[i, j] = new MapGrid(i, j, deftex);
  401.  
  402.             return;
  403.         }
  404.  
  405.         public MapGrid GetGrid(int x, int y)
  406.         {
  407.             if (x < 0) return null;
  408.             if (y < 0) return null;
  409.             if (x >= Width) return null;
  410.             if (y >= Height) return null;
  411.  
  412.             return Grids[x, y];
  413.         }
  414.  
  415.         public MapGrid GetGrid(Point p)
  416.         {
  417.             return GetGrid(p.X, p.Y);
  418.         }
  419.  
  420.         public void ReplaceGridWith(int x, int y, MapGrid nmg)
  421.         {
  422.             nmg.Coordinate.X = x;
  423.             nmg.Coordinate.Y = y;
  424.             Grids[x, y] = nmg;
  425.  
  426.             return;
  427.         }
  428.  
  429.         public void SetObjectLocation(MapObject mo, Point p)
  430.         {
  431.             if (mo.Map != this)
  432.             {
  433.                 if (mo.Map != null) mo.Map.ClearObjectLocation(mo);
  434.                 mo.Map = this;
  435.             }
  436.             else ClearObjectLocation(mo);
  437.  
  438.             MapGrid mg;
  439.             mo.Location = p;
  440.             for (int y = p.Y; y < p.Y + mo.Height; y++)
  441.                 for (int x = p.X; x < p.X + mo.Width; x++)
  442.                 {
  443.                     mg = GetGrid(x, y);
  444.                     if (mg != null) mg.Object = mo;
  445.                 }
  446.  
  447.             return;
  448.         }
  449.  
  450.         public void ClearObjectLocation(MapObject mo)
  451.         {
  452.             if (mo == null) return;
  453.  
  454.             MapGrid mg;
  455.             for (int y = mo.Location.Y; y < mo.Location.Y + mo.Height; y++)
  456.                 for (int x = mo.Location.X; x < mo.Location.X + mo.Width; x++)
  457.                 {
  458.                     mg = GetGrid(x, y);
  459.                     if (mg != null) mg.Object = null;
  460.                 }
  461.  
  462.             return;
  463.         }
  464.  
  465.         public Vector2 GetGridRenderLocation(int x, int y, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
  466.         {
  467.             Vector2 v;
  468.  
  469.             int OriginX = CenterGrid.X - DisplayAreaWidth / 2;
  470.             int OriginY = CenterGrid.Y - DisplayAreaHeight / 2;
  471.  
  472.             if (OriginX < 0) OriginX = 0;
  473.             if (OriginY < 0) OriginY = 0;
  474.  
  475.             // initialize v to the base render point of a grid at the center of the screen
  476.             v.X = (ScreenWidth / 2) + (ScreenWidth % 2) - FloorTileWidthHalf;
  477.             v.Y = (ScreenHeight / 2) + (ScreenHeight % 2) + FloorTileHeightHalf;
  478.             // offset v to the base render point of CenterGrid
  479.             v.X -= (CenterGrid.X - OriginX - CenterGrid.Y + OriginY) * FloorTileWidthHalf;
  480.             v.Y -= (CenterGrid.X - OriginX + CenterGrid.Y - OriginY) * FloorTileHeightHalf;
  481.             // offset v to the final base render point
  482.             v.X += (x - OriginX - y + OriginY) * FloorTileWidthHalf;
  483.             v.Y += (x - OriginX + y - OriginY) * FloorTileHeightHalf;
  484.  
  485.             return v;
  486.         }
  487.  
  488.         private void AddToNoRenderAreaList(MapObject mo, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight)
  489.         {
  490.             if (mo == null) return;
  491.  
  492.             NoRenderArea nra = NRAPool.GetObject();
  493.  
  494.             int StartX = CenterGrid.X - DisplayAreaWidth / 2;
  495.             int StartY = CenterGrid.Y - DisplayAreaHeight / 2;
  496.             if (StartX < 0) StartX = 0;
  497.             if (StartY < 0) StartY = 0;
  498.  
  499.             int EndX = StartX + DisplayAreaWidth - 1;
  500.             int EndY = StartY + DisplayAreaHeight - 1;
  501.             if (EndX > Width - 1) EndX = Width - 1;
  502.             if (EndY > Height - 1) EndY = Height - 1;
  503.  
  504.             nra.Object = mo;
  505.  
  506.             // if the left edge is outside the display area, cue the edge as already good
  507.             if (mo.Location.X <= StartX)
  508.             {
  509.                 //nra.x = StartX;
  510.                 nra.x = mo.Location.X;
  511.                 nra.bLeftEdge = true;
  512.             }
  513.             else
  514.             {
  515.                 nra.x = mo.Location.X;
  516.                 nra.bLeftEdge = false;
  517.             }
  518.  
  519.             // if the right edge is outside the display area, cue the edge as already good
  520.             if (mo.Location.Y <= StartY)
  521.             {
  522.                 //nra.y = StartY;
  523.                 nra.y = mo.Location.Y;
  524.                 nra.bRightEdge = true;
  525.             }
  526.             else
  527.             {
  528.                 nra.y = mo.Location.Y;
  529.                 nra.bRightEdge = false;
  530.             }
  531.  
  532.             // double check that the right edge is inside the display area and set the width
  533.             if (nra.x + mo.Width - 1 >= EndX)
  534.             {
  535.                 nra.w = EndX - nra.x + 1;
  536.                 nra.bRightEdge = true;
  537.             }
  538.             else nra.w = mo.Width;
  539.  
  540.             // double check that the left edge is inside the display area and set the height
  541.             if (nra.y + mo.Height - 1 >= EndY)
  542.             {
  543.                 nra.h = EndY - nra.y + 1;
  544.                 nra.bLeftEdge = true;
  545.             }
  546.             else nra.h = mo.Height;
  547.  
  548.             MapGrid mg;
  549.             // double check that the left edge is a grid that hasn't been processed yet
  550.             mg = GetGrid(nra.x - 1, nra.y + nra.h);
  551.             if ((mg == null) || (mg.ProcessID == ProcessID)) nra.bLeftEdge = true;
  552.             // double check that the right edge is a grid that hasn't been processed yet
  553.             mg = GetGrid(nra.x + nra.w, nra.y - 1);
  554.             if ((mg == null) || (mg.ProcessID == ProcessID)) nra.bRightEdge = true;
  555.  
  556.             NoRenderAreas.Add(nra);
  557.  
  558.             return;
  559.         }
  560.  
  561.         private void RemoveFromNoRenderAreaList(MapObject mo)
  562.         {
  563.             for (int i = 0; i < NoRenderAreas.Count; i++)
  564.             {
  565.                 if (NoRenderAreas[i].Object == mo)
  566.                 {
  567.                     NoRenderAreas[i].Object = null;
  568.                     NRAPool.ReturnObject(NoRenderAreas[i]);
  569.                     NoRenderAreas.RemoveAt(i);
  570.                     return;
  571.                 }
  572.             }
  573.  
  574.             return;
  575.         }
  576.  
  577.         private bool IsInNoRenderAreaList(MapObject mo)
  578.         {
  579.             return (NoRenderAreas.Find(n => n.Object == mo) != null);
  580.         }
  581.        
  582.         private void RenderAreaCornerCheck(MapGrid mg)
  583.         {
  584.             if (mg == null) return;
  585.  
  586.             for (int i = 0; i < NoRenderAreas.Count; i++)
  587.             {
  588.                 // check for mg being a corner of a NoRenderArea
  589.                 if ((mg.Coordinate.X == NoRenderAreas[i].x - 1) && (mg.Coordinate.Y == NoRenderAreas[i].y + NoRenderAreas[i].h))
  590.                     NoRenderAreas[i].bLeftEdge = true;
  591.  
  592.                 if ((mg.Coordinate.X == NoRenderAreas[i].x + NoRenderAreas[i].w) && (mg.Coordinate.Y == NoRenderAreas[i].y - 1))
  593.                     NoRenderAreas[i].bRightEdge = true;
  594.             }
  595.  
  596.             return;
  597.         }
  598.        
  599.         private bool ShouldDeferRender(MapGrid mg)
  600.         {
  601.             if (mg == null) return false;
  602.  
  603.             RenderAreaCornerCheck(mg);
  604.  
  605.             for (int i = 0; i < NoRenderAreas.Count; i++)
  606.             {
  607.                 if (mg.Object == NoRenderAreas[i].Object) continue;
  608.  
  609.                 if ((mg.Coordinate.X >= NoRenderAreas[i].x) && (mg.Coordinate.Y >= NoRenderAreas[i].y)) return true;
  610.             }
  611.  
  612.             return false;
  613.         }
  614.  
  615.         private void RenderUnderObject(MapObject mo, SpriteBatch sb, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
  616.         {
  617.             MapGrid mg;
  618.             Vector2 Sprite;
  619.  
  620.             // we render by rows instead of diagonals to gain a bit of speed boost
  621.             // only the grids along the edge of the object will be seen, and the very large odds are nobody will ever be able to visually tell the difference
  622.             for (int y = mo.Location.Y; y < mo.Location.Y + mo.Height; y++)
  623.                 for (int x = mo.Location.X; x < mo.Location.X + mo.Width; x++)
  624.                 {
  625.                     mg = GetGrid(x, y);
  626.                     if (mg == null) continue;
  627.                     // need to make sure we give this grid the chance to flag an edge of another NoRenderArea
  628.                     RenderAreaCornerCheck(mg);
  629.                     // don't process a grid more than once
  630.                     if (mg.ProcessID != ProcessID)
  631.                     {
  632.                         mg.ProcessID = ProcessID;
  633.                         if (mg.Texture == null) continue;
  634.                         Sprite = GetGridRenderLocation(x, y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
  635.                         Sprite.X += FloorTileWidthHalf - mg.Texture.Width / 2;
  636.                         Sprite.Y -= mg.Texture.Height;
  637.                         sb.Draw(mg.Texture, Sprite, Color.White);
  638.                     }
  639.                 }
  640.  
  641.             return;
  642.         }
  643.  
  644.         private void RenderDeferred(SpriteBatch sb, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
  645.         {
  646.             Vector2 Sprite;
  647.  
  648.             for (int i = 0; i < DeferredGrids.Count; i++)
  649.             {
  650.                 if (!ShouldDeferRender(DeferredGrids[i]))
  651.                 {
  652.                     // ensure we process this grid only once
  653.                     DeferredGrids[i].ProcessID = ProcessID;
  654.  
  655.                     Sprite = GetGridRenderLocation(DeferredGrids[i].Coordinate.X, DeferredGrids[i].Coordinate.Y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
  656.  
  657.                     if (DeferredGrids[i].Texture != null)
  658.                     {
  659.                         Sprite.X += FloorTileWidthHalf - DeferredGrids[i].Texture.Width / 2;
  660.                         Sprite.Y -= DeferredGrids[i].Texture.Height;
  661.                         sb.Draw(DeferredGrids[i].Texture, Sprite, Color.White);
  662.                     }
  663.  
  664.                     DeferredGrids.RemoveAt(i--);
  665.                 }
  666.             }
  667.  
  668.             return;
  669.         }
  670.  
  671.         public void Render(SpriteBatch sb, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
  672.         {
  673.             int CurX, CurY;         // this tell us which grid coordinate we're dealing with
  674.             int LimitX, LimitY;     // these tell us which coordinate limits on each axis we are currently processing
  675.             int OriginX, OriginY;   // these mark our starting grid for the entire area
  676.             int StartX, StartY;     // these mark our starting grid for the line
  677.             int EndX, EndY;         // these mark our ending grid for the line
  678.             int SpriteOriginX, SpriteOriginY;   // these mark the rendering location of the first grid, serves as a rendering origin for all grids
  679.             Vector2 Sprite;         // this is used to store the current grid's rendering location
  680.             bool bEdgeX, bEdgeY;    // these get used to know when we finish rendering the desired area
  681.             bool bProcessNRA;       // this tells us to process NoRenderAreas even if we added one immediately
  682.             MapGrid CurGrid;        // this tells us which grid we are currently processing
  683.  
  684.             // this is how we know whether or not we've processed a grid without having to touch every grid an extra time
  685.             ProcessID++;
  686.  
  687.             // clear out our deferred grids list so it's fresh for this frame
  688.             DeferredGrids.Clear();
  689.             NoRenderAreas.Clear();
  690.  
  691.             // initialize our values to the first grid we'll process
  692.             OriginX = StartX = LimitX = CenterGrid.X - DisplayAreaWidth / 2;
  693.             OriginY = StartY = LimitY = CenterGrid.Y - DisplayAreaHeight / 2;
  694.  
  695.             // ensure we aren't starting outside the bounds of our grid array
  696.             if (LimitX < 0) OriginX = StartX = LimitX = 0;
  697.             if (LimitY < 0) OriginY = StartY = LimitY = 0;
  698.  
  699.             // initialize our ending grid
  700.             EndX = StartX + DisplayAreaWidth - 1;
  701.             EndY = StartY + DisplayAreaHeight - 1;
  702.  
  703.             // ensure we aren't ending outside the bounds of our grid array
  704.             if (EndX >= Width) EndX = Width - 1;
  705.             if (EndY >= Height) EndY = Height - 1;
  706.  
  707.             // initialize the sprite rendering origin coordinates
  708.             SpriteOriginX = (ScreenWidth / 2) + (ScreenWidth % 2) - FloorTileWidthHalf;
  709.             SpriteOriginY = (ScreenHeight / 2) + (ScreenHeight % 2) + FloorTileHeightHalf;
  710.             SpriteOriginX -= (CenterGrid.X - StartX) * FloorTileWidthHalf - (CenterGrid.Y - StartY) * FloorTileWidthHalf;
  711.             SpriteOriginY -= (CenterGrid.X - StartX) * FloorTileHeightHalf + (CenterGrid.Y - StartY) * FloorTileHeightHalf;
  712.  
  713.             // start our SpriteBatch
  714.             sb.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null);
  715.  
  716.             // we're rendering diagonally across the array
  717.             // this means we don't have to precompute how many iterations we're doing, as that gets tested later on
  718.             while (true)
  719.             {
  720.                 // start a new line
  721.                 CurX = StartX;
  722.                 CurY = LimitY;
  723.  
  724.                 // reset our edge values
  725.                 bEdgeX = bEdgeY = false;
  726.  
  727.                 // iterate across the line of grids
  728.                 while ((CurX <= LimitX) && (CurY >= StartY))
  729.                 {
  730.                     CurGrid = Grids[CurX, CurY];
  731.                     if ((CurGrid != null) && (CurGrid.ProcessID != ProcessID))
  732.                     {
  733.                         // every grid gets checked to see if it's in a NoRenderArea's shadow
  734.                         if (ShouldDeferRender(CurGrid))
  735.                         {
  736.                             DeferredGrids.Add(CurGrid);
  737.                             CurX++;
  738.                             CurY--;
  739.                             continue;
  740.                         }
  741.  
  742.                         // this is how we flag the grid as being processed
  743.                         CurGrid.ProcessID = ProcessID;
  744.                         // if there's no sprite associated with this grid, continue on
  745.                         if (CurGrid.Texture == null)
  746.                         {
  747.                             CurX++;
  748.                             CurY--;
  749.                             continue;
  750.                         }
  751.                         // set our sprite rendering coordinates
  752.                         Sprite.X = SpriteOriginX + (CurX - OriginX) * FloorTileWidthHalf - (CurY - OriginY) * FloorTileWidthHalf + FloorTileWidthHalf - CurGrid.Texture.Width / 2;
  753.                         Sprite.Y = SpriteOriginY + (CurX - OriginX) * FloorTileHeightHalf + (CurY - OriginY) * FloorTileHeightHalf - CurGrid.Texture.Height;
  754.                         // draw this grid
  755.                         sb.Draw(CurGrid.Texture, Sprite, Color.White);
  756.  
  757.                         bProcessNRA = false;
  758.  
  759.                         // check if there's an object to render on this grid
  760.                         if ((CurGrid.Object != null) && (CurGrid.Object.Texture != null))
  761.                         {
  762.                             // always immediately render single grid objects
  763.                             if ((CurGrid.Object.Width == 1) && (CurGrid.Object.Height == 1))
  764.                             {
  765.                                 Sprite = GetGridRenderLocation(CurGrid.Coordinate.X, CurGrid.Coordinate.Y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
  766.                                 Sprite.X += FloorTileWidthHalf - CurGrid.Object.Texture.Width / 2;
  767.                                 Sprite.Y -= CurGrid.Object.Texture.Height;
  768.                                 sb.Draw(CurGrid.Object.Texture, Sprite, Color.White);
  769.                             }
  770.                             else if (!IsInNoRenderAreaList(CurGrid.Object))
  771.                             {
  772.                                 // create a NoRenderArea that covers this object
  773.                                 AddToNoRenderAreaList(CurGrid.Object, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight);
  774.                                 // it's possible that this object's edges have already been processed, so we flag for an immediate processing of NoRenderAreas
  775.                                 if (NoRenderAreas[NoRenderAreas.Count - 1].bLeftEdge && NoRenderAreas[NoRenderAreas.Count - 1].bRightEdge) bProcessNRA = true;
  776.                             }
  777.                         }
  778.  
  779.                         if (bProcessNRA || (CurGrid.Object == null))
  780.                         {
  781.                             // check to see if this grid enables us to render a deferred object
  782.                             for (int i = 0; i < NoRenderAreas.Count; i++)
  783.                             {
  784.                                 // when both edges are flagged, we want to render the object immediately
  785.                                 if (NoRenderAreas[i].bLeftEdge && NoRenderAreas[i].bRightEdge)
  786.                                 {
  787.                                     // first render all grids the object is on
  788.                                     RenderUnderObject(NoRenderAreas[i].Object, sb, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
  789.                                     // render object now
  790.                                     Sprite = GetGridRenderLocation(NoRenderAreas[i].Object.Location.X, NoRenderAreas[i].Object.Location.Y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
  791.                                     Sprite.X += FloorTileWidthHalf + FloorTileWidthHalf * (NoRenderAreas[i].Object.Width - NoRenderAreas[i].Object.Height) / 2 - NoRenderAreas[i].Object.Texture.Width / 2;
  792.                                     Sprite.Y += FloorTileHeightHalf * (NoRenderAreas[i].Object.Width + NoRenderAreas[i].Object.Height - 2) - NoRenderAreas[i].Object.Texture.Height;
  793.                                     sb.Draw(NoRenderAreas[i].Object.Texture, Sprite, Color.White);
  794.                                     // remove this NoRenderArea
  795.                                     RemoveFromNoRenderAreaList(NoRenderAreas[i--].Object);
  796.                                     // we may have made some deferred grids renderable now
  797.                                     RenderDeferred(sb, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
  798.                                 }
  799.                             }
  800.                         }
  801.                     }
  802.  
  803.                     // move to the next grid on the line
  804.                     CurX++;
  805.                     CurY--;
  806.                 }
  807.  
  808.                 // increment our X axis limit
  809.                 if (++LimitX > EndX)
  810.                 {
  811.                     // this means our diagonal traversals are hitting the right most edge of the area
  812.                     LimitX = EndX;
  813.                     // we've also hit the bottom most edge of the area
  814.                     if (++StartY > EndY)
  815.                     {
  816.                         StartY = EndY;
  817.                         bEdgeY = true;
  818.                     }
  819.                 }
  820.  
  821.                 // increment our Y axis limit
  822.                 if (++LimitY > EndY)
  823.                 {
  824.                     // this means our diagonal traversals are hitting the bottom most edge of the area
  825.                     LimitY = EndY;
  826.                     // we've also hit the right most edge of the area
  827.                     if (++StartX > EndX)
  828.                     {
  829.                         StartX = EndX;
  830.                         bEdgeX = true;
  831.                     }
  832.                 }
  833.  
  834.                 // hitting both edges at the same time means we've run out of diagonals
  835.                 if (bEdgeX && bEdgeY) break;
  836.             }
  837.  
  838.             sb.End();
  839.  
  840.             return;
  841.         }
  842.     }
  843. }
  844.  
  845. //ObjectPool.cs :
  846.  
  847. using System;
  848. using System.Collections.Generic;
  849.  
  850. namespace IsoRender
  851. {
  852.     public class ObjectPool<T> where T : new()
  853.     {
  854.         private Queue<T> unused = new Queue<T>();
  855.         private LinkedList<T> used = new LinkedList<T>();
  856.         private int MaxPoolSize;
  857.         public int Count
  858.         {
  859.             get { return unused.Count + used.Count; }
  860.         }
  861.  
  862.         public ObjectPool(int startingpool, int maxpool)
  863.         {
  864.             for (int i = 0; i < startingpool; i++) unused.Enqueue(new T());
  865.  
  866.             MaxPoolSize = maxpool;
  867.  
  868.             return;
  869.         }
  870.  
  871.         public T GetObject()
  872.         {
  873.             T t;
  874.  
  875.             if (unused.Count == 0)
  876.             {
  877.                 if ((MaxPoolSize > 0) && (Count >= MaxPoolSize)) return default(T);
  878.                 t = new T();
  879.             }
  880.             else t = unused.Dequeue();
  881.  
  882.             used.AddFirst(t);
  883.             return t;
  884.         }
  885.  
  886.         public void ReturnObject(T t)
  887.         {
  888.             if (used.Remove(t)) unused.Enqueue(t);
  889.  
  890.             return;
  891.         }
  892.     }
  893. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement