views:

218

answers:

2

As of right now. I have 3 objects. One BitMap that acts as my canvas. And 2 bitmapDatas. One is my buffer and another is my tiles. I am creating a tiling effect for a game. I would like to take my tile:BitMapData, and turn it into a custom object. reason being is I want each tile to be interactive. So I can click on each one. Is it possible to turn my bitMapData that represents a tile, into a custom object that has properties and methods. Sort of like a movie clip. and draw it into my buffer ?? Could I create a new class that extends bitMapData ?? Or would I have to get rid of the buffer and draw the tile objects directly into the BitMap ??

In other words, what is the best way to put Sprite or a tile into a BitMapData object or even a Bitmap.

+3  A: 

First of all, BitmapData and Bitmap are not interchangeable. They are two very different things. The BitmapData class contains bitmap pixel data, and allows you to manipulate that pixel data, e.g. draw to it, change the color of particular pixels, et c. There is no way of displaying a BitmapData directly, i.e. by adding it to the display list.

The Bitmap class, on the other hand, is a DisplayObject, like MovieClips and Sprites, which you can add to the display list. It's single purpose is to render a BitmapData in the display list. In fact, it is not even interactive, so you cannot detect clicks directly on a Bitmap instance, for example.

On to your question: If you have a bitmap data that contains a tile sprite, and you want to draw that tile in another bitmapdata, you can use the BitmapData.draw() method, or the BitmapData.copyPixels() method. The latter is one of the fastest methods you can use on any BitmapData, so I would highly recommend it.

Depending on your particular application, it might not be beneficial to draw everything in a bitmap at all. It sounds as if you want to be able to detect click events on all the tiles, which makes me think that you would probably benefit from having them be separate DisplayObjects, e.g. Sprites.

If you want to, you can create a Tile class that extends Sprite, and draws a BitmapData using a bitmap fill. That way, you can have any properties you want, and also detect mouse events on the tile instances.

package
{
  /* ... imports ... */

  public class Tile extends Sprite 
  {
    private var _solid : Boolean;

    public function Tile(bmp : BitmapData, solid : Boolean)
    {
      this.graphics.beginBitmapFill(bmp, null, false, true);
      this.graphics.drawRect(0, 0, bmp.width, bmp.height);

      _solid = solid;
    }

    /**
     * Sample custom property. Could be used to define whether a tile
     * is solid, e.g. the player cannot pass it.
    */
    public function get isSolid() : Boolean
    {
      return _solid;
    }
  }
}

This class could simply be instantiated for every tile in your game, passing in the bitmap data that should be drawn in the tile. You could also listen for events on such a tile instance.

var tile : Tile;

tile = new Tile(myBitmapData, false);
tile.x = 200;
tile.y = 200;
tile.addEventListener(MouseEvent.CLICK, handleTileClick);

addChild(tile);

This way, you don't have to use the Bitmap class at all to render the tiles. They can be added directly to the display list.

richardolsson
That sounds like what I will have to do. This is the only way I can make my tiles interactive, I can't think of another way. So it sounds like I should turn my canvas into a sprite object. then add my tile:Sprite objects inside of that. This means I would get rid of the buffer bitmapData object as well. Or, is it faster or possible to add a Sprite to a BitMap Object ?? To my knowledge that doesnt seem possible.
numerical25
You are correct. It is not possible to add display objects as children of a Bitmap (as it is not a DisplayObjectContainer.) But on the other hand, there is no reason why one would ever want to do such a thing. As a matter of fact, the Bitmap class has little general use at all.
richardolsson
I should clarify that what I'm saying in the above comment is that the Bitmap class does nothing that you cannot do with bitmap fills, the latter of which requires no object instantiation and doesn't add depth to the display list. In the end though, it's a matter of preference, so perhaps I shouldn't have said "as a matter of fact" :)
richardolsson
I understood what you meant. I did what you added and it worked. Only one problem though. I add the tilesheet using graphics.beginBitmapFill(). The tilesheet then becomes the sprite. I then use the graphics.drawRect() to pick out what part of the tilesheet to use. when I add the x and y coords to the function, those coords also add on to the coords that the sprite sits on that canvas. so some tiles sit x positions farther then where it suppose to be. do you know a simpler approach without adding an extraordinary amount of code.
numerical25
Well, in my code above, I always draw the tile at 0,0 in the sprite coordinate space. To position the tile, you don't modify the drawRect() call, but set the x and y properties of the Tile instance. I have edited the second block of code in the post to show an example of this.
richardolsson
A: 

I figure a better solution for when you want to select certain parts of the tile without effecting the position of the sprite itself

theMatrix.translate(30,0);
this.graphics.beginBitmapFill(tileImage,theMatrix);
//this.graphics.drawRect(0, 0,tWidth ,tHeight );
this.graphics.endFill();

Your right, leave drawRect at 0, 0. using Matrix.Translate, allows you to move the positioning of what part of the tile you want, without affecting the sprite position itself.

numerical25