/drtiled

Tiled map loader for DragonRuby Game Toolkit

Primary LanguageRubyMIT LicenseMIT

DRTiled

GitHub release (latest by date)

This is a library for loading Tiled map files in DragonRuby Game Toolkit.

It supports TMX format directly allowing skip exporting to json or csv files step.

Check out tiledriver for a lightweight lib with a camera and rendering functions.

Demo

Map updating with DRTiled lib

Content

Installation

  1. Create a lib directory inside the base directory of your DR game.
  2. Copy lib/tiled directory to created lib.
  3. Add require 'lib/tiled/tiled.rb' to the top of your app/main.rb file.

Usage

This is the simplest way to use library:

require 'lib/tiled/tiled.rb'

def tick(args)
  if args.state.tick_count.zero?
    map = Tiled::Map.new("maps/map.tmx")
    map.load
    args.state.map = map
    args.outputs.static_sprites << map.layers.first.sprites
  end
end

The tilesets and spritesheets used in map should be placed inside your game dir, for example you should save map files inside map dir and spritesheets inside sprites dir.

Accessing layers

ground_layer = map.layers['ground'] # Get layer by name
collisions_layer = map.layers['collisions']
layer_5 = map.layers.at(5) # Get layer by index

map.layers.select(&:visible?) # Get visible layers

Working with tiles

You can access individual tiles using #tile_at(x, y) method.

collisions_layer = map.layers['collisions']
if collisions_layer.tile_at(new_x, new_y).properties.passable?
  player.move(new_x, new_y)
end

Loading tilesets from files

Tilesets that referenced in map file are automatically loaded. But if you need to load separate tileset file to use it outside of a map, you can do it using Tiled::Tileset.load method. For example:

require 'lib/tiled/tiled.rb'

def tick(args)
  if args.state.tick_count.zero?
    tileset = Tiled::Tileset.load('sprites/player.tsx')
    args.state.tileset = tileset

    player_icon_id = 0
    args.outputs.static_sprites << tileset.sprite_at(10, 10, player_icon_id)
    args.state.player = [100, 100]
  else
    args.outputs.sprites << tileset.sprite_at(args.state.player.x, args.state.player.y, 2)
  end
end

Rendering sprite from tileset

No matter how tileset was loaded, you can use sprite_at method to render tile in desirable location by tile id:

args.outputs.sprites << tileset.sprite_at(100, 200, 42)
args.outputs.sprites << map.tilesets.first.sprite_at(200, 300, 42)

Using objects

Object layers can be found using Map#layers as well.

object_layer = map.layers['object'] # Get it the same as any other layer

collision_layer = map.layers['collision']
collision_layer.objects.each do |hitbox|
  if player_primitive.intersect_rect?([hitbox.x, hitbox.y, hitbox.width, hitbox.height])
    # handle collision...
  end
end

The following is for development purposes and will eventually be removed; see below for a dedicated rendering library.

object_layer.render(args) # Renders to args.outputs.primitives
collision_layer.render(args, :debug) # Renders to args.outputs.debug
object_layer.render(args, args.render_target(:foo).primitives) # You may also pass in a GTK::OutputsArray

#object_type will give you one of the following:

  • :rectangle: The object has x, y, width, and height attributes
  • :ellipse: Same attributes as rectangle
  • :polygon: Has x, y, and a points attribute containing an array of points relative to the [x, y] point
  • :polyline: Has x, y, and a points attribute containing an array of points relative to the [x, y] point
  • :point: Has x and y attributes
  • :text: Same attributes as rectangle and text, fontfamily, pixelsize, bold, italic, underline, strikeout, kerning, wrap, color, halign, valign attributes. to_h method will return label primitive that can be used to output labels in args.output.*.
  • :tile: Has gid, x, y, width, and height attributes, tile method will return Tiled::Tile that this object references by gid

Using tile collision

You can access collisions for whole map or for one layer:

# For the map:
player_collided = map.collision_objects.any? do |object|
  object.intersect_rect?([player.x + offset_x, player.y + offset_y, player.w, player.h])
end

# For a layer
player_collided = map.layers['walls'].collision_objects.any? do |object|
  object.intersect_rect?([player.x + offset_x, player.y + offset_y, player.w, player.h])
end

Or access individual tile related objects:

layer.tile_at(new_x, new_y).object_layer.objects

In this case all coordinates of object will be relative to tile.

Using properties

Next properties types supported:

  1. int, float, bool - converts to Integer, Float, true/false respectively.
  2. string - supports multiline string.
  3. color - will converts to Tiled::Color supports #AARRGGBB and #RRGGBB Tiled formats.
  4. file - relative file path will be converted to absolute path relative to game dir.
  5. object - will return Tiled::ObjectRef, which has object attribute that will be resolved to referenced object when called.

Running samples

# clone drtiled somewhere
./dragonruby /path/to/drtiled

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Credits

License

MIT