Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Game1.cs :
- /// <summary>
- /// Copyright (c) 2010 Resseguier Valentin
- /// All rights reserved.
- ///
- /// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- ///
- /// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- /// * 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.
- /// * 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.
- ///
- /// 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.
- /// </summary>
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Audio;
- using Microsoft.Xna.Framework.Content;
- using Microsoft.Xna.Framework.GamerServices;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Media;
- using IsoRender;
- namespace Open_RollerCoasterTycoon
- {
- /// <summary>
- /// This is the main type for your game
- /// </summary>
- public class Game1 : Microsoft.Xna.Framework.Game
- {
- GraphicsDeviceManager graphics;
- SpriteBatch spriteBatch;
- Texture2D floor;
- Texture2D house;
- Texture2D road;
- Map map;
- int ScreenWidth;
- int ScreenHeight;
- Point Location;
- SpriteFont text;
- float CumulativeFrameTime, currentTime;
- int NumFrames;
- int FramesPerSecond;
- Vector2 PositionMouse;
- Song GameMusic1;
- public Game1()
- {
- graphics = new GraphicsDeviceManager(this);
- graphics.IsFullScreen = false;
- graphics.PreferredBackBufferHeight = 768;
- graphics.PreferredBackBufferWidth = 1024;
- IsMouseVisible = true;
- ScreenWidth = graphics.PreferredBackBufferWidth;
- ScreenHeight = graphics.PreferredBackBufferHeight;
- Content.RootDirectory = "Content";
- }
- /// <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()
- {
- // TODO: Add your initialization logic here
- 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);
- // TODO: use this.Content to load your game content here
- GraphicsDevice.PresentationParameters.PresentationInterval = PresentInterval.Immediate;
- GraphicsDevice.Reset();
- floor = Content.Load<Texture2D>("Map/Texture/Herbe32");
- house = Content.Load<Texture2D>("Object/House/House32");
- road = Content.Load<Texture2D>("Object/Road/Road32");
- /*floor32 = Content.Load<Texture2D>("Map/Texture/Herbe32");
- floor16 = Content.Load<Texture2D>("Map/Texture/Herbe16");
- floor8 = Content.Load<Texture2D>("Map/Texture/Herbe8");*/
- text = Content.Load<SpriteFont>("Text/text");
- GameMusic1 = Content.Load<Song>("Music/GameMusic1");
- MediaPlayer.IsRepeating = true;
- if (MediaPlayer.State == MediaState.Stopped)
- MediaPlayer.Play(GameMusic1);
- }
- /// <summary>
- /// UnloadContent will be called once per game and is the place to unload
- /// all content.
- /// </summary>
- protected override void UnloadContent()
- {
- // TODO: Unload any non ContentManager content here
- MediaPlayer.Stop();
- }
- /// <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)
- {
- // Allows the game to exit
- if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
- this.Exit();
- // TODO: Add your update logic here
- if (map == null)
- {
- map = new Map();
- map.Initialize(40, 40, floor);
- map.FloorTileWidthHalf = 32;
- map.FloorTileHeightHalf = 16;
- MapGrid mg;
- for (int i = 0; i < map.Width; i++)
- for (int j = 0; j < map.Height; j++)
- {
- mg = map.GetGrid(i, j);
- }
- Random rnd = new Random();
- MapObject mo = new MapObject(2, 2, house);
- mo.Location.X = 38;
- mo.Location.Y = 17;
- mo.SetLocation(mo.Location, map);
- mo = new MapObject(2, 2, road);
- mo.Location.X = 38;
- mo.Location.Y = 18;
- mo.SetLocation(mo.Location, map);
- mo = new MapObject(2, 2, road);
- mo.Location.X = 37;
- mo.Location.Y = 18;
- mo.SetLocation(mo.Location, map);
- mo = new MapObject(2, 2, road);
- mo.Location.X = 36;
- mo.Location.Y = 18;
- mo.SetLocation(mo.Location, map);
- mo = new MapObject(2, 2, road);
- mo.Location.X = 35;
- mo.Location.Y = 18;
- mo.SetLocation(mo.Location, map);
- mo = new MapObject(2, 2, road);
- mo.Location.X = 34;
- mo.Location.Y = 18;
- mo.SetLocation(mo.Location, map);
- }
- if (Keyboard.GetState().IsKeyDown(Keys.Down))
- {
- Location.X++;
- Location.Y++;
- }
- else if (Keyboard.GetState().IsKeyDown(Keys.Up))
- {
- Location.X--;
- Location.Y--;
- }
- if (Keyboard.GetState().IsKeyDown(Keys.Left))
- {
- Location.X--;
- Location.Y++;
- }
- else if (Keyboard.GetState().IsKeyDown(Keys.Right))
- {
- Location.X++;
- Location.Y--;
- }
- /*if (Keyboard.GetState().IsKeyDown(Keys.Add))
- {
- if (map.FloorTileWidthHalf == 32)
- {
- }
- else if (map.FloorTileWidthHalf == 8)
- {
- floor = Content.Load<Texture2D>("Map/Texture/Herbe16");
- map.Initialize(40, 40, floor);
- map.FloorTileWidthHalf = map.FloorTileWidthHalf * 2;
- map.FloorTileHeightHalf = map.FloorTileHeightHalf * 2;
- }
- else if (map.FloorTileWidthHalf == 16)
- {
- floor = Content.Load<Texture2D>("Map/Texture/Herbe32");
- map.Initialize(40, 40, floor);
- map.FloorTileWidthHalf = map.FloorTileWidthHalf * 2;
- map.FloorTileHeightHalf = map.FloorTileHeightHalf * 2;
- }
- }
- else if (Keyboard.GetState().IsKeyDown(Keys.Subtract))
- {
- if (map.FloorTileWidthHalf == 8)
- {
- }
- else if (map.FloorTileWidthHalf == 32)
- {
- floor = Content.Load<Texture2D>("Map/Texture/Herbe16");
- map.Initialize(40, 40, floor);
- map.FloorTileWidthHalf = map.FloorTileWidthHalf / 2;
- map.FloorTileHeightHalf = map.FloorTileHeightHalf / 2;
- }
- else if (map.FloorTileWidthHalf == 16)
- {
- floor = Content.Load<Texture2D>("Map/Texture/Herbe8");
- map.Initialize(40, 40, floor);
- map.FloorTileWidthHalf = map.FloorTileWidthHalf / 2;
- map.FloorTileHeightHalf = map.FloorTileHeightHalf / 2;
- }
- }*/
- if (Keyboard.GetState().IsKeyDown(Keys.F1))
- {
- currentTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
- if(currentTime >= 75)
- {
- graphics.ToggleFullScreen();
- currentTime = 0;
- }
- }
- if (Keyboard.GetState().IsKeyDown(Keys.Escape))
- {
- this.Exit();
- }
- if (Location.X < 0) Location.X = 0;
- if (Location.Y < 0) Location.Y = 0;
- if (Location.X >= map.Width) Location.X = map.Width - 1;
- if (Location.Y >= map.Height) Location.Y = map.Height - 1;
- base.Update(gameTime);
- }
- /// <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)
- {
- GraphicsDevice.Clear(Color.CornflowerBlue);
- // TODO: Add your drawing code here
- if (map != null)
- {
- map.Render(spriteBatch, ref Location, 40, 40, ScreenWidth, ScreenHeight);
- }
- spriteBatch.Begin();
- CumulativeFrameTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000f;
- NumFrames++;
- if (CumulativeFrameTime >= 1f)
- {
- FramesPerSecond = NumFrames;
- NumFrames = 0;
- CumulativeFrameTime -= 1f;
- }
- spriteBatch.DrawString(text, FramesPerSecond.ToString(), Vector2.One * 5, Color.White);
- //spriteBatch.DrawString(text, string.Format("{0},{1}", Location.X, Location.Y), Vector2.One * 5 + Vector2.UnitY * 20, Color.White);
- spriteBatch.End();
- base.Draw(gameTime);
- }
- }
- }
- // IsoRender.cs :
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- namespace IsoRender
- {
- public class MapObject
- {
- public Point Location;
- public Map Map;
- public int Width;
- public int Height;
- public Texture2D Texture;
- public MapObject(int w, int h, Texture2D t)
- {
- Width = w;
- Height = h;
- Texture = t;
- return;
- }
- public void SetLocation(Point p)
- {
- if (Map != null) Map.SetObjectLocation(this, p);
- return;
- }
- public void SetLocation(int x, int y)
- {
- if (Map != null) Map.SetObjectLocation(this, new Point(x, y));
- return;
- }
- public void SetLocation(Point p, Map m)
- {
- if (m != null) m.SetObjectLocation(this, p);
- return;
- }
- public void SetLocation(int x, int y, Map m)
- {
- if (m != null) m.SetObjectLocation(this, new Point(x, y));
- return;
- }
- }
- public class MapGrid
- {
- public Point Coordinate;
- public uint ProcessID;
- public Texture2D Texture;
- public MapObject Object;
- public MapGrid(int x, int y)
- {
- Coordinate.X = x;
- Coordinate.Y = y;
- return;
- }
- public MapGrid(int x, int y, Texture2D t)
- {
- Coordinate.X = x;
- Coordinate.Y = y;
- Texture = t;
- return;
- }
- }
- public class NoRenderArea
- {
- public int x, y; // the coordinates of the upper-left most grid that this area covers
- public int w, h; // the width and height of the
- public bool bLeftEdge, bRightEdge;
- public MapObject Object;
- }
- public class Map
- {
- private uint ProcessID = 0;
- protected MapGrid[,] Grids;
- private int _mapwidth;
- public int Width { get { return _mapwidth; } }
- private int _mapheight;
- public int Height { get { return _mapheight; } }
- protected List<MapGrid> DeferredGrids = new List<MapGrid>();
- protected ObjectPool<NoRenderArea> NRAPool = new ObjectPool<NoRenderArea>(0, 0);
- protected List<NoRenderArea> NoRenderAreas = new List<NoRenderArea>();
- public int FloorTileWidthHalf;
- public int FloorTileHeightHalf;
- public Map()
- {
- }
- public void Initialize(int w, int h, Texture2D deftex)
- {
- _mapwidth = w;
- _mapheight = h;
- Grids = new MapGrid[w, h];
- for (int j = 0; j < h; j++)
- for (int i = 0; i < w; i++)
- Grids[i, j] = new MapGrid(i, j, deftex);
- return;
- }
- public MapGrid GetGrid(int x, int y)
- {
- if (x < 0) return null;
- if (y < 0) return null;
- if (x >= Width) return null;
- if (y >= Height) return null;
- return Grids[x, y];
- }
- public MapGrid GetGrid(Point p)
- {
- return GetGrid(p.X, p.Y);
- }
- public void ReplaceGridWith(int x, int y, MapGrid nmg)
- {
- nmg.Coordinate.X = x;
- nmg.Coordinate.Y = y;
- Grids[x, y] = nmg;
- return;
- }
- public void SetObjectLocation(MapObject mo, Point p)
- {
- if (mo.Map != this)
- {
- if (mo.Map != null) mo.Map.ClearObjectLocation(mo);
- mo.Map = this;
- }
- else ClearObjectLocation(mo);
- MapGrid mg;
- mo.Location = p;
- for (int y = p.Y; y < p.Y + mo.Height; y++)
- for (int x = p.X; x < p.X + mo.Width; x++)
- {
- mg = GetGrid(x, y);
- if (mg != null) mg.Object = mo;
- }
- return;
- }
- public void ClearObjectLocation(MapObject mo)
- {
- if (mo == null) return;
- MapGrid mg;
- for (int y = mo.Location.Y; y < mo.Location.Y + mo.Height; y++)
- for (int x = mo.Location.X; x < mo.Location.X + mo.Width; x++)
- {
- mg = GetGrid(x, y);
- if (mg != null) mg.Object = null;
- }
- return;
- }
- public Vector2 GetGridRenderLocation(int x, int y, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
- {
- Vector2 v;
- int OriginX = CenterGrid.X - DisplayAreaWidth / 2;
- int OriginY = CenterGrid.Y - DisplayAreaHeight / 2;
- if (OriginX < 0) OriginX = 0;
- if (OriginY < 0) OriginY = 0;
- // initialize v to the base render point of a grid at the center of the screen
- v.X = (ScreenWidth / 2) + (ScreenWidth % 2) - FloorTileWidthHalf;
- v.Y = (ScreenHeight / 2) + (ScreenHeight % 2) + FloorTileHeightHalf;
- // offset v to the base render point of CenterGrid
- v.X -= (CenterGrid.X - OriginX - CenterGrid.Y + OriginY) * FloorTileWidthHalf;
- v.Y -= (CenterGrid.X - OriginX + CenterGrid.Y - OriginY) * FloorTileHeightHalf;
- // offset v to the final base render point
- v.X += (x - OriginX - y + OriginY) * FloorTileWidthHalf;
- v.Y += (x - OriginX + y - OriginY) * FloorTileHeightHalf;
- return v;
- }
- private void AddToNoRenderAreaList(MapObject mo, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight)
- {
- if (mo == null) return;
- NoRenderArea nra = NRAPool.GetObject();
- int StartX = CenterGrid.X - DisplayAreaWidth / 2;
- int StartY = CenterGrid.Y - DisplayAreaHeight / 2;
- if (StartX < 0) StartX = 0;
- if (StartY < 0) StartY = 0;
- int EndX = StartX + DisplayAreaWidth - 1;
- int EndY = StartY + DisplayAreaHeight - 1;
- if (EndX > Width - 1) EndX = Width - 1;
- if (EndY > Height - 1) EndY = Height - 1;
- nra.Object = mo;
- // if the left edge is outside the display area, cue the edge as already good
- if (mo.Location.X <= StartX)
- {
- //nra.x = StartX;
- nra.x = mo.Location.X;
- nra.bLeftEdge = true;
- }
- else
- {
- nra.x = mo.Location.X;
- nra.bLeftEdge = false;
- }
- // if the right edge is outside the display area, cue the edge as already good
- if (mo.Location.Y <= StartY)
- {
- //nra.y = StartY;
- nra.y = mo.Location.Y;
- nra.bRightEdge = true;
- }
- else
- {
- nra.y = mo.Location.Y;
- nra.bRightEdge = false;
- }
- // double check that the right edge is inside the display area and set the width
- if (nra.x + mo.Width - 1 >= EndX)
- {
- nra.w = EndX - nra.x + 1;
- nra.bRightEdge = true;
- }
- else nra.w = mo.Width;
- // double check that the left edge is inside the display area and set the height
- if (nra.y + mo.Height - 1 >= EndY)
- {
- nra.h = EndY - nra.y + 1;
- nra.bLeftEdge = true;
- }
- else nra.h = mo.Height;
- MapGrid mg;
- // double check that the left edge is a grid that hasn't been processed yet
- mg = GetGrid(nra.x - 1, nra.y + nra.h);
- if ((mg == null) || (mg.ProcessID == ProcessID)) nra.bLeftEdge = true;
- // double check that the right edge is a grid that hasn't been processed yet
- mg = GetGrid(nra.x + nra.w, nra.y - 1);
- if ((mg == null) || (mg.ProcessID == ProcessID)) nra.bRightEdge = true;
- NoRenderAreas.Add(nra);
- return;
- }
- private void RemoveFromNoRenderAreaList(MapObject mo)
- {
- for (int i = 0; i < NoRenderAreas.Count; i++)
- {
- if (NoRenderAreas[i].Object == mo)
- {
- NoRenderAreas[i].Object = null;
- NRAPool.ReturnObject(NoRenderAreas[i]);
- NoRenderAreas.RemoveAt(i);
- return;
- }
- }
- return;
- }
- private bool IsInNoRenderAreaList(MapObject mo)
- {
- return (NoRenderAreas.Find(n => n.Object == mo) != null);
- }
- private void RenderAreaCornerCheck(MapGrid mg)
- {
- if (mg == null) return;
- for (int i = 0; i < NoRenderAreas.Count; i++)
- {
- // check for mg being a corner of a NoRenderArea
- if ((mg.Coordinate.X == NoRenderAreas[i].x - 1) && (mg.Coordinate.Y == NoRenderAreas[i].y + NoRenderAreas[i].h))
- NoRenderAreas[i].bLeftEdge = true;
- if ((mg.Coordinate.X == NoRenderAreas[i].x + NoRenderAreas[i].w) && (mg.Coordinate.Y == NoRenderAreas[i].y - 1))
- NoRenderAreas[i].bRightEdge = true;
- }
- return;
- }
- private bool ShouldDeferRender(MapGrid mg)
- {
- if (mg == null) return false;
- RenderAreaCornerCheck(mg);
- for (int i = 0; i < NoRenderAreas.Count; i++)
- {
- if (mg.Object == NoRenderAreas[i].Object) continue;
- if ((mg.Coordinate.X >= NoRenderAreas[i].x) && (mg.Coordinate.Y >= NoRenderAreas[i].y)) return true;
- }
- return false;
- }
- private void RenderUnderObject(MapObject mo, SpriteBatch sb, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
- {
- MapGrid mg;
- Vector2 Sprite;
- // we render by rows instead of diagonals to gain a bit of speed boost
- // 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
- for (int y = mo.Location.Y; y < mo.Location.Y + mo.Height; y++)
- for (int x = mo.Location.X; x < mo.Location.X + mo.Width; x++)
- {
- mg = GetGrid(x, y);
- if (mg == null) continue;
- // need to make sure we give this grid the chance to flag an edge of another NoRenderArea
- RenderAreaCornerCheck(mg);
- // don't process a grid more than once
- if (mg.ProcessID != ProcessID)
- {
- mg.ProcessID = ProcessID;
- if (mg.Texture == null) continue;
- Sprite = GetGridRenderLocation(x, y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
- Sprite.X += FloorTileWidthHalf - mg.Texture.Width / 2;
- Sprite.Y -= mg.Texture.Height;
- sb.Draw(mg.Texture, Sprite, Color.White);
- }
- }
- return;
- }
- private void RenderDeferred(SpriteBatch sb, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
- {
- Vector2 Sprite;
- for (int i = 0; i < DeferredGrids.Count; i++)
- {
- if (!ShouldDeferRender(DeferredGrids[i]))
- {
- // ensure we process this grid only once
- DeferredGrids[i].ProcessID = ProcessID;
- Sprite = GetGridRenderLocation(DeferredGrids[i].Coordinate.X, DeferredGrids[i].Coordinate.Y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
- if (DeferredGrids[i].Texture != null)
- {
- Sprite.X += FloorTileWidthHalf - DeferredGrids[i].Texture.Width / 2;
- Sprite.Y -= DeferredGrids[i].Texture.Height;
- sb.Draw(DeferredGrids[i].Texture, Sprite, Color.White);
- }
- DeferredGrids.RemoveAt(i--);
- }
- }
- return;
- }
- public void Render(SpriteBatch sb, ref Point CenterGrid, int DisplayAreaWidth, int DisplayAreaHeight, int ScreenWidth, int ScreenHeight)
- {
- int CurX, CurY; // this tell us which grid coordinate we're dealing with
- int LimitX, LimitY; // these tell us which coordinate limits on each axis we are currently processing
- int OriginX, OriginY; // these mark our starting grid for the entire area
- int StartX, StartY; // these mark our starting grid for the line
- int EndX, EndY; // these mark our ending grid for the line
- int SpriteOriginX, SpriteOriginY; // these mark the rendering location of the first grid, serves as a rendering origin for all grids
- Vector2 Sprite; // this is used to store the current grid's rendering location
- bool bEdgeX, bEdgeY; // these get used to know when we finish rendering the desired area
- bool bProcessNRA; // this tells us to process NoRenderAreas even if we added one immediately
- MapGrid CurGrid; // this tells us which grid we are currently processing
- // this is how we know whether or not we've processed a grid without having to touch every grid an extra time
- ProcessID++;
- // clear out our deferred grids list so it's fresh for this frame
- DeferredGrids.Clear();
- NoRenderAreas.Clear();
- // initialize our values to the first grid we'll process
- OriginX = StartX = LimitX = CenterGrid.X - DisplayAreaWidth / 2;
- OriginY = StartY = LimitY = CenterGrid.Y - DisplayAreaHeight / 2;
- // ensure we aren't starting outside the bounds of our grid array
- if (LimitX < 0) OriginX = StartX = LimitX = 0;
- if (LimitY < 0) OriginY = StartY = LimitY = 0;
- // initialize our ending grid
- EndX = StartX + DisplayAreaWidth - 1;
- EndY = StartY + DisplayAreaHeight - 1;
- // ensure we aren't ending outside the bounds of our grid array
- if (EndX >= Width) EndX = Width - 1;
- if (EndY >= Height) EndY = Height - 1;
- // initialize the sprite rendering origin coordinates
- SpriteOriginX = (ScreenWidth / 2) + (ScreenWidth % 2) - FloorTileWidthHalf;
- SpriteOriginY = (ScreenHeight / 2) + (ScreenHeight % 2) + FloorTileHeightHalf;
- SpriteOriginX -= (CenterGrid.X - StartX) * FloorTileWidthHalf - (CenterGrid.Y - StartY) * FloorTileWidthHalf;
- SpriteOriginY -= (CenterGrid.X - StartX) * FloorTileHeightHalf + (CenterGrid.Y - StartY) * FloorTileHeightHalf;
- // start our SpriteBatch
- sb.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null);
- // we're rendering diagonally across the array
- // this means we don't have to precompute how many iterations we're doing, as that gets tested later on
- while (true)
- {
- // start a new line
- CurX = StartX;
- CurY = LimitY;
- // reset our edge values
- bEdgeX = bEdgeY = false;
- // iterate across the line of grids
- while ((CurX <= LimitX) && (CurY >= StartY))
- {
- CurGrid = Grids[CurX, CurY];
- if ((CurGrid != null) && (CurGrid.ProcessID != ProcessID))
- {
- // every grid gets checked to see if it's in a NoRenderArea's shadow
- if (ShouldDeferRender(CurGrid))
- {
- DeferredGrids.Add(CurGrid);
- CurX++;
- CurY--;
- continue;
- }
- // this is how we flag the grid as being processed
- CurGrid.ProcessID = ProcessID;
- // if there's no sprite associated with this grid, continue on
- if (CurGrid.Texture == null)
- {
- CurX++;
- CurY--;
- continue;
- }
- // set our sprite rendering coordinates
- Sprite.X = SpriteOriginX + (CurX - OriginX) * FloorTileWidthHalf - (CurY - OriginY) * FloorTileWidthHalf + FloorTileWidthHalf - CurGrid.Texture.Width / 2;
- Sprite.Y = SpriteOriginY + (CurX - OriginX) * FloorTileHeightHalf + (CurY - OriginY) * FloorTileHeightHalf - CurGrid.Texture.Height;
- // draw this grid
- sb.Draw(CurGrid.Texture, Sprite, Color.White);
- bProcessNRA = false;
- // check if there's an object to render on this grid
- if ((CurGrid.Object != null) && (CurGrid.Object.Texture != null))
- {
- // always immediately render single grid objects
- if ((CurGrid.Object.Width == 1) && (CurGrid.Object.Height == 1))
- {
- Sprite = GetGridRenderLocation(CurGrid.Coordinate.X, CurGrid.Coordinate.Y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
- Sprite.X += FloorTileWidthHalf - CurGrid.Object.Texture.Width / 2;
- Sprite.Y -= CurGrid.Object.Texture.Height;
- sb.Draw(CurGrid.Object.Texture, Sprite, Color.White);
- }
- else if (!IsInNoRenderAreaList(CurGrid.Object))
- {
- // create a NoRenderArea that covers this object
- AddToNoRenderAreaList(CurGrid.Object, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight);
- // it's possible that this object's edges have already been processed, so we flag for an immediate processing of NoRenderAreas
- if (NoRenderAreas[NoRenderAreas.Count - 1].bLeftEdge && NoRenderAreas[NoRenderAreas.Count - 1].bRightEdge) bProcessNRA = true;
- }
- }
- if (bProcessNRA || (CurGrid.Object == null))
- {
- // check to see if this grid enables us to render a deferred object
- for (int i = 0; i < NoRenderAreas.Count; i++)
- {
- // when both edges are flagged, we want to render the object immediately
- if (NoRenderAreas[i].bLeftEdge && NoRenderAreas[i].bRightEdge)
- {
- // first render all grids the object is on
- RenderUnderObject(NoRenderAreas[i].Object, sb, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
- // render object now
- Sprite = GetGridRenderLocation(NoRenderAreas[i].Object.Location.X, NoRenderAreas[i].Object.Location.Y, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
- Sprite.X += FloorTileWidthHalf + FloorTileWidthHalf * (NoRenderAreas[i].Object.Width - NoRenderAreas[i].Object.Height) / 2 - NoRenderAreas[i].Object.Texture.Width / 2;
- Sprite.Y += FloorTileHeightHalf * (NoRenderAreas[i].Object.Width + NoRenderAreas[i].Object.Height - 2) - NoRenderAreas[i].Object.Texture.Height;
- sb.Draw(NoRenderAreas[i].Object.Texture, Sprite, Color.White);
- // remove this NoRenderArea
- RemoveFromNoRenderAreaList(NoRenderAreas[i--].Object);
- // we may have made some deferred grids renderable now
- RenderDeferred(sb, ref CenterGrid, DisplayAreaWidth, DisplayAreaHeight, ScreenWidth, ScreenHeight);
- }
- }
- }
- }
- // move to the next grid on the line
- CurX++;
- CurY--;
- }
- // increment our X axis limit
- if (++LimitX > EndX)
- {
- // this means our diagonal traversals are hitting the right most edge of the area
- LimitX = EndX;
- // we've also hit the bottom most edge of the area
- if (++StartY > EndY)
- {
- StartY = EndY;
- bEdgeY = true;
- }
- }
- // increment our Y axis limit
- if (++LimitY > EndY)
- {
- // this means our diagonal traversals are hitting the bottom most edge of the area
- LimitY = EndY;
- // we've also hit the right most edge of the area
- if (++StartX > EndX)
- {
- StartX = EndX;
- bEdgeX = true;
- }
- }
- // hitting both edges at the same time means we've run out of diagonals
- if (bEdgeX && bEdgeY) break;
- }
- sb.End();
- return;
- }
- }
- }
- //ObjectPool.cs :
- using System;
- using System.Collections.Generic;
- namespace IsoRender
- {
- public class ObjectPool<T> where T : new()
- {
- private Queue<T> unused = new Queue<T>();
- private LinkedList<T> used = new LinkedList<T>();
- private int MaxPoolSize;
- public int Count
- {
- get { return unused.Count + used.Count; }
- }
- public ObjectPool(int startingpool, int maxpool)
- {
- for (int i = 0; i < startingpool; i++) unused.Enqueue(new T());
- MaxPoolSize = maxpool;
- return;
- }
- public T GetObject()
- {
- T t;
- if (unused.Count == 0)
- {
- if ((MaxPoolSize > 0) && (Count >= MaxPoolSize)) return default(T);
- t = new T();
- }
- else t = unused.Dequeue();
- used.AddFirst(t);
- return t;
- }
- public void ReturnObject(T t)
- {
- if (used.Remove(t)) unused.Enqueue(t);
- return;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement