FlixelCommunity / flixel

Community fork of Adam “Atomic” Saltsman's popular game engine Flixel. Distilled from a variety of Flash games he worked on over the last couple years, including Gravity Hook, Fathom and Canabalt, its primary function is to provide some useful base classes that you can extend to make your own game objects.
http://flixelcommunity.org/
Other
84 stars 17 forks source link

Animated Tilemap - FlxAnimatedTilemap.as #145

Open FlixelCommunityBot opened 11 years ago

FlixelCommunityBot commented 11 years ago

Issue by msilver101 from 2012-10-27T22:53:39Z Originally opened as https://github.com/AdamAtomic/flixel/issues/233


I've written a class that extends FlxTilemap. Its really useful if you have an animated tileset that you want to use for say a top down strategy game. Feel free to use it and change the opening comment to be licensed however you want.

I've called it 'FlxAnimatedTilemap.as' in my branch.

package org.flixel
{
    import org.flixel.FlxTilemap;
    /**
     * Extention of FlxTileMap that allows for loading in several images and swaping them to animate.
     * 
     * @author  Michael Silverman
     */
    public class FlxAnimatedTilemap extends FlxTilemap
    {
        /**
         * Internal list of the frames in the tilemap animation.
         */
        protected var _tileArray:Array;
        /**
         * Internal current index in the animation array.
         */
        protected var _curFrame:uint;
        /**
         * Internal, used to time each frame of animation.
         */
        protected var _frameTimer:Number;

        /**
         * Internal, length of each frame
         */
        protected var _frameTime:Number;

        /**
         * The tilemap constructor just initializes some basic variables.
         */
        public function FlxAnimatedTilemap()
        {
            super();
            _tileArray = new Array();
            _curFrame = 0;
            _frameTimer = 0;
            _frameTime = 0.125;
        }

        /**
         * Clean up memory.
         */
        override public function destroy():void
        {
            for (var i:uint = 0;  i < _tileArray.length; i++ )
            {
                _tileArray[i] = null;
            }
            _tileArray = null;

            super.destroy();
        }

        public function loadAnimatedMap(MapData:String, TileArray:Array, TileWidth:uint=0, TileHeight:uint=0, AutoTile:uint=OFF, StartingIndex:uint=0, DrawIndex:uint=1, CollideIndex:uint=1, FrameTime:Number = 0.125):FlxAnimatedTilemap
        {
            super.loadMap(MapData, TileArray[0], TileWidth, TileHeight, AutoTile, StartingIndex, DrawIndex, CollideIndex);

            _tileArray = new Array();
            for (var i:uint = 0; i < TileArray.length; i++)
            {
                _tileArray.push(FlxG.addBitmap(TileArray[i]));
            }
            _frameTime = FrameTime;

            return this;
        }

        /**
         * Automatically called after update() by the game loop,
         * this function swaps the tile image if needed.
         */
        override public function postUpdate():void
        {
            super.postUpdate();

            var dirty:Boolean;

            if (_tileArray.length > 0)
            {
                _frameTimer += FlxG.elapsed;
                while(_frameTimer > _frameTime)
                {
                    _frameTimer = _frameTimer - _frameTime;
                    if(_curFrame == _tileArray.length-1)
                    {
                        _curFrame = 0;
                    }
                    else
                        _curFrame++;
                    _tiles = _tileArray[_curFrame];
                    dirty = true;
                }
            }

            if (dirty)
            {
                setDirty(true);
            }
        }
    }
}
Gama11 commented 11 years ago

Animated tilemaps are something that should totally be a part of flixel. It's probably a majority of tilemap-based games that needs them at some point, and having to use sprites just for a few animations is a bit annyoing.

However, this class doesn't seem compatible with the current version of flixel - the second paramter of loadMap is not TileArray (whatever that was needed for) anymore, but TileGraphic.

Dovyski commented 11 years ago

I like that too, but I don't think changing the whole tile map every frame is the best approach. Maybe something simpler like adding a new parameter to setTileProperties() to indicate the animation or a new method: setTileAnimation().

michaelplzno commented 11 years ago

@Dovyski The code only changes the image one time when the time between each frame is passed. This is why the setDirty(true) code only happens if (dirty) For example, if the map is set to animate every 1 second it will do almost nothing other than count down a timer till the 1 second passes. Then for one frame change the image to the new tileset. I can't come up with a quicker way to so this, though I'm curious if someone can. In practice it works quite nicely.

@Gama11 Not sure about compatibility with this version, it worked fine for the version I wrote it for, if you want I can try to link it against a different version, I'm sure the changes needed would be tiny.

Dovyski commented 11 years ago

Oh, I see now @msilver101 . Thanks for clarifying that!