Roguelike 2 - Using HTML for graphics
This is the second of several posts I’m writing to catalogue the development of my game. This article focusses on how to use HTML as graphics.
Continuing from Part 1, where I scaffolded a game loop and a state stack, now on to the more interesting bit: handling HTML elements in a game.
Everything you see on screen is an HTML element. There are two main ‘categories’ of elements. The first is the structure that holds everything in place. The second are the elements that make up the tiles of the game. The first one is straight forward, just a bunch of static divs, so I’ll just focus on the second category.
The decorator pattern
I chose not to extend the prototype of native class
HTMLElement for this because not all methods added this way are applicable to all elements. This methods just expands the capabilities of a single object of type
HTMLElement. More specifically,
move will move the object
n amount of pixels to the left or right by setting the specific
dataset attributes, and then parsing those as style in the
draw function. This allows me to do all sorts of checks and balances before manipulating the actual position of the element on the screen.
I’m using this pattern for almost everything that has a shared componenent, that in other languages might have been an inherited class or interface.
Tiles and assets
Two concepts. a Tile is a square of a particular size representing a specific chunk of the game world. This drives game mechanics and visuals, so Tiles are more functional in nature and can be seen as the definition of said chunk of game. There are tiles for rock, water and trees, but also for players, monsters and items.
The second concept is assets, which govern the technical nature of a chunk in the game world. An asset has actions like the ability to position itself on the screen and can keep track of all attributes like current position, wether it’s visible to the player or invisible etc. Part of an asset in this scenario is a Tile type, but all actions and attributes are more or less independent of that. An asset is like the implementation of a game chunk.
To streamline the process of defining Tiles and creating Assets, the game has the following:
- a tile bank, holding information about every type of tile out there. I want a central repository which will just simply give me a tree, without me specifying every time there needs to be a
*character in it, or that you can’t walk through a tree.
- an asset generator, which implements a tile using the decorator pattern explained above.
TileBank creates new
Tile objects is that every tile you’re getting out should be unique. If I simply return the object literal, I can never tweak that particular tile without changing all tiles of that type - the object literal would be referenced everywhere.
The Asset function uses the decorator described above. What you see below is not the full code, it’s meant to show you how I’ve approached creating assets and should be used as an example.
To get a tree in grid position [5,10] and put it in the browser all that’s left to do is:
In reality this should be fleshed out. My roguelike implements not only static objects like trees and grass, but also moving elements like the player object. They have the
draw functions, but were run through an additional decorator to add functions for movement, for instance collision detection.
With some CSS styling to add colours, the result looks like this:
In part three, I will explain how I generated that island above.
Jorg is a SAP and UI5 developer.