dcsimg
A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 22

Thread: Cut tiles from tileset bitmap using copyPixels

  1. #1
    Senior Member
    Join Date
    Mar 2003
    Posts
    161

    Cut tiles from tileset bitmap using copyPixels

    I'm trying to create a few functions so that I can easily load an external png file as my "tileset." Another function can then be used to cut specific tiles on-the-fly from my tileset and create them as a seperate (and much smaller) images.

    I've already created a system to do this (which I'll post when I get home), but it has many problems and so far I haven't been able to get it working how I would like.

    One problem I have is that when I call my function tilesetLoadSet(pngImageToLoad), it creates an empty movieclip with the moviecliploader class and loads the png file. "OnLoad," it creates a BitmapData variable. From what I can tell, the moviecliploader isn't working (unless I run the code within my function as regular code, instead of calling it within a function).

    Could anyone supply or point me in the direction of some useful functions to grab slices of an image?

  2. #2
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,928
    I've had problems with the movieClipLoader class too. You using listeners for it ?

    As to cutting up bitMaps, load the image into your holder mc, create another bitMap, use draw() to copy the image from your holder into the 2nd bitmap ( You can then delete the holder mc ), and then use copyPixels to split it up all nice and tiley.

    Squize.

  3. #3
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    Is it possible (and wise?) to leave my tileset BitmapData as a variable in memory (rather than attaching it to a container) and then simply referencing it when I make tiles?

    This is because I will be slicing tiles very frequently and it might use less resources to just leave it in memory instead of creating a snapshot of the bitmap again for EVERY tile I make...

    PS - Yes I use listeners with my movieClipLoader class. I'll attach the fla in a few minutes.

  4. #4
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    Ok I've attached my current project.

    Right now the problem seems to be with this function:
    code:
    function tileLoadSet(file,container) {
    //create a movie clip to hold tileset
    var tempMc:MovieClip = this.createEmptyMovieClip("tsLoad",this.getNextHig hestDepth());
    loader = new MovieClipLoader()
    loader.addListener(_root); //gives status updates by firing events
    loader.loadClip(file,tempMc); //load the external file into the holding movie clip
    //function is called by the 'loader' object when the file is loaded and ready to use
    function onLoadInit() {
    myBitmap = new BitmapData(tempMc._width, tempMc._height,true,0x00FFFFFF)
    //Snapshot the movie clip that contains the external file we loaded
    myBitmap.draw(tempMc)
    //attach bitmap to our container
    container.attachBitmap(myBitmap,1)
    //we don't need this movie clip anymore, so remove it
    tempMc.removeMovieClip()
    trace("Should have just removed clip...")
    }
    //function is called by the 'loader' object if the file couldn't be loaded
    function onLoadError() {
    //loader failed, freeing resources
    _root.tempMc.removeMovieClip()
    }
    }



    It creates a mc (tempMc), but after loading successfully (with the moveClipLoader class) it SHOULD remove the tempMc... it doesn't. It doesn't execute anything within the onLoadInit() function...
    Attached Files Attached Files

  5. #5
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,928
    Yep, going back to my original post, let's call that second bitmap we created ( that we draw() to so we can copyPixel() from ) the tileSheet.

    The tileSheet will just be a bitmap in memory, no need to attach it. The way I approached it was to just create an array to each tile, of the format

    [x,y]

    So you loop through the tileSheet at init time, just creating a big look up table of x,y coords. Then your map data can be fairly simple, they'd just be a look-up value ( eg

    The map data 1,2,3

    So from that each value would be an offset to our look-up table, so

    var offset=mapData[x][y];
    var tile=lookUpTable[offset];

    }

    'Cause the x and y's are stored it's just a straight forward case of using copyPixel to blit that tile from the tileSheet to your on screen bitmap.

    Hope that's some way clear.

    <Update - wrote this before seeing your code>

    Squize.

  6. #6
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    Hey, I managed to fix the loading issue with moveClipLoader. Here is the fix
    PHP Code:
    function tileLoadSet(file,container) {
        
    //create a movie clip to hold tileset
        
    var tempMc:MovieClip this.createEmptyMovieClip("tsLoad",this.getNextHighestDepth());
        var 
    loader = new MovieClipLoader()
        var 
    loaderListener = new Object()
        
    loaderListener.onLoadInit = function(tempMc,container) {
            
    myBitmap = new BitmapData(tempMc._widthtempMc._height,true,0x00FFFFFF)
            
    //Snapshot the movie clip that contains the external file we loaded
            
    myBitmap.draw(tempMc)
            
    //attach bitmap to our container
            
    container.attachBitmap(myBitmap,1)
            
    //we don't need this movie clip anymore, so remove it
            
    tempMc.removeMovieClip()
            
    trace("Should have just removed clip...")
        }
        
    loaderListener.onLoadError = function(tempMc) {
            
    //loader failed, freeing resources
            
    _root.tempMc.removeMovieClip()
        }
        
    loader.addListener(loaderListener); //gives status updates by firing events
        
    loader.loadClip(file,tempMc); //load the external file into the holding movie clip

    I'm still having trouble getting it to attach the image to the 'container' that I supply on frame two like this:
    code:
    var tilsetContainer:MovieClip = this.createEmptyMovieClip("test",1);
    tileLoadSet("1.png",tilsetContainer);


  7. #7
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    You shouldnt need to attach the bitmap to a container.

    You have the loading right, and that is all you need, you load in the PNG, you draw it to a new BitmapData, and then you throw away everything but the BitmapData.

    If you then want to display it (which you do, obviously) create a new BitmapData for the screen, and then copyPixels from the bitmap which contains the source tiles.
    Christopher Rhodes
    squarecircleco.

  8. #8
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    Ok, I have a question though. If I use a function like this to load a png into flash as a bitmapdata variable:
    code:
    function tileLoadSet(file) {
    //create a movie clip to hold tileset
    var tempMc:MovieClip = this.createEmptyMovieClip("tileLoading",this.getNe xtHighestDepth());
    var loader = new MovieClipLoader()
    var loaderListener = new Object()
    loaderListener.onLoadInit = function(tempMc) {
    //load complete, create bitmapdata
    var myBitmap:BitmapData = new BitmapData(tempMc._width, tempMc._height,true,0x00FFFFFF);
    myBitmap.draw(tempMc);
    //cleaning up
    tempMc.removeMovieClip();
    }
    loaderListener.onLoadError = function(tempMc) {
    //loader failed, freeing resources
    tempMc.removeMovieClip()
    }
    loader.addListener(loaderListener); //gives status updates by firing events
    loader.loadClip(file,tempMc); //load the external file into the holding movie clip
    }


    Should I be able to use that 'myBitmap' variable outside of the function? I can't seem to be able to... the variable seems to be "undefined" when traced. Or can I 'return' the variable at the end and then called the function like: "var tilesetBitmap:BitmapData = new tileLoadSet('1.png');"?
    Last edited by joncom11; 05-13-2006 at 01:34 AM.

  9. #9
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    push myBitmap into an array, or you could put myBitmap into the loaderListener (this.bitmap = myBitmap).

    Its dissapearing because you are defining the variable in that block only (var).
    Christopher Rhodes
    squarecircleco.

  10. #10
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    If I remove the "var" from my variable setting will it allow me to access it outside the function?

    EDIT - I can't see to establish that any bitmap is available to me... I try the following:
    code:
    tileLoadSet("1.png");
    this.createEmptyMovieClip("test",1);
    test.attachBitmap(myBitmap);



    Note, I also removed the "var " that deemed the first variable.
    Last edited by joncom11; 05-13-2006 at 02:53 AM.

  11. #11
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    Yes, but its a hack, making use of flash's terrible global scoping =D
    Christopher Rhodes
    squarecircleco.

  12. #12
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    I made that edit before I saw your response.^

    How would you recommend making it accessable then.

  13. #13
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    When I do it, I push all the loaded bitmaps into an array. That way you can also check if you have previously loaded that bitmap, so next time you request that bitmap, you can return it immediately.
    Christopher Rhodes
    squarecircleco.

  14. #14
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    So if I have the following
    code:
    function tileLoadSet(file) {
    //create a movie clip to hold tileset
    var tempMc:MovieClip = this.createEmptyMovieClip("tileLoading",this.getNe xtHighestDepth());
    var loader = new MovieClipLoader()
    var loaderListener = new Object()
    loaderListener.onLoadInit = function(tempMc) {
    //load complete, create bitmapdata
    myBitmap = new BitmapData(tempMc._width, tempMc._height,true,0x00FFFFFF);
    myBitmap.draw(tempMc);
    tilesetBitmaps.push(myBitmap);
    //cleaning up
    tempMc.removeMovieClip();
    }
    loaderListener.onLoadError = function(tempMc) {
    //loader failed, freeing resources
    tempMc.removeMovieClip()
    }
    loader.addListener(loaderListener); //gives status updates by firing events
    loader.loadClip(file,tempMc); //load the external file into the holding movie clip
    }

    tilesetBitmaps = [];
    tileLoadSet("1.png");
    this.createEmptyMovieClip("test",1);
    test.attachBitmap(tilesetBitmaps[0]);



    This should work? It doesn't seem to...

  15. #15
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    The problem is now, that tilesetBitmaps[0] probably wont exist when you attach it, as it hasn't loaded yet.

    But you're heading in the right direction.
    Christopher Rhodes
    squarecircleco.

  16. #16
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    How could I go about ensuring that is has loaded first? Just for testing purposes I put these lines on frame 150 instead:
    code:
    this.createEmptyMovieClip("test",1);
    test.attachBitmap(tilesetBitmaps[0]);



    That still didn't seem to work.

  17. #17
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    Put some more code on the listener, maybe advance to another frame (preferably call a function)

    and your 'attachBitmap' function is written incorrectly, the correct syntax is:

    attachBitmap(bitmapData,DEPTH);

    I've had that exact same problem before.
    Christopher Rhodes
    squarecircleco.

  18. #18
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    Ok cool. But I tried changing the "//cleaning up" code to this:
    code:
    //cleaning up
    tempMc.removeMovieClip();
    tempMc = this.createEmptyMovieClip("tileLoading",this.getNe xtHighestDepth());
    tempMc.attachBitmap(myBitmap,1);



    Just to see if I can handle the bitmap even before finishing finishing the function... It still didn't work. Is it not making a proper snapshot of the movieclip during "draw"?

  19. #19
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    Well try alt+control+v'ing, and seeing if the bitmapData has a width/height. chances are its been drawn if you called draw().

    But I think your problem there is your calling 'this.createEmptyMovieClip' while your inside the eventHandler, so your 'this' is referring to loaderListener
    Christopher Rhodes
    squarecircleco.

  20. #20
    Senior Member
    Join Date
    Mar 2003
    Posts
    161
    I'm trying to merge my tileset-loader/tile-slicer program with my working scrolling engine now, but when I put the code in with my scroller program I get the following error:

    **Error** Scene=Scene 1, layer=code, frame=1:Line 1: Syntax error.
    import flash.display.BitmapData;

    **Error** Scene=Scene 1, layer=code, frame=1:Line 2: Syntax error.
    import flash.geom.Rectangle;

    **Error** Scene=Scene 1, layer=code, frame=1:Line 3: Syntax error.
    import flash.geom.Point;

    Total ActionScript Errors: 3 Reported Errors: 3
    The lines: "import flash.display.BitmapData; import flash.geom.Rectangle; import flash.geom.Point;" seem to be causing trouble... Any ideas?

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