Search code examples
haxetiledtmxhaxeflixelhaxelib

Haxe - Why can I not access a child's attribute without getting an error that the parent does not have the given attribute?


I've recently been getting into Haxe and just started to use HaxeFlixel to load a Tiled .TMX file.

I am creating a TiledMap object and passing it the TMX file path, then I want to iterate over the layers in that object to add them to the game scene. However when I try to access .tileArray (which is a property of TiledTileLayer) I get the following error :-

flixel.addons.editors.tiled.TiledLayer has no field tileArray

Here is the code:

package;

import flixel.FlxState;
import flixel.tile.FlxTilemap;
import flixel.addons.editors.tiled.TiledMap;
import openfl.Assets;


class PlayState extends FlxState
{
    private var _tiled_map:TiledMap;

    override public function create():Void
    {
        _tiled_map = new TiledMap("assets/data/Map1.tmx");

        for(layer in _tiled_map.layers){
            var layerData:Array<Int> = layer.tileArray;
        }

        super.create();
    }

    override public function update(elapsed:Float):Void
    {
        super.update(elapsed);
    }
}

I've found the following example - http://coinflipstudios.com/devblog/?p=182 which seems to work fine for people.

So I wanted to check whether the layer object was a TiledTileLayer as it should be, or TiledLayer, with the following:

trace(Type.typeof(layer));

Which sure enough yields:

PlayState.hx:24: TClass([class TiledTileLayer])

So if it is a TiledTileLayer which has the field tileArray why is it moaning?

I had a look at the source code (https://github.com/HaxeFlixel/flixel-addons/blob/dev/flixel/addons/editors/tiled/TiledMap.hx#L135) and TiledTileLayer inherits from TiledLayer. Layers is an array of type TiledLayer, so I think this is why it is moaning. I can clearly see that the array is storing child objects of TiledLayer, but as soon as I access any props/methods of those children, it complains that the parent does not have that field? Very confusing!

To run I'm using this command: C:\HaxeToolkit\haxe\haxelib.exe run lime test flash -debug -Dfdb

Thank you!


Solution

  • So if it is a TiledTileLayer which has the field tileArray why is it moaning?

    It may be a TiledTileLayer in this case, but that may not always be the case. layers is an Array<TileLayer> after all, so it could be a TiledObjectLayer or a TiledImageLayer as well (which don't have a tileArray field). This can nicely be seen in the code you linked. The concrete type can only be known at runtime, but the error you get happens at compile-time.

    If you know for sure there won't be any object or image layers, you can just cast it to a TiledTileLayer. However, just to be safe, it's good practice to check the type beforehand anyway:

    for (layer in _tiled_map.layers) {
        if (Std.is(layer, TiledTileLayer)) {
            var tileLayer:TiledTileLayer = cast layer;
            var layerData:Array<Int> = tileLayer.tileArray;
        }
    }
    

    It works without this for the tutorial you linked because it was made for an older version of flixel-addons.