Author Topic: FlxTilemapSheet  (Read 3831 times)

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
FlxTilemapSheet
« on: Tue, Nov 10, 2009 »
Like the FlxSpriteSheet class, this allows you to have tilemaps made with sheets of tiles rather than strips of them. I made it because the absurdly long strip of tiles in Level Up was a pain to work with.

I did -try- to make it an extension of FlxTilemap, re-writing _rects in the constructor, but I had too many problems with tileWidth messing everything up, so I just wrote a derivative class instead.

Code: [Select]
package com.titch.FlxExtensions
{
import com.adamatomic.flixel.FlxCore;
import com.adamatomic.flixel.FlxTilemap;
import flash.geom.Rectangle;
import com.adamatomic.flixel.FlxG;
import com.adamatomic.flixel.FlxSprite;
import flash.display.BitmapData;
import com.adamatomic.flixel.FlxArray;
import com.adamatomic.flixel.FlxBlock;
import flash.geom.Point;
/**
* ...
* @author ...
*/
public class FlxTilemapSheet extends FlxCore
{


private var widthInTiles:uint;
private var heightInTiles:uint;
private var _pixels:BitmapData;
private var _data:FlxArray;
private var _rects:FlxArray;
private var _tileSize:uint;
private var _p:Point;
private var _block:FlxBlock;
private var _ci:uint;

private var _screenRows:uint;
private var _screenCols:uint;

//@desc Constructor
//@param MapData A string of comma and line-return delineated indices indicating what order the tiles should go in
//@param TileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData
//@param Size The size of the tile (square) in pixels.
//@param CollisionIndex The index of the first tile that should be treated as a hard surface
//@param DrawIndex The index of the first tile that should actually be drawn
public function GathTilemap(MapData:String, TileGraphic:Class,Size:int = 16, CollisionIndex:uint=1, DrawIndex:uint=1)
{
super();
_ci = CollisionIndex;
widthInTiles = 0;
heightInTiles = 0;
_data = new FlxArray();
var c:uint;
var cols:Array;
var s_rows:int;
var s_colunms:int;

var rows:Array = MapData.split("\n");
heightInTiles = rows.length;
for(var r:uint = 0; r < heightInTiles; r++)
{
cols = rows[r].split(",");
if(cols.length <= 1)
{
heightInTiles--;
continue;
}
if(widthInTiles == 0)
widthInTiles = cols.length;
for(c = 0; c < widthInTiles; c++)
_data.push(uint(cols[c]));
}

_pixels = FlxG.addBitmap(TileGraphic);
s_colunms = this._pixels.width / Size;
s_rows = this._pixels.height / Size;
_rects = new FlxArray();
_p = new Point();
_tileSize = Size;
width = widthInTiles*_tileSize;
height = heightInTiles*_tileSize;
var numTiles:uint = widthInTiles*heightInTiles;
for(var i:uint = 0; i < numTiles; i++)
{
if(_data[i] >= DrawIndex)
_rects.push(new Rectangle(_tileSize*((_data[i])%s_colunms),_tileSize*int((_data[i])/s_colunms),_tileSize,_tileSize));
else
_rects.push(null);
}

_block = new FlxBlock(0,0,_tileSize,_tileSize,null);

_screenRows = Math.ceil(FlxG.height/_tileSize)+1;
if(_screenRows > heightInTiles)
_screenRows = heightInTiles;
_screenCols = Math.ceil(FlxG.width/_tileSize)+1;
if(_screenCols > widthInTiles)
_screenCols = widthInTiles;
}

//@desc Draws the tilemap
override public function render():void
{
//NOTE: While this will only draw the tiles that are actually on screen, it will ALWAYS draw one screen's worth of tiles
super.render();
getScreenXY(_p);
var tx:int = Math.floor(-_p.x/_tileSize);
var ty:int = Math.floor(-_p.y/_tileSize);
if(tx < 0) tx = 0;
if(tx > widthInTiles-_screenCols) tx = widthInTiles-_screenCols;
if(ty < 0) ty = 0;
if(ty > heightInTiles-_screenRows) ty = heightInTiles-_screenRows;
var ri:int = ty*widthInTiles+tx;
_p.x += tx*_tileSize;
_p.y += ty*_tileSize;
var opx:int = _p.x;
var c:uint;
var cri:uint;
for(var r:uint = 0; r < _screenRows; r++)
{
cri = ri;
for(c = 0; c < _screenCols; c++)
{
if(_rects[cri] != null)
FlxG.buffer.copyPixels(_pixels,_rects[cri],_p,null,null,true);
cri++;
_p.x += _tileSize;
}
ri += widthInTiles;
_p.x = opx;
_p.y += _tileSize;
}
}

//@desc Collides a FlxSprite against the tilemap
//@param Spr The FlxSprite you want to collide
override public function collide(Spr:FlxSprite):void
{
var ix:uint = Math.floor((Spr.x - x)/_tileSize);
var iy:uint = Math.floor((Spr.y - y)/_tileSize);
var iw:uint = Math.ceil(Spr.width/_tileSize)+1;
var ih:uint = Math.ceil(Spr.height/_tileSize)+1;
var c:uint;
for(var r:uint = 0; r < ih; r++)
{
if((r < 0) || (r >= heightInTiles)) continue;
for(c = 0; c < iw; c++)
{
if((c < 0) || (c >= widthInTiles)) continue;
if(_data[(iy+r)*widthInTiles+ix+c] >= _ci)
{
_block.x = x+(ix+c)*_tileSize;
_block.y = y+(iy+r)*_tileSize;
_block.collide(Spr);
}
}
}
}
}

}
Free cake whippings every day at #flixel on irc.freenode.net.

Socapex

  • Active Member
  • ***
  • Posts: 156
  • Karma: +0/-0
    • View Profile
Re: FlxTilemapSheet
« Reply #1 on: Tue, Nov 10, 2009 »
Thanks alot! It is very appreciated :) I am getting to a point where my tilesheet is getting too big, and making all those tiles a strip is giving me nightmares. Do you think this would work with FLAN? I guess not, but I haven't tested flan out yet (waiting for mac version). From what I've been reading on it's site, you need to import your tiles as a sheet, correct?
Free cake every day at #flixel on irc.freenode.net.
Use your favorite IRC client or  http://webchat.freenode.net/

Titch

  • Contributor
  • ****
  • Posts: 270
  • Karma: +0/-0
  • Thing with the guy in the place.
    • View Profile
Re: FlxTilemapSheet
« Reply #2 on: Tue, Nov 10, 2009 »
As far as I know, it won't work with Flan at the moment because Flan tries to be smart and work out the tile height for you based on the image height, although I'm sure if somone asked nitram_cero very nicely he would add manual sizing back in.

It's not a problem for me, cos I use Mappy for my tilemaps.
Free cake whippings every day at #flixel on irc.freenode.net.

eirikhm

  • Guest
Re: FlxTilemapSheet
« Reply #3 on: Mon, Dec 28, 2009 »
Hi!


I just came across this post, and I'm giving it a go.

Are you sure you attached the correct class? The constructor name (GathTilemap) is different from the actual class name (FlxTilemapSheet)


EDIT: I just found out that this class is a bit outdated. Do you have a newer version that's compatible with the latest Flixel release?
« Last Edit: Mon, Dec 28, 2009 by eirikhm »

Socapex

  • Active Member
  • ***
  • Posts: 156
  • Karma: +0/-0
    • View Profile
Re: FlxTilemapSheet
« Reply #4 on: Mon, Dec 28, 2009 »
The latest flixel is compatible with tilesheets...  :P Check out the release notes on the wiki.
Free cake every day at #flixel on irc.freenode.net.
Use your favorite IRC client or  http://webchat.freenode.net/