Creating a Sokoban Clone
Yesterday, I attempted to write a fast little clone of Sokoban to apply and understand the benefits of a Command Pattern. Unfortunately, I got bogged down by the details of the game implementation before I ever got a chance to play around with the pattern itself.
I wanted to use libgdx’s builtin TiledMap classes to facilitate having a fast representation of where what is and saw that it already implemented Tiles, Layers, Cells, and an overall Map. However, I do think if I am to use this feature of the library again, I will have to dedicate a whole prototype just to understanding its own inner workings. I almost did yesterday. What I wanted was as follows:
You have a player object, that can be moved with the keyboard via the direction keys. There are pushable objects on the map that need to be pushed onto goals and walls surround you. Everything only ever moves along the grid. Sounds incredibly simple, right? Well, I had an awful time finagling my way around the actual implementation with the help of TiledMapTiledLayers and StaticTiledMapTiledTiles and whatever else it threw at me. Of course, I am just kidding. Libgdx is an awesome library and me not understanding the ideas behind one of its implementations does not signal the library’s lack of usefulness - just my ineptitude.
The whole tilemap part of the library consists of many different moving parts that you have to fit together to make work. You begin by creating a Map object. Then you add layers to the object. The layers all have different sizes and can even contains tiles of different sizes (which seems very intriguing). Then you fill the the layer with individual cells, which are really just there to hold Tiles, which are the maps way of representing TextureRegions. So far, so good. I began hacking away. I did not realize a few key things however; Cells really only existed to contain textures (and whether they would have to flipped or not), not even their position was kept within. There was also no way to query the tilelayer for the positional information of individual cells. And cells, especially empty one would probably be re-used by the system to save on memory.
An incredible amount of overkill for my purposes, which I did not recognize until I was in way too deep. But, what is overkill for me is presumably very much appreciated for more complex efforts at creating something else - a platformer that is not constrained to the grid, tilemaps with animations, Different layers interacting with each other and so on.
What I ended up doing was coding almost an entire system for tilemaps working beside the original one. Don’t do that. I started copying position values from one to the other, I checked tilemaps for collision with my own system and made changes to the cells with the library. Really, I should have either committed to the library’s way of doing this wholly, or just implemented my very simple version of it from the get-go. Hopefully, I can salvage the working parts of it to finish up this weekend - because the idea of a simple Sokoban game actually sounds nice, and I got a working file importer and parser going, which would pull in levels from text files, or maybe even the internet. And maybe I can finally further my understanding of the Command Pattern, which was the purpose of this whole exercise in the first place.
In the meantime - if you decide to use libgdx tilemaps: Don’t be a fool like me and miss MapObjects. They’re important.