Isometric 2d rendering with MonoGame (XNA) and F#
open System | |
open Microsoft.Xna.Framework | |
open Microsoft.Xna.Framework.Graphics | |
open Microsoft.Xna.Framework.Storage | |
open Microsoft.Xna.Framework.Input | |
/// Logical type of a MapCell | |
type CellType = | |
| Empty | |
type MapCell(spriteBatch : SpriteBatch, cellType : CellType) = | |
member val Type : CellType = cellType with get, set | |
member val BaseTile : Texture2D list = [] with get, set | |
member val HeightTile : Texture2D list list = [] with get, set | |
member val BaseColor : Color = Color.White with get, set | |
member this.AddBaseTile (tile : Texture2D) = | |
this.BaseTile <- this.BaseTile @ [ tile ] | |
this | |
member this.AddHeightTiles (tiles : Texture2D list) = | |
this.HeightTile <- this.HeightTile @ [ tiles ] | |
this | |
// Draw the Tile | |
member this.Draw (x : int, y : int, tileSize : int) = | |
let rec draw_base (texList : Texture2D list) = | |
match texList with | |
| [] -> () | |
| tex::texList' -> | |
// devo scalarlo | |
spriteBatch.Draw (tex, new Vector2 (x |> float32, y |> float32), this.BaseColor) | |
draw_base texList' | |
draw_base this.BaseTile | |
type TileMap(width : int, height : int, spriteBatch : SpriteBatch) = | |
member val Width : int = width with get, set | |
member val Height : int = height with get, set | |
member val Cells : MapCell array = Array.init (width * height) | |
(fun i -> | |
new MapCell (spriteBatch, CellType.Empty)) | |
// Retrive cell at position (x, y) | |
member this.CellAt (x, y) = | |
this.Cells.[y * this.Width + x] | |
// Draw the TileMap | |
member this.Draw (indexX, indexY, startX, startY, tileSize) = | |
// dir = 0 -> sin, 1 -> des, 2 -> sindes | |
let rec drawLoop x y dir = | |
if x < 0 || y < 0 || x >= this.Width || y >= this.Height then () | |
else | |
let nx = startX + (x + y) * tileSize / 2 | |
let ny = startY + (x - y) * tileSize / 4 | |
this.Cells.[y * this.Width + x].Draw (nx, ny, tileSize) | |
if dir > 0 then drawLoop (x+1) (y) 1 | |
if dir <> 1 then drawLoop (x) (y-1) 2 | |
() | |
drawLoop 0 (this.Height - 1) 2 | |
type IsoGame() as this = | |
inherit Game () | |
do | |
this.Content.RootDirectory <- "Content" | |
member val graphics : GraphicsDeviceManager = new GraphicsDeviceManager (this) with get, set | |
member val spriteBatch : SpriteBatch = null with get, set | |
member val map : TileMap = new TileMap (0, 0, null) with get, set | |
member val tiles : Map<int,Texture2D> = Map.empty with get, set | |
override this.Initialize () = | |
base.Initialize () | |
// Load content, graphics and audio | |
override this.LoadContent () = | |
// Create the spritebatch | |
this.spriteBatch <- new SpriteBatch (this.graphics.GraphicsDevice) | |
// Create empty 2x2 tilemap | |
this.map <- new TileMap (10, 10, this.spriteBatch) | |
// Load tiles | |
this.tiles <- this.tiles.Add (1, this.Content.Load<Texture2D>("grass")) | |
this.tiles <- this.tiles.Add (2, this.Content.Load<Texture2D>("sand")) | |
// Create the map. This will be replaced with a map loader | |
for x in 0 .. this.map.Width - 1 do | |
for y in 0 .. this.map.Height - 1 do | |
(this.map.CellAt (x, y)).Type <- CellType.Empty | |
(this.map.CellAt (x, y)).AddBaseTile (this.tiles.[1]) |> ignore | |
override this.Update (gameTime) = | |
base.Update (gameTime) | |
override this.Draw (gameTime) = | |
this.graphics.GraphicsDevice.Clear (Color.CornflowerBlue) | |
// Draw the tilemap | |
this.spriteBatch.Begin () | |
this.map.Draw (0, 0, 0, this.Window.ClientBounds.Height / 2 - 16, 64) | |
this.spriteBatch.End () | |
base.Draw (gameTime) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment