grid game unit movement javaScript example
So this week I started working on a new canvas example prototype, and the very first minor release of the prototype thus far strikes me as something good to write about as a simple stand alone javaScript example post. Thus far it is just a simple example of having a grid, and having a player unit move around in the grid when a player clicks on a given cell location. The basic idea that I have together thus far with it could be taken in a whole range of different directions when it comes to making it into something that is more of a game beyond that of what I have in mind for the canvas example prototype. So I thought I would copy and past the source code over to another location and maintain it as just a simple starting point for a grid type game that involves moving a unit around a simple grid.
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.
However in this one I have an idea that I have not done yet with grids, and would like to move forward with it. Also in this post I am touching base on a lot of other topics when it comes to starting a foundation to which I will build on top of when it comes to making a real project rather than just yet another simple javaScript code example. This is a cycle that I would very much like to break at some point in my life.
It may seem as a very simple, trivial example, and for a veteran javaScript developer I suppose it is. However there are still many topics that are covered when it comes to just getting to this simple starting point, and also even when it comes to being an experienced javaScript developer there is the topic of how to go about structuring a complex projects that might at one point in the future consist of thousands of lines of code. This is a topic that I still strugle with even though I have many years of experience thus far. So then this should prove to be a nice little starting point for a simple game that involves a player controlled unit, so lets take a look at the source code.
1 - Getting started and the utility module of this grid unti movement javaScript example
This is a post on a simple client side javaScript example, so then it should go without saying that this is not a getting started with javaScript type post. I assume that you have at least some background with the basics of javaScript as well as other client side web development languages which include HTML and CSS. With that out of the way in this section I will be going over just the utilities module of the example leaving the other various files for later sections of this post.
Full source code is also on Github
If you are on Github and wondering if there is a location on Github where I am parking the source code that I am write about in this post there such a place will be found here in my test vjs repository. This is also where I pack the source code examples for my many other posts on native javaScript features and examples.
1.1 - The utility module
So first off here is a utility module that has some stand alone static methods that I am going to be using in one or more additional modules moving forward with the rest of the code. This is just a standard practice of sorts when it comes to making any kind of canvas example, or complex javaScript project. A popular javaScript library that can be described as a general unity library would of course be lodash, however with these javaScript example posts I like to do everything from the ground up, making my own custom cut libraries. I have another utilities library javaScript example post in which it get into detail about making this kind of module that is packed with all kinds of usual suspect type methods that I will often park in a file such as this. However I often do make custom versions of this kind of library on a project by project, and example by example type basis.
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.
In this javaScript example I have a simple gird where when a cell location is clicked a player object will move in the direction of that location by one cell at a time. So I have a angle to point method that can be used to get a direction from one position to another that will be used in my main game module. This method makes use of the Math.atan2 method which is useful for these kinds of situations that have to do with angles. I have also made yet another javaScript example where I am making an angles module that is based of a library on angles that I like called just simply angles.js.
Another method that I have here is useful for getting a canvas relative rather than window relative location when it comes to pointer events. I will not be getting into this subject in detail as I have wrote a post on this topic before hand, so if you want to learn more about this you can check that out if interested. In this javaScript example I will be using this method when it comes to my crude yet functional state machine in my main.js file that ties everything together. I will be getting into that module more so later in this post when it comes to the section on the main javaScript file of the example where I am using the method when working with event handlers.
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
In this javaScript example the main module will be the state machine object that I will be getting to later in this post. However the game module is still a major component that will contain everything that has to do with the state of the game, rather than the application as a whole. This means the state of the map as well as the units that will be located in the map as well.
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
So now it is time to get to my main.js file for this javaScript example where I will make use of all the modules that I have put together for this example. Here I create the canvas element that I will be using, and set up a simple state machine object that for the same of this example is not really much of a state machine but just a place holder for such a thing. Also here in the main.js file I have my main application loop that is typically for any of my canvas examples.
|
|
6 - Conclusion
So for now I have a decent starting point for a game, but there are all ready thins that I might choose to do differently when it comes to this basic starting point. Like many javaScript projects that make use of canvas I have a main update loop that is calling requestAnimationFrame over and over again. I decided to keep that, but the thought did occur that I might want to make this project completely event driven rather than having an update loop fire all the time. Also when it comes to keeping it there are many little subtle improvements that are needed that I have not got to yet, but have done in other projects.
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.