A Flash Developer Resource Site

Results 1 to 15 of 15

Thread: [AS3] Need Help Creating Tile-Based Map

  1. #1
    Member
    Join Date
    May 2008
    Location
    Ohio, USA
    Posts
    63

    [AS3] Need Help Creating Tile-Based Map

    I'm working on a platform game and I'm a little stuck on the map building part. I've already got a working example that takes a set of tiles and draws a map with them, but it only works if all the tiles are aligned in one row on the same tile sheet. This is fine for my test level, which only has 4 different tiles, but I'm planning on making bigger and more complex maps with 50 or more different tiles.

    Is there a way I can make an array that will store the x and y position of each tile? If not, what other method should I use? An XML file maybe? I'd also like to be able to group similar tiles together in their own tile sheets - grass/trees/bushes in one, dirt/stone/sand in another, etc. How would I tell the map builder function which tile sheet the tile is in, though?

  2. #2
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    http://www.tilemap.co.uk/mappy.php
    http://board.flashkit.com/board/show...ght=map+editor
    http://tilestudio.sourceforge.net/
    http://mapeditor.org/screenshots.html
    http://www.codeproject.com/KB/game/mapeditor.aspx
    ...
    *google is your friend*

    or simply code your own,- if you have the engine working a few code lines would be enough to:
    - register the mouse tile/cell position
    - fill it with a defined ID (the map array)
    - export function to trace out the array as string

  3. #3
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    The first one of those links, Mappy, is the one I've used for years. It uses lua as the scripting language for the exporter, so you can just code your own to spit the map data out in whatever format you want ( Funnily enough just updated my code a couple of days ago, and according to the comments I did the original in 2005, so yeah Mappy is more than good enough to use in real world environments ).

    As to the actual tile plotting, you can go a couple of ways with that. When you load the tilesheet you can copyPixel out each tile into their own bitmap and then just attach them to the holder ( ie tile ) mc when updating them.
    Or you can use a simple bit of maths to find each tile when you need it. If you know your tile width and height, and the width of the tilesheet you can easily calculate the x / y coords of any tile on it.

    For setting different tilesheets for different levels, have a very simple levelObject in your game. This will hold basic info like:
    * map data
    * tileSheet
    * player start x/y

    Basically it's a case of pulling in all your dumb data from the server ( images / maps ) and then parsing them into something you can actually use in the game, and then storing easy references to that.

    ( I'm just doing all this in as3 for the first time, and it's just as simple as as2 to be honest ).

    Squize.

  4. #4
    Member
    Join Date
    May 2008
    Location
    Ohio, USA
    Posts
    63
    I've got a basic map builder working already. I have an array that stores the position of each tile in the tile sheet (0, 1, 2, etc.). Then I have a Bitmap that contains the entire tile sheet for my level and another Bitmap that I copy all of the tiles into to create the map. Since each tile is 40x40, I multiply the number in the array by 40 and use that as my starting point, then copy a 40x40 section out of the tile sheet to get my tile and place it on the map. My map builder function runs through the entire array and copies each corresponding tile to the map Bitmap, then adds that Bitmap to the stage. The whole thing is done with copyPixels and BitmapData.

    This all works fine, except all the tiles have to be in one row and on the same tile sheet. I can't have a tile sheet that's 5 tiles wide and 5 tiles tall, for example, or gather tiles from more than one sheet, because my arrays only store one value per tile. I need a way to supply more than just one value to the map builder, so I could tell it which tile sheet to copy the tile from, how many tiles over it is, and how many tiles down. I don't know of any way to do this using an array like I'm doing now, but I also don't know of any other way to manage my level data. That's what I need help with. I've read through at least a dozen different tutorials already, but they all assume you'll only be working with 4 or 5 different tiles on one sheet.

    I do like the Tiled map editor that render posted, though. Mostly because it works on my Mac. I've tried Mappy before on Windows and I liked it a lot, but I can't justify installing an XP virtual machine just to run a map editor.

  5. #5
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    hmm maybe these threads might be of inspiration
    http://board.flashkit.com/board/showthread.php?t=725001
    http://board.flashkit.com/board/showthread.php?t=706063

    in booth cases I used a mix of libary and library item information to define a single tile. I use this concept even today in newer engines that dont have that much in common with tiles.
    The idea is that you can have multiple spriteSheets or librarys and each of course multiple sprites.

    a excerpt of the 1st link
    Quote Originally Posted by renderhjs View Post
    ...
    some samples (all: 3x3 matrix) I could imagine:

    simplified text:
    Code:
    1,2,3
    5,3,44
    11,12,1
    simplified array:
    Code:
    map = [[1,2,3],[5,3,44],[11,12,1]];
    simplified xml:
    Code:
    <row>1,2,3</row>
    <row>5,3,44</row>
    <row>11,12,1</row>
    simplified xml B:
    Code:
    <r v="1,2,3"/>
    <r v="5,3,44"/>
    <r v="11,12,1"/>
    advanced xml (library association, allowing to use multiple sprite sets)
    see my zelda engine for input or details on this:
    http://board.flashkit.com/board/showthread.php?t=706063
    Code:
    <r>a-1,a-2,e-3</r>
    <r>water-5,rock-3,rock-44</r>
    <r>water-11,water-12,rock-1</r>
    the last one is what I meant- of course you would have to define somewhere else (usually a header) what a, rock or water stands for e.g which spriteSheet.

  6. #6
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,378
    I'm going to assume 5 different tile sheets in the library are conveniently named "sheetA" through "sheetE"...

    Code:
    var levelmap = new BitmapData(200, 200, true, 0);
    var p = new Point(0, 0);
    var r = new Rectangle(40, 40);
    
    
    mapdata = 
    [["E-3", "E-1", "E-2", "E-1", "E-4"],
    ["E-6", "A-2", "C-4", "A-2", "E-6"],
    ["E-6", "A-2", "C-3", "A-2", "E-6"],
    ["E-6", "A-2", "A-2", "A-2", "E-6"],
    ["E-5", "E-7", "A-2", "E-8", "E-9"]];
    
    for (var i = 0; i< mapdata.length; i++) {
    for (var j = 0; j< mapdata.length; i++) {
    var bmd = new BitmapData.loadBitmap("sheet" + mapdata[i][j].split("-")[0]);
    var frame = mapdata[i][j].split("-")[1];
    p.x = i*40;
    p.y = j*40;
    
    r.x = frame*40;
    
    levelmap.copyPixels(bmd, r, p);
    }
    }
    Sorry. It'll need to be ported to AS3.

    Also, I assumed your tilesheets were a single row of tiles. If they are say, all 5 tiles wide, then you can do this instead:

    Code:
    r.x = int(frame/5)*40;
    r.y = (frame%5)*40;
    Last edited by ImprisonedPride; 03-22-2009 at 12:59 PM.
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  7. #7
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    in addition to whats already been said here- going with XML is good and perhaps a essential way to go- as it lets you store the map files out of flash get the real benefit out of a map editor.
    Writing bloated arrays in actionscript is not always nice to manage - hence the option to go with XML.

  8. #8
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,378
    It was an example. I'm not going to demonstrate importing xml for him.
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  9. #9
    Member
    Join Date
    May 2008
    Location
    Ohio, USA
    Posts
    63
    So basically you're saying I could use an XML file, and then define the tile sheet, row and column inside that? I took a look at the posts you linked to but it doesn't make much sense to me. I think it's all a little over my head. Could I just use something like this instead?

    PHP Code:
    <tilerow>
       <
    tilecol>
          <
    tilesheet>water</tilesheet>
          <
    rownum>0</rownum>
          <
    colnum>0</colnum>
       </
    tilecol>
    </
    tilerow
    Then I could just reference them with xmlFile.tilerow[0].tilecol[0].tilesheet, right?

  10. #10
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    that might be a code friendly XML but a terrible one to read and edit in a editor - and that should be the main goal in this case if you go with XML.
    If you write the maps like that you have like 70 - 80% wasted filesize in your XML - use less characters and a less bloated architecture.

    e.g sample:
    PHP Code:
    <map a="sprite_1.png" e="sprite_2.png" >
        <
    r>a-1,a-2,e-3</r>
        <
    r>b-5,b-3,b-44</r>
        <
    r>d-11,d-12,d-1</r>
    </
    map
    which is a perfect valid XML but its way more easy to read with the eyes and by that fix.

  11. #11
    Member
    Join Date
    May 2008
    Location
    Ohio, USA
    Posts
    63
    How would I actually use something like that, though? I know how to get any given value using my method, even if it would be a nightmare to create and edit. Ideally I'd like to be able to do something like this:

    PHP Code:
    <map>
       <
    r>water-0-0water-0-1water-0-2</r>
       <
    r>dirt-0-1dirt-3-2dirt-4-4</r>
    </
    map
    And then use the first value as the tile sheet, the second one as the row number, and the third one as the column number. How would I differentiate between them, though? I've got essentially the same thing working using ImprisonedPride's method - is there some way to mimic the Array.split() method with an XML file? If not I might just stick with using arrays like I was originally planning.

  12. #12
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    And then use the first value as the tile sheet, the second one as the row number, and the third one as the column number.
    does not make one bit sense to me,- perhaps rethink that.
    with:
    PHP Code:
    <map>
       <
    r>water-1water-2water-4</r>
       <
    r>dirt-1dirt-2dirt-4</r>
    </
    map
    you already have 2 rows and 3 columns which you could read as:
    PHP Code:
    water-1  |  water-2  |  water-4
    dirt
    -1  |  dirt-2  |  dirt-
    and reagarding reading it something like this would do:
    PHP Code:
    function getTileId(row,column):Object{
    var 
    item:String xml.firstChild.childNodes[row-1].firstChild.split[","][column-1];
    var 
    category:String item.slice(0,item.indexOf("-"));//e.g water, dirt
    var nr:Number int(Numberitem.slice(item.lastIndexOf("-")+1,item.length) )); 

    the XML should imo. also be help of the structual information so that you can read somewhat how many rows and columns there are

  13. #13
    Member
    Join Date
    May 2008
    Location
    Ohio, USA
    Posts
    63
    Quote Originally Posted by renderhjs View Post
    does not make one bit sense to me,- perhaps rethink that.
    What I mean is, say I have a tile sheet called "water" with 15 tiles, which is 5 tiles wide and 3 tiles tall. In my XML file, if I wanted to refer to tile 3,1 (3 over and 1 down) from the water sheet, I'd use "water-3-1" and it would find the appropriate tile when I built my map.

    As for your function, basically what you're doing is parsing the XML file into a string, then splitting that string into the individual entries, like IP was doing with the array?

  14. #14
    Member
    Join Date
    May 2008
    Location
    Ohio, USA
    Posts
    63
    Here's what I've got so far, adapted from your example.

    PHP Code:
    var xmlSplit:String xml.r[0].split(",")[0];
    var 
    xmlSheet:String xmlSplit.split("-")[0];
    var 
    xmlRow:int xmlSplit.split("-")[1];
    var 
    xmlCol:int xmlSplit.split("-")[2];
    trace(xmlSheetxmlRowxmlCol); 
    With the follow XML file as a source:

    PHP Code:
    <map>
       <
    r>water-0-1</r>
    </
    map
    The trace output is "water 0 1"

    Success! Thanks to everyone who responded. Now I just have to get to work writing the XML files.

  15. #15
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    ah okay makes sense now - so the spritesheet is devided in rows and columns as well. Its just that I imagined (the way I did things so far ) is that you automaticly tile the spritesheet based on possible dividing columns/rows,

    e,g (not perfect but roughly the way)
    PHP Code:
    getSpriteSheetTile(5);

    function 
    getSpriteSheetTile(nr:int):BitmapData{

        var 
    math.floor(spriteSheet.width 32);
        var 
    Math.floor(spriteSheet.height 32);
        
        var 
    Math.floornr );
        var 
    nr w;
        
        var 
    bmp = new BitmapData(32,32);
        
    bmp.copyPixels(spriteSheet,new Rectangle(x*32,y*32,32,32));

    which would make adressing things easier + the xml alot smaler

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center