Video of the remade Isometric Engine

Quick video showing the zoom and height map.

The tile world is using a rather excessive pre randomly generated 500×500 tiles so 250,000 in total – for testing purposes only, this would be broken down into zones in later stages.

The engine now supports rotation, lossless zooming, height maps and tile shadows as well as a far better drawing approach.

Still need to implement the previously created functionality but it shouldn’t take long as we have already created the path-finding to support our new tile organisation methods.

Sorry for quality of video, not sure the best way to go about making these and can never get it to look as smooth and fast as it really does!

Posted in Uncategorized | 4 Comments

Perhaps a small update.

Although Glacial Flame did come to a halt due to available of time I have been rewriting the engine behind it over the last few months. It is set and built to contain all of the previous features and a few more as well as now being properly optimized and even more smooth.

The new aspects of the engine can be seen bellow.

Height maps have been added which can be easily toggled on and off.

When creating the initial ground layer you can perform the following:

ground_level.stack_tiles(height_map_layout,”5-ground-block.png”);

height_map_layout is the array containing the different heights for each tile and “5-ground-block.png” represents the image to use.

Engine now contains “simple” rotation where you can rotate around the world to view from 4 angles.

Of course, no isometric engine would be complete without gradual smooth zoom. Tiles are created larger than the set width and heights meaning the Canvas draw resizes. This means when zooming detail doesn’t become pixely. The drawing algorithm also takes into account for larger height tiles such as trees. The width and height proportions are set when the isometric object is created

ground_level = new isometric(context,50,25,ground_map_layout, ground_graphics,ground_dict,28);

50 and 25 being the proportions.

And then rotated when zoomed in.

 

With height map shadows toggled on. You’ll need to excuse the tiles that contain trees just now, currently the shadow function works out the start of the tile meaning it isn’t taking into accord for the height (yet).

 

Some other features contain:

objects_level.alpha_mouse_behind = 1; // Allows you to alpha the objects in front of the mouse pointer.

objects_level.hideGraphics(true,0,6,”7-normal.png”); // Allows you to mass replace a range of graphics with other tiles on the fly. Will be properly useful when you are outside of a building and obviously shouldn’t be able to see inside.

ground_level.setPosition(10,10); // Jump to point on the map

ground_level.draw_tiles = 28; // Number of tiles to draw in viewport

objects_level.align(“h-center”,706);

objects_level.align(“v-center”,425); // used for aligning your map to the centre of your canvas element (useful when in a small 4×4 room).

 

But yeah, there has been isometric work, just got to get on top of my  real work and university stuff first and then there will be more!

 

 

Posted in About Glacial Flame, Canvas, Javascript, Technology, Tile World | 10 Comments

A post….!?

Well I just sat through over 1500 comments of spam looking for the small few which where genuine posts. From buying a Jennifer Aniston to suing over cracked eggs was covered. I apologise for the zero activity all of a sudden to this project and lack of replies to posts. Sadly with University and bills to pay it got put to the burner. I’m mid way through my Masters right now in Advanced Computer Science but I really want to continue this series and perhaps cover other aspects of Canvas games. Right now I’m finishing off a few industry work things that should let me then lower my industry work a bit (for a while) and allow me to hopefully give more time for hobby programming e.g. this. Although with my Thesis moving in closer and so on I can’t promise anything.

I’ll try and reply to all comments that have been left tonight even though I’m sure answers have been found and methods picked up from elsewhere!

Again sorry for no action on this project,

Best,

Iain

Posted in Uncategorized | 1 Comment

Diamond Isometric map scrolling Part One

First off the reason this tutorial is referred to as diamond isometric is because we will be wrapping up on the simpler isometric method soon. This tutorial is split into two parts. Part one covers the simple scrolling and displaying only a visible area of the map. The second tidies up the offsets we have added as well as implementing a further method to keep our drawing minimal and overall speeding up our game.

What is this diamond method you speak of you ask?

It’s basically what we have been using so far. If you look at your isometric map it is a diamond. It is by far the simplest method of drawing out your tiles as well as keeping track of player positions, interactions and other such game requirements like path finding. The tutorial after this written up by Ed will cover the path finding and AI basics for this sort of isometric map. This tutorial will cover producing a large scrolling isometric map and some optimization techniques to help speed things up in canvas.

What we aim to have at the end of this is a large smooth scrolling 100×100 tile map which only draws the most required tiles. We will have a startX and startY range which when calculated will be the starting point in the array for our draw function. This alone would reduce the above screenshot like so:

With only the tile rows being drawn that are needed to fill the screen we have already reduced our 10,000 tiled map to 49 tiles at a time. If this is for multiple layers then that is a huge saving. On top of this we can use a second tile limiting method which I found also contributes to keeping that frame rate high meaning Ralph can avoid those possessed water coolers worry free.

Using startX and startY within our array we can work out easily what the middle tile is on screen. With a couple of small conditional checks you can check the distance of the surrounding tiles and make sure they are worth drawing. For example in the above screenshot, due to our diamond system we have the point unseen tiles on all four sides still being drawn. The outcome would look like this:

Taking the total drawn tiles from 49 down to 28.

So we’ll just dive straight in and fire out our scrolling.

Just following on from tutorial 7: http://glacialflame.com/tutorials/tiles/06/

First change to make if you are still using a small viewport is to increase its width and height to a decent size. Perhaps even centre it. (make sure you update the clearRect to match your new sizes e.g. ctx.clearRect(0,0,500,500).

Using the following little script I had a random array of 100×100 tiles made up:

http://glacialflame.com/tutorials/tiles/07/gen.php?x=100&y=100&type=array

The array it generates is just made up of 0s and 1s.

If you replace the current contents of both the map and objectMap with a random generate array as well.

If you declare at the top with the rest of your global variables:

var mapXD;

var mapYD;

These two variables will hold the direction we are scrolling.

In the mouseCheck(e) function add the following anywhere under where x and y are set. As the width I’m using is 500, I set it to have a 100 space

	  if(x - canvas.offsetLeft> 400 ){
	   	  mapXD= 1;
	  }else if(x -canvas.offsetLeft < 100){
		  mapXD =2;
	  }else{
		  mapXD = 0;
	  }
   	   if(y - canvas.offsetTop > 400){
		  mapYD= 2;
	  }else if(y - canvas.offsetTop < 100){
		  mapYD =1;
	  }else{
		  mapYD = 0;
	  }

In the drawMap() function add the following before the draw loops:

if(mapXD == 1){mapX -= 5;}

if(mapXD == 2){mapX += 5;}

if(mapYD == 1){mapY += 5;}

if(mapYD == 2){mapY -= 5;}

And that’s all that is required for the scrolling part. Using the mouse we can now move around our large world as we please. The first issue here is we have 10,000 tiles being drawn at the same time, and although it may or may not run smooth depending on your pc specs there is some demanding improvements to be made.

Add the following to the drawMap after the previous addition of code:

		startY= mapY+(mapX/2);
		startX=(startY-mapX);
		startY=Math.round(-startY/25);
		startX=Math.round(-startX/25);
		if(startX  < 0){startX = 0}
		if(startY < 0){startY = 0 }

And update your two tile drawing for loops to reflect the following:

for(i=startX;i<map.length;i++){

for(j=startY;j<map[i].length;j++){

The startX and startY defines where to start within the map array from position of your map according to its mapX and mapY values.

If you test your code now you will see that you always have a pointing tip to your map.

Next up we will add a range of tiles to draw.

Declare another two variables within the drawMap()

var rangeY = 10;

var rangeX = 10;

Then add the following before draw your for loops once again

if(startY+rangeY > map.length){ rangeY =  map.length-startY;}

if(startX+rangeX > map.length){ rangeX =  map.length-startX;}

Finally update your loops to take in the range.

for(i=startX;i<startX+rangeX;i++){

for(j=startY;j<startY+rangeY;j++){

rangeX and rangeY represent how many tiles you wish to draw. If you run your code you will see it should scroll properly but may need some adjustments. If your finding your map keeps running away then the following will need updated:

var xpos = (i-j)*tileH+ mapX;

var ypos = (i+j)*tileH/2+ mapY;

In my case my mapX needed reversed with a further offset applied:

var xpos = (i-j)*tileH - mapX + 235;

var ypos = (i+j)*tileH/2+ mapY+50;

These offsets and ranges will all need customized to your specific tiles and how much you wish to draw. With the right offset and tile range you can fill your screen no bother and keep drawing to a minimum.

var mapX = 0;
var mapY = 0;

For the purpose of this part of the tutorial I set the initial mapX and mapY globals to zero.

The next part of the tutorial will cover fixing the mouse for your new offsets and adjusting the range to fill your viewport as well as the second distance from centre tile speed-up method. Will have the next part of this up in a couple of days, probably Monday.

As always the full source code so far can be seen here:

http://glacialflame.com/tutorials/tiles/07/

Let me know if you run into any issues!

Posted in Uncategorized | 26 Comments

Delay for another week

Just a wee update on things. Once again just as momentum was building university/work steps in and says no not today mates. Ed has his final honours exams for his electronics and electrical engineering degree this week and I’m staring at iOS stuff for a good while. We do have a list of tutorials we are going to fire out though as soon as next week ends.

Diamond based isometric map scrolling,

Diamond based isometric path finding

Some more random stuff for diamond based isometric maps like player projectiles and collisions as well as a simple method to speed up your game.

Then.

We will cover rectangular based isometric maps (which we use) and everything that we covered previously but to work with this different and more optimized layout method.

Also… Should have some updates on Rabbit Zombies in the next couple of weeks.

Catch you all in a week!

Posted in Uncategorized | 13 Comments

Rabbit Zombies

As we mentioned in a previous post, we are working on a game with the current engine state to highlight the capabilities of what we have created.
So I give you. Rabbit Zombies.

We aim to have the alpha testing up for this soon, be sure to stay tuned.

http://www.rabbitzombies.com/

Posted in Uncategorized | 6 Comments

Canvas Isometric Tutorial – Add a player and throw in some objects Pt2.

Walls and other solid objects

This will be pretty easy to do and apart from a few extra condition checks in your movement code everything else is really just a case of duplicating.

Obviously to begin with we are going to need a wall tile, for this tutorial I decided to go with the orange wall of blockade. Took a while to plan out and design before creating such a tile but here it is if you wish to use it, carefully.

The wall as usual is a .png. The .png canvas height is made to be 50 pixels, double the ground tile height. This means our object can be any height between 0 and 50 pixels and by halving the height attribute of the object we can always line it up with ground tile it is on top of.

For speed and ease I’ll be going back to the original source of tutorial 02 where the map is just directly in the array rather than loaded as XML from a database. Ralph, our playable character has also been added in. It shouldn’t be hard at all though to use a later code version as I said it really is just a case of repeating some steps.

Current source of all the isometric tutorials minus the loading/saving can be seen here:

http://glacialflame.com/tutorials/tiles/06/source.html

Step One – loading our isometric objects

Adding objects is simple. Duplicate the ground tile code and then draw it on top once our ground layer has been drawn. Using a second array for objects means for simplicity all we have to do is look up the array coordinates relating to the players desired position, if there is an entry then that coordinate is impassable.

So duplicate the map array and imagine for just now zero is passable and one is a wall.

var objectMap = Array([0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,1,1,0,0],[0,1,1,0,0,1],[1,0,1,1,0,1],[0,0,0,0,0,0],[1,0,1,0,1,0],[1,1,1,0,0,0]);

Also similar to when you added your playable character, duplicate the image arrays and update the loader. Around the same area as your tileDict and tileImg add:

var objectDict = Array("wall.png");
var objectImg = new Array();

In your loadImg() function add:

	for(var i=0;i<objectDict.length;i++){
		objectImg[i] = new Image();
		objectImg[i].src = objectDict[i];
		objectImg[i].onload = function(){
			loaded++;
		}
	}

in your loadAll() function update your loaded condition to check if all object images have been loaded like so:

if(loaded == tileDict.length + charDict.length + objectDict.length){

All done!

Step Two – Let the user personally reflect over our wall object

In order to draw the objects into our map go the function drawMap() and within the loops add the following, underneath var drawTile = ma… is just fine:

var drawObj = objectMap[i][j];

Now we want objects to be drawn on top of our ground so under our ctx.drawImage(tileImg[drawTile],xpos,ypos) and before our character drawing add the following:

if(drawObj){
ctx.drawImage(objectImg[drawObj-1],xpos,ypos-(objectImg[drawObj-1].height/2));
}

This should explain itself, if drawObj (which is equal to the current drawing coordinate in our array ) is anything above zero then… well… draw it. The reason for drawObj-1 is because our object images start at zero however in our object array we start at 1. Otherwise every 0 in our array would represent a wall.

You should now be able to run Ralph around the map behind and in front of walls.

Step Three – HALT! You can’t walk there Ralph

Finally we update our movement code to check if there is an object or not.

Within our checkKeycode(event) function we can throw in the following around our current movement code:

if(!objectMap[playerX-1][playerY]){
playerX--;
}

The if check makes sure that the desired players coordinates within the objectMap array is false allowing the player to move that direction. This is done for each direction like so:

case 38:
if(!objectMap[playerX-1][playerY]){
playerX--;
}
break;
case 40:
if(!objectMap[playerX+1][playerY]){
playerX++;
}
break;
case 39:
if(!objectMap[playerX][playerY-1]){
playerY--;
}
break;
case 37:
if(!objectMap[playerX][playerY+1]){
playerY++;
}
break;

And that’s it. Ralph can now run about our fields with only the orange walls of blockade preventing his fun.

Full source can be found here:

http://glacialflame.com/tutorials/tiles/06/

As always let me know how you get on!

All the best.

Posted in Canvas, Javascript, Tile World, Tutorial | 11 Comments

Canvas Isometric Tutorial – Add a player and throw in some objects Pt1

With Ed finishing up his honours at uni and myself being chained to work over the last month things have slowed down again. However with all the great feedback and emails we have been getting it’s about time this was pushed on!

Currently all we have covered is creating a map. Not any old map though, a map which is generated from an XML feed, a map which brings graphical jealousy to those with even the upper most advanced Photoshop skills. For this is an isometric map. An isometric map we will now add a magnificent controllable cuboid square pyramid. A square pyramid like Ralph.

As we will be moving Ralph over our fields he will need to be like everything else a .png for the transparency, plus it is his preferred file type, bless him. You can download Ralph from this and bump him into your image folder:

Step One – removing the map editor save code (only if using Pt2 code of the saving tutorial)

The following tutorial stages are fine and ready to go with:

Mouse Control on Isometric Canvas tiles

http://glacialflame.com/tutorials/tiles/02/

Saving and loading from a database with PHP & XML in canvas Pt1

http://glacialflame.com/tutorials/tiles/03/

First thing we will do is remove any of the Save code you may have from the previous tutorial. As this is the actual game and not the editor none of it is required. (You will only have this code if you are editing the version created from the saving map tutorial.)

If you have the following remove:


<script src="DBSave.js" type="text/javascript"></script>
------
case 83:
          var db = new DBSave();
          db.saveMap(3,map);
break;
------

<select id="tile">
         <option value="0">Water</option>
         <option value="1">Grass</option>
         <option value="2">Swamp</option>
</select>

- Hit <strong>s</strong> to save.
------

if(map[xmouse][ymouse]){
         map[xmouse][ymouse] = document.getElementById('tile').value;
}
------

Step Two – loading up your character object

We will duplicate our tile images script for the most part so that we can load up Ralph in preparation for his interactivity.

We will add our character image holder at the top around the same area you have your tile dictionary and image holder array.


var charDict = Array("ralph.png"); // -- rename ralph.png to mimic your player image if Ralph wasn't good enough

var charImg = new Array();

We will use an array for the character images for multiple future reasons. You may want to keep non playable characters in this or multiple versions of your playable character relating to movement directions and so on.

Next up we need to edit our loadImg() function to include our character dictionary. Add in the additional loop:

	for(var i=0;i<charDict.length;i++){
		charImg[i] = new Image();
		charImg[i].src = charDict[i];
		charImg[i].onload = function(){
			loaded++;
		}
	}

Similar to the tile loop this just runs through all our images in the character array, loads them and increments the loaded variable.

In our loadAll() function edit the if statement so that it reflects the following:


if(loaded == tileDict.length + charDict.length){

Pretty obvious this will now make sure the loaded variable is equal to that of the arrays holding our images meaning every image is loaded and ready.

Step Three – get in there Ralph

We can throw Ralph into the map pretty simply really. Add the following global variables:


var playerX = 4;
var playerY = 4;

These will be the X and Y coordinates of Ralph and shall be updated whenever a player uses the arrows keys.

Finally add the following to the drawMap() function after the drawing of the tile:


if(i == playerX &amp;&amp; j == playerY){
          ctx.drawImage(charImg[0],xpos,ypos-(charImg[0].height/2));
}

One thing to note here is we make use of the image height attribute to make sure the bottom of Ralph matches up with the bottom of the tile. Also for just now we will just use charImg[0] as Ralph is the 1st array entry.

Testing your script now you should see your player standing somewhere on your map. Obviously Ralph can move so last up to our simple player addition is to add key movement.

Step Four – I give you legs Ralph

For this I’ll be using the arrow keys however WASD as an alternative can be easily used etc.

Should you want to use different keys the easiest way to get the code is to add

document.title = keyCode;

after the initial conditional if check in the checkKeycode(event) function.

We can then add to the case statement to reflect our key movements like the following:


case 38:

        playerX--;

break;

38 is the key code for up, we decrease playerX by 1 when pressed, which will update the players position on screen as our graphics update loop is ran through. So our final checkKeycode function reflects the following:


function checkKeycode(event) {
var keycode;
  if(event == null)
  {
    keyCode = window.event.keyCode;
  }
  else
  {
    keyCode = event.keyCode;
  }
  document.title = keyCode;
  switch(keyCode)
  {
	   case 38:
			playerX--;
	   break;
	   case 40:
			playerX++;
	   break;
	   case 39:
			playerY--;
	   break;
	   case 37:
			playerY++;
	   break;
	   default:
	   break;
		}
}

And that should be everything you need to add a moveable player.

As always the final code can be seen here:

http://glacialflame.com/tutorials/tiles/05/

Will write up the objects tutorial tomorrow which will include a quick simple passable and non passable condition check allowing for trees/grey walls etc.

After that I think I will cover changing some of this stuff to objects to allow for individual tile properties and so on. But might need to wait a week or so for that part… work :( .

Let me know how you get on with this!

All the best.

Posted in Canvas, Javascript, Tile World, Tutorial | 3 Comments

Glacial Flame Video

And here it is. The first video of our canvas project so far… No sound or anything, it speaks for itself. :)

Posted in About Glacial Flame, Canvas, Javascript, Particle System, Technology, Tile World | 5 Comments

Video right around the corner.

While on holiday from university/work Edward and I have really pushed ourselves on getting the game video ready (as well as the starting stages of being ready for our side game which will showcase everything so far). Expect frequent guides, screenshots, game information, videos and eventually our side game in the upcoming weeks. Be sure to check out our screenshot gallery for the latest captures and as always feel free to leave a comment or mail us directly :) .

Posted in About Glacial Flame, Canvas, Javascript | Leave a comment