Thursday 30 April 2015

Week Without a Post?

Could I leave you, my darlings, without a post for a whole week?... No, of course I couldn't.

So what is going on?... Well, I'm trying to arrange a Friday night D&D game with a group of mates - but two of them are being quiet on the availability, one doesn't have a webcam or mic to join in with, one is eager and I'm getting blue balls about the whole affair.

I've been playing some games, notably Cities Skylines, and I've been made to play a lot of H1Z1 Battle Royale for the wife, our best result has been #2 so far, so near, and yet so far from a win!

Today see's the release of WarThunder patch 1.70, their 1945 release, and it's biggest item for me is the new British Naval Aviation line, which I'll look forward to unlocking and getting to ace status.

Beyond all that, I think we're going to be busy Saturday, the father-in-law is having his boat launched (seriously, a whole boat) so we've got to go to that.  Then Sunday we're meant to be going to see some friends, but I don't know what that'll entail.  If I can throw together a D&D game and their kids are in the mood I'll drag that with me and make them play.

Development wise for the Dungeon Crawler, I've been tidying up some of the C++ code under the hood, and I've formally sorted out the XML loaders, so that's the format for everything, settings and screen layout will be the next feature I look at.  Doors are still a work in progress, and I'm still mulling the whole steps thing...

Saturday 25 April 2015

Beard Gate

I'm beginning to process the interactions I've had over the last week, with the grief and trying to keep busy I've shluft off a lot of stuff and am only now processing it... One item on the list was I had to collect one of the poodles from the clippers...

The lady who does the clipping, I've known her since 1989... So boy, teen and man... in 1994 I grew a beard...

So, 21 years... I've had a beard for 21 years....

She looked at me when I collected the dog the other day and said...

"Oh you're not growing a beard are you"

Go figure... Go figure.

Friday 24 April 2015

Dungeon Crawler - C++/SDL - Loading Maps

Very quick update, I've been taking the XML Maps from the Editor in it's current form and loading them into the actual game now, this has required a change of several subsystems inside the Grid/Map loading code.

The most important change has been caching one copy of each image, so minimising memory use, and then customising them at a surface level to add walls, drawing all this once and then just rendering the one single image we hold in RAM, whilst the rest of the images can be dropped out of memory to again free more resources.

Anyway, here's a screen shot of the game (background left) with the map editor open showing the map in design.


Path finding of course routes around the walls, and tiles can be toggles as blocking or not, opening up the ability now to add doors or even hidden/false/magic doors.

Thursday 23 April 2015

Dungeon Crawler - C++/SDL/C# - Map Editor Updates

So, the Map Editor, I made a brief mention of progress on Tuesday's post, but I've refined a few things, and I'm ready to show you some screenshots of how things look...


Here we see a tile set being imported, and placed down, then I've laid a set of dividers, a divider is a none-crossable wall like structure, but it lets us use a single square as a wall, rather than using a blank gap.


So, hopefully you can see that we can enclose spaces without so much blank black squares.

Which then leads to more complex structures:



The next item I'm literally coding now is a door, which will go into places as highlighted in red here...


Supporting single spans, or double spans...

And of course, once all this is designed into the map editor it's going to be ported into the game itself to give us the basics of the Adventure loading & walk through.


Wednesday 22 April 2015

Dungeon Crawler - C++/SDL/C# - Representing Stairs Challenge

So, the game, at the moment is totally top down 2D, there are no camera angles, no isometric perspective, it's just all looking straight down at the canvas below.

So, one challenge is how to represent depth, I've seen some art styles showing walls rising from an edge of a square and away to the centre, so it looks as though it's a wall climbing up towards the camera.

And, this effect is built in, not by the game, but by loading the pictures/images from disk, so anyone can draw like that.

One thing I can't do however is I can't draw, not very well, not on a computer.

And the next challenge facing me is how to represent stairs, if I can't do it easily with a single tile, do I need to make stairs which take up several tiles and have isometric effects to them, or do I need to increase the size of the tiles?

You see, there are options, which work to represent top down stairs...



That looks right to me, but it's done with shadows, alpha and importantly to work it all needs more than 70x70 resolution...  The same trick for me, using gradient brushes, at 70x70 comes out like this:



It's not the same is it?... No, I didn't think so.

Other options are to make stairs as I would with a biro on a table top map:



But, again this needs more pixels per tile, and definitely needs more than one tile.

Stairs going down are also a challenge, they need just as good a resolution which my tiles don't provide:



From http://www.cartographersguild.com/showthread.php?t=22407

Suggestions on a postcard please.

Tuesday 21 April 2015

General Blog - Dungeon Map Editor & The Day Job Office

At home I'm working on fleshing out the Dungeon Map editor, so there's more information coming on that later... To whet your appetites however, I have implemented:

* Solid Tiles
* Total Empty Void Space
* Dividing Walls
* Doors in single tile
* Doors over multiple tiles
* Trap doors (drops)

And in the works on the editor are:

* Stairs Up
* Stairs Down
* Portals

These latter three items however, all require a change to how I structure the Adventure....

So, an adventure now is going to be multiple maps, each map being a layer, and you can portal from one place on one map/layer, up to another map/layer (or down).

Stairs are the same, but you enter the map at the position it's placed directly above the stair (or below).

However, none of this is why I'm blogging today, I'm blogging because I just left the day job, and before I get in the car I thought I needed to point this out...

The company I work for is multi-million Euro turn over, it's huge... The building I work in has had major infrastructure upgrades, notably a fresh air circulation system and about £35,000 worth of new air conditioning and then brand new energy efficient triple glazing....

So, the new glazing keeps the heat in... The Air circulation system is never on, and the air-con is on warm....

I have had to turn a fan on today!

It's ridiculous, the guys in charge of the A/C controls sit in an area of the building which is taller than here, so it's more airy, they don't have the sunlight falling on their windows, and they're old - so they're always cold...

The rest of us, in the blazing sun box end of the building, just sit and gently sweat...

I've pointed out before that this end of the building smells like the inside of a training shoe, and they turned the air cycling system on, and it became so fresh, so light and a great place to work... But then they insist on keeping this system off!

It is annoying beyond irritation, beyond moaning, it's just endemic stupidity, and lack of understanding of people... Very much the "I'm all right Jack" attitude prevails.

It's been so warm, I've taken to rolling a glass of water from the cooler on my arms... and I'm only sat here in a cotton shirt!  Gah.

The atmosphere, the temperature, would have to be the second thing I decided on if I ran my own software shop/office somewhere.  The first being what desks, PC's, keyboards, Screens etc the peeps used.... Before I worried about the coffee machine, it'd be air conditioning and proper fresh air, not recycling the same stale air through a wall mounted unit on a circuit.

Monday 20 April 2015

Blog Views

We're in a unique position of two first, today is the first day my Blog has Russia as the top source of viewers (hello Russia - you strange lot you)... And also the first time the United Arab Emirates has featured on my top view count list... 


Friday 17 April 2015

D&D - Session 1

Last night, I had the pleasure of hosting my first D&D Fifth Edition game, now I did vastly simplify the rules and let lots of the detail slip, because not only was it my first time hosting, but it was my players first time playing.

So, we simplified the D20 use and the character sheets, but I kept the story rich and powerful, I'll relay the whole story below, with the options I gave people.

The adventure was in two parts, one needed no board and it constituted me taking the players together to a small village to get a task, the task was given by the inn keeper (a woman) to track down her son who had gone missing looking for treasure in the nearby mountains.

The party had to roll perception to spot a picture of the son, and note he wears a distinctive hat, and they could roll charisma with the inn keeper to negotiate their fee...

The party then had to move along the obvious path the guy took through the forest and to the foot of the mountains and the first dexterity and athletics tests were put to them, with a party of a rogue then two cloth wearers you could imagine the rogue would spring up the mountain side, but they rolled a 1... So fell flat on their arse, this made the other two more wary of climbing up, so they missed a surprise round here against a rat enemy in the entry way...

I had it scripted that there was a rat, if they killed the rat by getting up there quietly it could not run into the next room to alert the next enemy.  As it was they didn't surprise the rat, it saw them and ran off, and alerted the next enemy.

Meanwhile I had them see a fissure in the wall looking down on a grander room below, this was the end goal room, so the dungeon they were in was a simple four sided affair, but they can only see this room, so I ask for a perception/history check... They fail this...

So the elaborate story about the light below and foot prints in the thick dust was lost on them, all they got to be told about was a shabby carpet which looked like it might have once been grand.

Into the next room, it's a church like vault, rotten wooden pews line it and it's rubble at one end.  At this point I explained "light" for the wizard and they elect to light a coin and throw it to the back of the room, where they see the first enemy a cockatrice (vastly lowered in HP)... If they had not let the rat go, they would have faced four 1HP bats, not a 8HP cockatrice.

This thing takes a bite out of the rogue, it also takes a bite out the priest, but they subdue it and then I offered them a rest.

No-one searched the corpse, the rogue just opted to chop it up for meat, only to find it's bad meat and not for eating.

Next there's a set of rotten double doors, they peek around and the rogue uses slight of hand to spot a trap, which they avoid.

Unfortunately they left the light on the coin, now they're in the dark and I point this out, but the wizard fails to light the tip of their wand again and the rogue falls down a set of steps in the dark.

The Priest manages it down the stairs, only the wizard manages the stairs well, and so at the bottom of the stairs the wizard manages to light their wand again and they see two sets of doors, one left with a grill, and one dead a head.

The door to the left is an old cell, the priest opens the door, by bashing them with their club, the wizard lights a coin and throws it in, they see nothing save a pile of bones and old straw, so they leave the room alone.

If they had stepped in, they would face a short sword wielding skeleton... However, the wizard and priest both stop the rogue going in.

They instead try to peek through the closed double doors, and they managed with detect magic, to find out there's a flame skull beyond the doors...

They open it, and surprise it, gaining advantage, the wizard slows it, it hits the priest and hits the rogue, it also silences the priest, but they beat it down... Not before however it bloodies the rogue down to 8HP.

They heal up and rest here briefly, then search part of the room, and find an important story line item I invented the "Globe of life", filled with good green energy.

They history check on it and find this is a much fabled vial of pure life, it was what the flameskull was seeking to bring itself back to real life.  The priest tucks this away.

They move on, and enter the final room, which has two halves, the half with the rug they saw previously, and the half just in stone... In the corner is a prone bundle, which is the body of the inn keepers son.  The players didn't know this however, as they failed their checks on it... They know it's dead...

The rogue then did a detect traps and spotted a gargoyle about to pounce, they fought this down fast, and had it at 5HP, when it offered to parle.... But they refused and tried to kill it, getting it down to 1HP, where it slunk away... It would have told them to use the vial on the body... As it was however, they decided to use the vial on the body and it was the innkeepers son, it was a check someone did to see if it had a hat on did the trick...

He takes a breath and says "don't step on the rug"... So they didn't.

Not using the vial they would have faced him as a zombie and not been able to get home with him to get their reward.

However, they also open a treasure chest, this spawned the final boss, however, as they didn't stand on the rug she's only 1/4 her normal strength, and with the wizard using all their dailies she's burning and charred and the DOT takes her down on the third turn after opening the fight.

This was the end of the run, it worked out, the flameskull was the hardest enemy they faced, at no point were they close to a wipe.

Feedback
And in general feedback they decided the priest wanted more to do.

But each party member went away with 25 gold pieces each, some XP and a good grounding in the game mechanics.

Because the boss wasn't full strength they didn't get any special items, also because they didn't fight the skeleton the rogue missed out on a nice +1 short sword, and they didn't search a table in the flameskull room, so they missed 3 more gold pieces and some magic items for the priest and wizard.

But they missed this more through wanting to not take all night and getting to the end within two hours, so I may award them to the player character sheets with some story about adventures they've been on and add them some more skills, especially for the priest.

Thursday 16 April 2015

Dungeon Crawler - C++/SDL - VLOG 3

The third VLOG in this on going series, see's me finding I've unexpectedly broken token collision detection.... But I'm; at last; loading maps from the MapEditor.

I've also fixed scaling issues which were causing the map to scale to the screen when it was a map which was intended to be smaller than the view area of the screen.



Update 3.5


Wednesday 15 April 2015

Dungeon Crawler - C++/SDL/C# - Map Editor

My previous post today said, what have I been doing, You could imagine, not a lot of code, I've not been able to think... But today, I've thrown myself into the development again, and set about sorting out a map editor of some use.

I simply have to do something to distract me from my grief.

So, we can select the size of map we're working on, either from the pre-set sizes, or just entering a number:


Then we can select the brush we're using to draw tiles:


Adding Tiles:


We see the mouse over a tile with the orange surround:


Painting the brush is by pressing "1" for the first brush, and I'm going to add 2, 3, 4, etc. so you can have up to 9 brushes selected, basically the numpad will be key, with the floor tile (or even a random set of tiles) being numpad 5, and the 1 2 3 4 6 7 8 and 9 keys being the corners and walls, letting you quickly build a room or space.


You can also clear a tile with Delete...


The development efforts on this may soon be renamed "Spirit of Dude Development"...

RIP - Dude

Monday was perhaps the hardest, and worst day of my life, I had to have my loyal, gorgeous, eternal friend Dude put to sleep.

I can't say more about it, Jo and I are still so upset.



Dude
15th May 2003 - 13th April 2015

"Beloved by all who knew him"

Saturday 11 April 2015

Dungeon Crawler - C++/SDL - VLOG 2

Today, you see how I have identified a bug in the token drawing (since fixed) and I show you the integrated path finding in the game engine itself.

The rest of today is going to be all about map editing and selecting/loading a map into the engine, rather than that damn blank map of stone slabs.


Friday 10 April 2015

Dungeon Crawler - Making Tokens Follow Routes

The last two days of game development time have been dedicated to the test bed for routing, and that's all working nicely now.

So, I'm starting to look at the game itself, to decide how best to implement routing into the game.

My first step therefore has been to make the moving game tokens follow a set of steps... Each step being a point within a queue of points, called a route.




Each time the token comes to rest, from the previous step, it looks for a new step to move onto, or it's done moving...


At the moment this is not a proper route, next I need to make the route be calculated, just as it is with the path finding test bed.

But again, I need to load the blocked (adventure) map into the actual program first.

--- Please also note, I just happen to have called this project "Dungeon Crawler", since starting it I've seen videos around of a different project in the same vein... We're not related projects.

Thursday 9 April 2015

Dungeon Crawler - 2D Path Finding

I've had to create a test-bed piece of code for the path finding, so this means there's been no changes to the game side of the code, all the work I've been doing on things over the last couple of days has been about the path finding and it's been in this test-bed application.


So, the application lets me see the grid (or graph if you're a mathematician), I can select the start point, the end point, set blocked grids and then ask it to calculate a route.

The algorithm I've used is an A* algorithm, but a greedy one, and then I've added back-tracing to allow it to get out of dead-ends (such as in a room with a narrow opening) and finally added simplification to the end result route.

The calculation of the route and back tracing is automatic, the simplification however, I've made a manual operation, so I can see how the routes come out of A* before I alter the list of plotted points.

Without the back tracing this is how it could get stuck:


And now, it back traces to the next best nearest grid point to continue the route without getting stuck or going over the points it's already found got it stuck:


And finally, I can apply a simplification to that solution:


I'm now pushing it further, asking the test-bed to work it's way around simple dungeon style rooms, here we see the route from inside one room, down a set of halls and into a cell within another area...


Simplify this result:


And it's quite neat.

The test-bed needs some more features, such as loading/saving the background blocks, making the start of a rudimentary map editor!

Once I'm more happy with the algorithms and heuristics I'm using, then I'll start to tidy the code and then port it into classes for use in the Dungeon game... And finally I'll start to make the movement routines take the list of points to go between...

Note: Since writing this draft, I've continued the work and testing... Only to find a strange problem, which was working, but I've somehow broke, here we see a grid... The Route can continue, but it just stops...




Hmmm, what have I done wrong?


-- Addition --

Since posting this last night at half six, I worked out the bug resulting in this dead end problem above, here's the result now:


Then simplification run on this route:


The challenge now is to simplify, clean up and better document this code.  Then to port it to clear easy to maintain C++


Wednesday 8 April 2015

Dungeon Crawler - C++/SDL - VLOG 1

For Part Two, click here.

This is my first VLOG on the topic of my dungeon crawler... Sorry about the echo in the last couple of minutes, no idea how that happened:



My first (ever) VLOG about the development of my 2D Dungeon Crawling Game & supporting classes in C++ with SDL.

Sorry about the echo after around 11 minutes - I have no idea how that started to happen, and I will not let it happen again, it was not spotted until I had uploaded this.

For more information about this project, and other projects I'm working on, the best place to check out is my blog at http://megalomaniacbore.blogspot.com

*Tutorials Used*


*Libraries*

See my other videos for more information on using Boost.


*Pathfinding*


Monday 6 April 2015

Using Java & Eclipse to Write a Game - Pt 3

The third week of our Java Game Tutorial, and hopefully you've had a lot of time to play with the growing Dots, the 2D draw, maybe you've had a play and made the rendering loop draw other things...

Because this week, we're going to look at something dungeon related, the grid or map, we're going to make our play area.

First things first though, we no longer want the background to react to clicking and go red, so we need remove the "m_LeftButton" flag, and it's used in the mouse pressed & mouse released functions.  Then we need remove it from the rendering loop.


We draw the background all black now, because we can't "see" anything.  In a moment we'll draw a grid of squares, or tiles, which we will move characters around on; but later we'll also be looking at how far those characters can see, and so how much of the black they push back.


Of course, drawing a grid so, we also don't want those seeds to grow, but we'll only stop them planting, so we can go to the mouse pressed function and just comment out the call to "AddSeed".


Commenting out means we leave the code in place, but the compiler when it builds the code into a program will skip that line.  To make it a comment therefore we add "//" at the from.

There are other ways to do comments, but for now stick to this method only, we'll cover the pit falls of other problems.

So, onto the new Grid code, lets create the Grid class....


And give it a name...


And so we get the new text file as a tab to edit...


Next time we create a class, I won't be documenting all these parts of the process again, I'll just say we're creating some named class.

So, what do we need to know about our grid?.. Well a size, so we need a width and a height, then we need to pass these values into the constructor.


To draw the grid we need to pass the Graphics2D context to it, do we'll add that function, and how about an Update function too, so we can animate things on the grid later.


The problem now is what to draw?... Well, we've not defined any data for the Grid yet, so how about we create a new class called a Tile.

Inside the tile, what is is going to represent?.. Well It's going to be a square on our grid... Which characters stand on, lets say they stand on a stone floor, the tile need to have a type inside it, something to tell us it is meant to represent a Stone Slab...


So how do we do this?  Well, there are things called "enums" which are a bit like a new type for us to use, and they are all the same "type" datawise, but they can have different labels inside, so we might have "TileType" and inside "Wall", "Floor" and so forth.


We've already seen one enum used, this was the "java.awt.Color", which has different colours inside.

We'll create our "TileTypes" enum, as follows:


And then we'll just add two types, "Blank" and "UNKNOWN".  We will always keep "UNKNOWN" as the last type in the list.


We can now use the "TileTypes" enum just like any other type in the language, such as "int" or "string" or boolean!

In our code though we also want to draw the tile, and perhaps also update the time, so we'll add those two functions now...


We need to be a little coy now, we can't draw a tile yet, because we don't know where it is on the screen, nor how big it is, but lets say that a tile is going to always be a fixed width and height, we can define those as constants, or finals...


Included in that we now have a top and a left for the tile, and can now define what we draw...


This is a new structure, where we can quickly jump down to the code we want to act upon, based on the value of the TileType.  So, when this is "BLANK" from the enum, we jump to set the colour to black, otherwise the colour is white.

Now we just draw a square...


Jumping back to the grid we now need a set of tiles to draw, for this we'll use a multi dimensional array, so each entry on the first set of the array is another array.... Meaning we can have "m_Tiles[1][3]" and it will go to that tile!


Of course we've just created the space for tiles, we've not gone through and set each tile to any type...


But, we need to know where to place each tile... This is going to be based on the size of the tile... 


The first thing you should see with adding this code change however, is that from inside the "Grid" you can't get at the two constants "c_Width" or "c_Height" inside the "Tile"... How come my code shows no error?

Well, I have gone back to the Tile and I've set those two constants "Static", this means I can access those as values of the type or class without actually needing to be inside a copy of the clas (it means more than that, but for now, roll with it).


Right, then... We have a grid of tiles, the tiles will draw themselves, lets flesh out the grid draw function...


And the update function...


Finally, jumping back to the main window, we now need a grid... lets make it create as a 10 x 6 area... And add a call to draw it...


Then to draw it...

Lets have a look what that looks like...


Everything is black... I've cleared the background to black, and I've made the tiles draw black... Hmmm, what should we do?

Well, I don't want the tiles to worry about drawing their outside or border, I want the grid to draw the borders, so we can turn them on or off later, and so that we can highlight the selected tile on the grid.

Lets jump to the Grid drawing function and make it now draw the borders....


How does that look?...


Was that what you were expecting?... It was what I expected, but perhaps you didn't see this coming?... What's going on?...

Well, as we move across the grid we draw and redraw the tiles, so each tile draws a black square, then the grid draws the border, the next tile then draws it's black and they overlap by a pixel, because we've not spaced them out.

So that black next tile scrubs out the border of the previous drawing.

To get around this we need to do one of two things, or eventually just move the tiles, but for now, we jump back to the grid class and change the border drawing...


So, we draw all the tiles, then draw the borders, this means we go over the loops twice, but does it fix our drawn image?...


Yes!

This is a good lesson to learn, we've done two passes over the same loops, to draw one set of tiles.  Avoiding too many repeats, especially as the data/grid size gets bigger, is important.

Still, our tiles don't look how I really want them, I'd like them to be a bit larger.  This is easy to fix, we just jump to the Tile code and change the width and height constants.

Because we've used constants and made them static for use in all the other classes wanting to know the size of a tile, we can now just change the constants once, rebuild the code, and it'll all fall into place... Lets try some different sizes.

Or...

I like that last size, so we'll stick with that... But we've already got another problem, the tiles to the right and bottom rows are now slipping off the screen.

I'm not going to worry about that directly, we next week we're going to look at scrolling the view around to see huge maps, 100x80 or 1000x800!

However, to help me understand what's happening now, and what might happen when we scale up to scrolling, I'm going to add some text to tell me the index of each tile.  This means drawing text.


First off, from the existing Clear Tiles in the grid, we now want to just tell the Tile the X and Y position, we'll let the tile itself calculate it's intended left and top inside.

And the Tile itself...


Running this code up now, gives us the same as the last run, but now we can jump to the Tile Draw and put the text for the "m_X" and "m_Y" values into the tiles top left corner!


So, we set the colour to yellow, build the coordinates as a string, and draw them just down and slightly to the right inside the tile.


Now, when we come to scrolling the grid around we're fore armed with the numbers of the grid in the tiles so we'll know where we are.

Final code clean ups, I'm going to go into the MainWindow and define two final static constants for the grid size to use, so we'll not have 10 and 8 coded directly into the MainWindow call to "new Grid", instead we'll have these two new constants.

We've changed the size of the tiles, we've can now change the size of the grid... Why not have a few experiments...

We can also go to the Run function and remove the "Starting Run" and "Ending Run" calls.  And the same println call in the main function, just to tidy up our code.  We can remove the rest of the Seed & Dot stuff as well...

---- MainWindow ----

package display.display;

import java.awt.Canvas;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class MainWindow extends Canvas implements MouseListener, WindowListener 
{
// The minimum Resolution Values
private final int c_MinWidth = 800;
private final int c_MinHeight = 600;
// The default grid size
private final int c_GridWidth = 100;
private final int c_GridHeight = 80;
// The master game loop exit flag
private boolean m_GameRunning;
// The seeds of our clicks
private java.util.Queue<java.awt.Dimension> m_Seeds = null;
// The list of expanding dots
private java.util.ArrayList<Dot> m_Dots = null;
// The window frame
private javax.swing.JFrame m_WindowFrame;
// The drawing strategy (refreshing)
private java.awt.image.BufferStrategy m_Strategy;
// The grid
private Grid m_Grid = null;
// Constructor - can be private, we only internal
// members of this class (i.e. main) will be calling
// to create a main window.
private MainWindow ()
{
CreateWindow();
AddPanelAndCanvas();
CreateBufferingStrategy();
m_Grid = new Grid(c_GridWidth, c_GridHeight);
}
// Create the buffering strategy
private void CreateBufferingStrategy()
{
this.setIgnoreRepaint(true);  // Ignore the windows paint event
this.createBufferStrategy(2); // Two buffers, one on and one off screen
m_Strategy = this.getBufferStrategy();
}
// Adds a panel to the JFrame, and this panel
// fills the whole area of the window, into that
// we then add our Canvas, which is "this"
private void AddPanelAndCanvas()
{
// The panel in the middle area
javax.swing.JPanel l_Panel = (javax.swing.JPanel)m_WindowFrame.getContentPane();
l_Panel.setPreferredSize(new java.awt.Dimension(c_MinWidth, c_MinHeight));
l_Panel.setLayout(null);
// Set our Canvas properties of size
this.setBounds(0,  0, c_MinWidth, c_MinHeight);
// Add the canvas to the panel
l_Panel.add(this);
}
// Create the Window - we're going to use Swing
private void CreateWindow()
{
m_WindowFrame = new javax.swing.JFrame("Dungeon"); // This is the window title text 
m_WindowFrame.addWindowListener(this); // Adding "this" to the frame
// means our MainWindow code as
// it is running will receive the
// Window events, like close & move
// Direct the mouse events to the
// canvas itself
this.addMouseListener(this);
m_WindowFrame.setSize(c_MinWidth, c_MinHeight);
m_WindowFrame.setVisible(true);
}
@Override
public void windowActivated(WindowEvent arg0) 
{
// TODO Auto-generated method stub

}

@Override
public void windowClosed(WindowEvent arg0) 
{
// TODO Auto-generated method stub

}

@Override
public void windowClosing(WindowEvent arg0) 
{
// TODO Auto-generated method stub
m_GameRunning = false;
}

@Override
public void windowDeactivated(WindowEvent arg0) 
{
// TODO Auto-generated method stub

}

@Override
public void windowDeiconified(WindowEvent arg0) 
{
// TODO Auto-generated method stub

}

@Override
public void windowIconified(WindowEvent arg0) 
{
// TODO Auto-generated method stub

}

@Override
public void windowOpened(WindowEvent arg0) 
{
// TODO Auto-generated method stub

}

@Override
public void mouseClicked(MouseEvent arg0)
{
// TODO Auto-generated method stub

}

@Override
public void mouseEntered(MouseEvent arg0)
{
// TODO Auto-generated method stub

}

@Override
public void mouseExited(MouseEvent arg0)
{
// TODO Auto-generated method stub

}

// Adds a seed to the list of places the
// mouse was clicked, since we last
// updated
private void AddSeed(int p_X, int p_Y)
{
if ( m_Seeds == null )
{
m_Seeds = new java.util.LinkedList<java.awt.Dimension>();
}
m_Seeds.add(new java.awt.Dimension(p_X, p_Y));
}
@Override
public void mousePressed(MouseEvent p_Event)
{
// Left click
if ( p_Event.getButton() == MouseEvent.BUTTON1 )
{
//AddSeed(p_Event.getX(), p_Event.getY());
}
}

@Override
public void mouseReleased(MouseEvent p_Event)
{
if ( p_Event.getButton() == MouseEvent.BUTTON1 )
{
}
}
// Add a Dot
private void AddDot(Dot p_newDot)
{
if ( m_Dots == null )
{
m_Dots = new java.util.ArrayList<Dot>();
}
m_Dots.add(p_newDot);
}
// Update the scene
private void Update(long p_Milliseconds)
{
// There are seeds
if ( m_Seeds != null )
{
// if we have seeds, add them
if ( !m_Seeds.isEmpty() )
{
// Dequeue each seed point and
// create a new expanding Dot
java.awt.Dimension l_Location = m_Seeds.remove();
Dot l_newDot = new Dot((int)l_Location.getWidth(), (int)l_Location.getHeight());
// They maybe called Width and Height, but
// really we're using them as two numbers...
AddDot(l_newDot);
}
}
if ( m_Dots != null && !m_Dots.isEmpty() )
{
// For each dot, update them
for (int i = 0; i < m_Dots.size(); ++i)
{
m_Dots.get(i).Update(p_Milliseconds);
}
}
}
// Draw the dots
private void DrawDots(java.awt.Graphics2D p_Graphics)
{
if ( m_Dots != null && !m_Dots.isEmpty())
{
for (int i = 0; i < m_Dots.size(); ++i)
{
m_Dots.get(i).Draw(p_Graphics);
}
}
}
/// The function we "run" from the main
/// function, to go into a loop, rendering
/// the game
private void Run ()
{
m_GameRunning = true;
// Game timing/update delta
long l_Time = System.currentTimeMillis();
long l_now;
long l_delta;
while (m_GameRunning)
{
// Get the time now, and work out the difference
l_now = System.currentTimeMillis();
l_delta = l_now - l_Time;
// Only if we are at the time, draw
if ( l_delta > 33 )
{
Update(l_delta);
// Get the graphics into which
// we can draw
java.awt.Graphics2D l_Graphics = (java.awt.Graphics2D)m_Strategy.getDrawGraphics();
// Clear the map background as black
l_Graphics.setColor(java.awt.Color.black);
l_Graphics.fillRect(0, 0, this.getWidth(), this.getHeight());
// Draw the grid
if ( m_Grid != null )
{
m_Grid.Draw(l_Graphics);
}
// After the update of the background colour,
// call to draw the dots
DrawDots(l_Graphics);
// Show this frame of graphics
// we've drawn
m_Strategy.show();
// because we did a draw, set time to now
l_Time = l_now;
}
Yield();
}
}
// Quick and dirty yield function, to
// release the CPU time whilst in the
// run loop
private void Yield()
{
try
{
Thread.sleep(2);
}
catch (Exception e)
{
System.out.println("Exception [" + e + "]");
}
}
public static void main(String[] args)
{
MainWindow l_Instance = new MainWindow();
l_Instance.Run();
}
}

---- Dot.java ----

package display.display;

public class Dot
{
private final int c_MinimumSize = 1;
private final int c_PixelsPerSecond = 2;
private int m_OriginX, m_OriginY;
private long m_Age;
public Dot(int p_X, int p_Y)
{
m_Age = 0;
m_OriginX = p_X;
m_OriginY = p_Y;
}
public void Update(long p_Delta)
{
m_Age += p_Delta;
}
public void Draw(java.awt.Graphics2D p_Graphics)
{
// Calculate the radius
int l_RadiusInPixels = c_MinimumSize + ((int)(m_Age/1000)*c_PixelsPerSecond);
int l_half = (int)(l_RadiusInPixels / 2);
int l_startX = m_OriginX - l_half;
int l_startY = m_OriginY - l_half;
p_Graphics.setColor(java.awt.Color.pink);
p_Graphics.fillOval(l_startX, l_startY, l_RadiusInPixels, l_RadiusInPixels);
}
}

---- Grid.java ----

package display.display;

public class Grid
{
// Size
private int m_Width, m_Height;
private Tile[][] m_Tiles;
// Draw options
private boolean m_DrawBorders = true;
// Constructor
public Grid(int p_Width, int p_Height)
{
m_Width = p_Width;
m_Height = p_Height;
m_Tiles = new Tile[m_Width][m_Height];
ClearTiles(TileTypes.BLANK);
}
private void ClearTiles(TileTypes p_Type)
{
for (int y = 0; y < m_Height; ++y)
{
for (int x = 0; x < m_Width; ++x)
{
m_Tiles[x][y] = new Tile(p_Type, x, y);
}
}
}
public void Draw(java.awt.Graphics2D p_Graphics)
{
// Just draw the tile contents
for (int y = 0; y < m_Height; ++y)
{
for (int x = 0; x < m_Width; ++x)
{
m_Tiles[x][y].Draw(p_Graphics);
}
}
if ( m_DrawBorders )
{
// Draw all borders
for (int y = 0; y < m_Height; ++y)
{
for (int x = 0; x < m_Width; ++x)
{
// Draw a border
p_Graphics.setColor(java.awt.Color.gray);
int l_Left = x * Tile.c_Width;
int l_Top = y * Tile.c_Height;
p_Graphics.drawRect(l_Left, l_Top, Tile.c_Width, Tile.c_Height);
}
}
}
}
public void Update(long p_Milliseconds)
{
for (int y = 0; y < m_Height; ++y)
{
for (int x = 0; x < m_Width; ++x)
{
m_Tiles[x][y].Update(p_Milliseconds);
}
}
}
}

---- Tile.java ----

package display.display;

public class Tile
{
// The width and height of a tile is fixed
public static final int c_Width = 80;
public static final int c_Height = 80;
// The type of the tile
private TileTypes m_Type;
// The X Y of the tile
private int m_X, m_Y;
// The top left corner position of the tile
private int m_Top, m_Left;
// Constructor
public Tile(TileTypes p_Type, int p_X, int p_Y)
{
m_Type = p_Type;
m_X = p_X;
m_Y = p_Y;
m_Top = m_Y * c_Height;
m_Left = m_X * c_Width;
}
public void Draw (java.awt.Graphics2D p_Graphics)
{
switch (m_Type)
{
case BLANK:
p_Graphics.setColor(java.awt.Color.black);
break;
default:
p_Graphics.setColor(java.awt.Color.white);
}
p_Graphics.fillRect(m_Left,  m_Top, c_Width, c_Height);
// The X Y Text
p_Graphics.setColor(java.awt.Color.yellow);
String l_Coords = "[" + m_X + ", " + m_Y + "]";
p_Graphics.drawString(l_Coords, m_Left + 5, m_Top + 15);
}
public void Update(long p_Milliseconds)
{
}
}

---- TileTypes.java ----

package display.display;

public enum TileTypes
{
BLANK,
UNKNOWN
}