
Latest posts by Nenad (see all)
- Traquer – Testing made easy - October 25, 2016
- ExtJS tag cloud - June 28, 2016
- Interactive Twitter stream visualization now online! - June 16, 2016
Last two weeks I was so bored with routine coding and routine life stuff, that I’ve searched for any distraction that could come to my mind. First, I tried to read some book, but that ended up before it started. Then, trying to be practical, I’ve set few permissions to the question ‘what should I do to entertain myself while not wasting time looking for it’. This was the list:
- It has to be coding,
- It has to be something I’m coding pretty rarely,
- It has to take two, max three days to complete (otherwise it can metastasize into a really destructive passion that can hold me back for months, been there),
- Search must not take more than few hours, otherwise I give up and default to default
So, after I’ve spent few hours browsing various blogs, articles, and GitHub projects, I’ve ended up with Isomer. Great little library for creating isometric stuff, and being a Flash developer that created some isometric games back in the days, I wanted to create something worth writing about. Nothing special, just for sport. My entertainment for few days was sublimed in this articles title – Let’s create a (isometric) game.
Imagination
Creating games is subjected more to imagination of the creator than to technical considerations and eventual limits. And I hope I’ll elaborate this stance in this article.
First and foremost I’m not game developer. I created few flash games during 2000ths, and few canvas based games later, of course just for sport. I’m not pro at the subject, and after all I’m not a gamer. Last game I’ve played with passion was Portal 2 – 4 years ago. Knowing this, you can judge me for the above-mentioned, I don’t really care. Also, for the topic’s sake – my imagination on the subject is very naive and limited.
The top game I could possibly create would be a variant of the game presented in this topic – Maze with coins, crystals and (if I could have some more time for path-finding algorithms) some stupid enemies.
That would conclude imagination part.
Idea
Whole idea about this game, which took me whole 2 minutes to come around is – Let’s make a maze and coins (crystals which I took from here). Player goes through maze collects crystals, and when all are collected advance to next level.
Pretty plain.
Problems
First version had one hard-coded level written as two-dimensional JavaScript array, that’s transpiled to isometric canvas, or matrix of size nxn where zeroes represent impassable areas, and ones represent our merry maze. It looked little something like this:
1 2 3 4 5 6 7 8 |
var maze= [[0,1,0,0,1,1,1,1], [0,1,0,0,1,0,0,1], [0,1,0,0,1,1,0,1], [0,1,1,0,0,1,0,1], [0,0,1,1,1,1,0,1], [0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,1], [0,0,0,0,1,1,1,1]] |
Crystals would have been randomly positioned along the path. One should move with arrows on their keyboard (not thinking about wasd or mobile variant right now).
That all worked great until I collected all crystals and ended up on same level, with new set of randomly positioned crystals. That sucked big time.
I didn’t want to write 200 matrices of random size, so I had to figure out how to generate those. For serious game devs this is a naive problem that has been solved so many times that they would probably laugh reading this, but what should I do :).
After I tried to implement some of these, unsuccessfully rewriting them in JavaScipt I’ve decided to think about the problem for myself and created a simple algorithm for creating a mazes of nxn size. It lacks some basics, but essentially works just fine.
Basically it’s recursive backtracking procedure that checks rounding (neighboring) points whether they have single passable point. If so, mark it as 1.
Remarks:
(Later, I gave up marking them 0/1, but rather 0/n where n would be a number of times algorithm had recursed. That number is later used to add up to block color so I could see how algorithm proceeded through maze).
(As a matter of credit, I came up to algorithm idea following this stack overflow article, it’s somewhat same as describe there).
It looks like this (more or less):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
function genmaze(pos){ var adjacent = [ [pos[0]-1, pos[1]], [pos[0]+1, pos[1]], [pos[0], pos[1]+1], [pos[0], pos[1]-1] ]; var neighbors = []; for (var l = 0; l < 4; l++) { if (adjacent[l][0] > -1 && adjacent[l][0] < width && adjacent[l][1] > -1 && adjacent[l][1] < height) { neighbors.push(adjacent[l]); } } // Choose one of the neighbors at random var rndn = Math.floor(Math.random()*neighbors.length); var next = neighbors[rndn]; field[pos[0]][pos[1]] = v; if(field[next[0]-1] && field[next[0]+1]){ // non-diagonal neighboring positions should not form a square var isSquare = ((field[next[0]-1][next[1]]) > 1) + (field[next[0]+1][next[1]] > 1) + (field[next[0]][next[1]+1] > 1) + (field[next[0]][next[1]-1] > 1); if (isSquare === 1){ start = next; genmaze(start); } current++; v++; } else { current--; } }; |
The Game
With maze generation done, we can now play this game forever with little possibility of repeating levels. Since the logic has been set, our little game is done, and it can be played here – http://statick.org/iso/ and code is available here.
Please, feel free to change it, or do whatever you want with it.
Thanks for reading.