• Advertisement
  • entries
    707
  • comments
    1173
  • views
    434679

Untitled

Sign in to follow this  

248 views

I've been working on implementing a tile engine that is flexible enough to be able to use across genres and dimensions. It's going pretty well so far. I haven't had much time to test it, but on paper it seems to do what I want.



This is a test of the new viewport system (previously the camera system, but I came to realize that cameras and viewports were pretty different, so I split the two and stole the name from Drew.)

Currently the system is setup as so:
ITileBrush : Contains the visual information stored in a palette's brush.
TileBrush : A basic implementation of ITileBrush.
TilePalette: A collection of ITileBrush instances used for rendering a tile-terrain.

ICellData : Contains the brush index for rendering and any game-specific information the game needs.
CellData :A basic implementation of ICellData.

TileTerrain : Contains an array of ICellDatas, it's size, the a cell scale, and some access methods.

ITerrainRenderer : A simple interface for rendering a tile-terrain. Requires a terrain, palette, camera, and viewport.
BasicTerrainRenderer : A renderer setup to use the basic implementations and my Render2D rendering library.

Nothing too advanced, but it works really well. I've done a simple RPG style map, a platformer map, and a simple 3D heightmap as tests.

Here's the code I used to set it the example (mostly in the Initialize() method because I don't have data files implemented for the system yet, so I have to enter it all by hand):

namespace SlimDX_Game_Template
{
public partial class Engine : EngineBase
{
Render2D.Renderer renderer = null;

Random rng = new Random();

TilePalette tilePalette = null;
TileTerrain tileTerrain = null;
ITerrainRenderer terrainRenderer = null;
Camera[] cameras = null;
Viewport[] viewports = null;

public Engine()
: base("Prototype", 1024, 768, true)
{
}
protected override void Initialize()
{
base.Initialize();

Mouse.ButtonUp += new MouseEventHandler(Mouse_ButtonUp);

renderer = new Render2D.Renderer(GraphicsDevice);

tilePalette = new TilePalette();
D3D9.Texture TileTexture = this.LoadTextureFromFile("MishMash.png");
for(int Row = 0; Row < 23; ++Row)
{
for(int Column = 0; Column < 23; ++Column)
{
tilePalette.Brushes.Add(new TileBrush
{
Texture = TileTexture,
Region = new Drawing.Rectangle(
Column * 32,
Row * 32,
32,
32),
});
}
}

tileTerrain = new TileTerrain(100, 100, 1);
terrainRenderer = new BasicTerrainRenderer(renderer);

int brushColumn = 0, brushRow = 0;
for(int Row = 0; Row < tileTerrain.size.Height; ++Row)
{
for(int Column = 0; Column < tileTerrain.size.Width; ++Column)
{
tileTerrain.SetCell(Column, Row, 0, new BasicCellData
{
BrushIndex = ((brushRow % 23) * 23) + (brushColumn % 23)
});
++brushColumn;

}
brushColumn = 0;
++brushRow;
}

List cams = new List();
List views = new List();

for(int Index = 0; Index < 64; ++Index)
{
views.Add(new Viewport
{
Location = new Drawing.Point(Index % 8 * (1024 / 8), Index / 8 * (768 / 8)),
Size = new Drawing.Size(1024 / 8, 768 / 8),
});

cams.Add(new Camera
{
Eye = new Vector2(rng.Next(0, 1024 - (1024 / 8)), rng.Next(0, (768 - (768 / 8)))),
});
}

cameras = cams.ToArray();
viewports = views.ToArray();
}

int selectedCamera = 0;
void Mouse_ButtonUp(object sender, MouseEventArgs e)
{
for(int Index = 0; Index < Math.Min(cameras.Length, viewports.Length); ++Index)
{
if(viewports[Index].ContainsPoint(e.Location))
{
selectedCamera = Index;
continue;
}
}
}

protected override void LoadContent()
{
base.LoadContent();
renderer.OnResetDevice();
}

protected override void Update(float FrameRate)
{
base.Update(FrameRate);

if(Keyboard.KeyIsDown(Keys.Left))
{
cameras[selectedCamera].Eye.X -= (128.0f * FrameRate);
cameras[selectedCamera].Eye.X = Math.Max(cameras[selectedCamera].Eye.X, 0);
}
else if(Keyboard.KeyIsDown(Keys.Right))
{
cameras[selectedCamera].Eye.X += (128.0f * FrameRate);
cameras[selectedCamera].Eye.X = Math.Min(cameras[selectedCamera].Eye.X, (tileTerrain.size.Width * tileTerrain.cellScale) - viewports[selectedCamera].Size.Width);
}

if(Keyboard.KeyIsDown(Keys.Up))
{
cameras[selectedCamera].Eye.Y -= (128.0f * FrameRate);
cameras[selectedCamera].Eye.Y = Math.Max(cameras[selectedCamera].Eye.Y, 0);
}
else if(Keyboard.KeyIsDown(Keys.Down))
{
cameras[selectedCamera].Eye.Y += (128.0f * FrameRate);
cameras[selectedCamera].Eye.Y = Math.Min(cameras[selectedCamera].Eye.Y, (tileTerrain.size.Height * tileTerrain.cellScale) - viewports[selectedCamera].Size.Height);
}
}

protected override void Frame()
{
base.Frame();

renderer.Begin();

for(int Index = 0; Index < Math.Min(cameras.Length, viewports.Length); ++Index)
terrainRenderer.Render(tileTerrain, tilePalette, cameras[Index], viewports[Index]);

for(int Index = 0; Index < Math.Min(cameras.Length, viewports.Length); ++Index)
renderer.DrawRectangle(viewports[Index].Location.X, viewports[Index].Location.Y, viewports[Index].Size.Width, viewports[Index].Size.Height, 1, Drawing.Color.Red, Drawing.Color.Red, Drawing.Color.Red, Drawing.Color.Red);

renderer.End();
}

protected override void FreeContent()
{
renderer.OnLostDevice();
base.FreeContent();
}

protected override void OnDispose(bool Disposing)
{
if(Disposing)
{
if(renderer != null)
renderer.Dispose();
}

renderer = null;
base.OnDispose(Disposing);
}
}
}


(Some of the names might not match the above; I'm in the middle of changing them.)

That's all for now. G'night Journal Land!
Sign in to follow this  


2 Comments


Recommended Comments

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement