I have made many projects in the past that involve the use of a grid in one form or another such as my grid defense canvas example, I also have another canvas example when it comes to creating and drawing grids in general with canvas. Shortly after I wrote this post for the first time I made another example where the aim is to make a grid module that can be used over and over again from one project to another rather than making a custom solution for a single project or examples such as the case with this example that I am writing about here. The problem with that as I see it s far is that making a grid module is something that I never seem to get just right, so I need to keep making new ones. So maybe some times it is a good idea to just create a custom grid module on a project by project basis rather than trying to make some kind of magic grid module that will work well in every possible project.
Full source code is also on Github
1.1 - The utility module
One method that I have at the ready is a typical distance formula function. Thus far I am using this function in my map module now when it comes to figuring what the weight should be when preforming path detection. Moe on that later on in the post when it comes to the section on the map module.
I then also have a crude yet effecting deep clone method that makes use of JSON to quickly deep clone objects. Thus far I am just using this in my map module as a way to quickly create a copy of a grid, and then use this copy of a grid to preform path detection. I can not recommend that this is a good solution for all situations in which one will need to deep clone objects though. For more on this topic you might want to check out my post on the lodash clone deep method.
2 - The map module that will be used to create the grid.
In order to get this example working I will need a grid in which to place the player object that will move on each grid location click. I could just have everything together in one module when it comes to a game project like this, but I am thinking ahead with this one and have decided to pull this part of the example into its own map module. For now I am going to be trying my best to keep this map module as simple as I can, however I am still going to want to add things like path detection so it is not going to be all that simple. With that said it has a few public methods that I may or may not expand on event more is I keep working on this project, but I am not sure there is much more I would want to add with this module at least.
There is of course a create method that I will be calling in my game module that I will be getting to in a later section in this post. When it comes to creating even a simple grid module there are all kinds of formats for the grid object that come to mind. Some developers might prefer some kind of format that involves an array of arrays, but as of late I prefer a solution that involves a single array and then using a formula to get or set the proper cell location.
After the create public method I have two methods that can be used to get a cell location in the map. One is just the basic get method that can get a cell by an index value, or an x and y cell location. The other method is what I will be using to get a cell location by way of a canvas relative pixel location.
In addition with a basic core set of methods to create and work with a map object, I have also added a number of methods that have to do with match detection. This code that I have for this is based off of what it is that I have worked out for my post on path detection. So now not only can I create a map, and get references to cells by a index or pixel location, but I can also get paths from one cell position to another. With that said by default all cells have a walkable property that by default is set to true. When it comes to my game module that will make use of this map module that is where I will want to set the walkable value of cells true and false as needed.
3 - The game module
Here in the game module I have a create method that will be used to create a new game state that will contain at least one instance of a map object for starters, and helper methods that can be used to create the player object. So the game module is the main state object for the state of the actual game in terms of the state of the map, and any display objects that might be in the map, or out of it actually. For now it is just the player object, as well as just simple wall units that I am concern with, and in time as I develop this project much of the code here will be pulled into another module that has to do with object pools, and units in general when and if I get to it.
So for now I have all of my unit methods and various related helper functions at the top of this game module helper. I then have a create base unit helper that is used to create a unit object with all properties that the unit of any kind should have. As of revision 3 the only real properties of interest with a unit would be the sheetIndex, and currentCellIndex properties.
With path detection now added to the map module as revision 3 of the example the place unit method will not set the walkable property of a cell to true when a unit is located in the cell, as well as set the value back to false when moving the unit to a new cell location. Because of this and any additional factors of concern moving forward the place unit method should always be used when moving any unit from one location to another or placing a new unit into a map.
4 - The draw module
So now that I have all the modules that can be used to create a main game object state, I am going to want to have a way to create a view for this state object. So I will then need module that can be used to draw to a canvas element which will be this draw.js file. With this example this far I just have a few draw methods one of which is to just draw a simple static background, another is to draw the state of the map as a whole, and I have another that just draws some basic state info.
5 - The main.js file and the start of a State machine
6 - Conclusion
Still for now I just wanted to get this the point where I am just moving a player object around in a grid, and that is it. I had it set in my mind as to what the first step is, and I completed that. There are going to be additional steps that involve making various invisible improvements that do not really change the behavior, or looks an feel of the project but that was not what I wanted to get done for the moment.