2013-10-18

Loading a simple map

Alright, enough with the raindrops. Now that the tutorial is more or less successfully done, it's time to concentrate on something else. In this post I will explain how to create a simple tile-based map with Tiled map editor (http://www.mapeditor.org/) and how to load and render it with Clojure and libgdx.

Note: I've created a github project for my experiments, so the source code and used pictures are available at https://github.com/jvnn/space-ventures.

I won't concentrate here on how to use Tiled because it's easy enough and there's tons of material out there to learn from (such as http://gamedev.tutsplus.com/tutorials/level-design/introduction-to-tiled-map-editor/). What wasn't clear to me right away (because I didn't bother reading through the tutorial) was how to give the editor something to work with. Tiled is a tile-based editor (as the name somewhat suggests) and thus it needs to have a tile set. The tiles are then used to draw the map. I ended up creating a very simple set of walls and corner tiles with Inkscape:


The picture above has the size of 512x32 pixels and is divided into 32x32-pixel tiles by Tiled. One might wonder why I have so many equally gray tiles included. Well, libgdx only accepts textures whose dimensions are a multiple of two. So creating just nine tiles (which would otherwise be enough for four corners, four walls and a floor tile) isn't going to cut it.

Once we have the tile set imported, we can draw a simple map with darker walls and a light gray floor. I didn't put much effort into making it fancy, this will do for now... The map can then be saved as a .tmx file that will be parsed by libgdx. 


So now we have a map. Then we need to dive into the awfully complex code that handles parsing the map file:

(ns com.space-ventures.map
  (:import [com.badlogic.gdx.maps.tiled TiledMap TmxMapLoader]
           [com.badlogic.gdx.maps.tiled.renderers OrthogonalTiledMapRenderer]))

(defn load-map [map-name]
  (let [tilemap (.load (TmxMapLoader.) map-name)]
    (hash-map :tilemap tilemap
              :renderer (OrthogonalTiledMapRenderer. tilemap))))

(defn render-map [mapmap camera]
  (.setView (mapmap :renderer) camera)
  (.render (mapmap :renderer)))


(defn dispose [mapmap]
  (.dispose (mapmap :tilemap))

  (.dispose (mapmap :renderer)))


Yep, that's it. I created a new file called map.clj and defined two functions, one for loading the map in the beginning and another one that renders it. The map information is stored in a hash-map that is created in load-map and later passed to the renderer. I'm still trying to learn the ways of the force, i.e. functional programming, so I'm not sure if this is the right way to do things but at least no state information is stored in the module itself. Otherwise I don't know much more to say about the code, it's so very simple! Loading the map only requires the name of the .tmx file (map-name) and the resulting map is then fed into the constructor of the map renderer. In the rendering function, the renderer is told to use the view of the camera and then simply told to render the thing. (Oh, sorry for the variable name, I gave up trying to create a better name for a map (hash-map) that contains a map...)

I will show how these functions are called from within the main code in the next post where I describe how to add a simple character into the "game".

No comments:

Post a Comment