flash as3 tiling background horizontally

Hellow all,

Let me explain the situation. I have this fluid flash layout, on resize elements are repositioned on the screen. I have a part that need to tile only horizontally. I have imported the png file and that is where i get stuck.

I cannot seem to create the code that tiles the bitmap horizontally, and on resize the bitmapfill needs to align itself to the bottom of the stage.

Who can help me with this (need AS3 code)

greetz,
walter
LVL 8
wal_toorAsked:
Who is Participating?
 
Jakob_ECommented:
Hi Walter,

I asume you imported the imager to your library - right?
If so then right-click it and select properties. Now you'll get the bitmap property window*
If displayied in basic mode click the advanced button to display the linkage options.
In the input field Class enter a name like "PixPattern" to make it accessible thru actionscrpt
*) see attached.
 

    // Align your stage top left and add a resize listener
    stage.align=StageAlign.TOP_LEFT;
    stage.addEventListener(Event.RESIZE,drawTiles,false,0,true);
   
   // Create a variable to hold the bitmapData of your image and fill it with    // the data from your PixPattern class
    var bmd:BitmapData=new PixPattern(0,0);
   
   // Create a shape to act as canvas
    var canvas:Shape=new Shape();
    addChild(canvas);
   
    // Create a function to draw the tiles to your canvas
    // 1  clear the canvas
    // 2  use your bitmapData as paint - remember to set repeat=true (third parameter)
    // 3  draw a rectangle using stageWidth and bitmapData height
    // 4  stop painting
    // 5  align to bottom of stage
    function drawTiles(e:Event):void {
        canvas.graphics.clear();
        canvas.graphics.beginBitmapFill(bmd,null,true,false);
        canvas.graphics.drawRect(0,0,stage.stageWidth,bmd.height);
        canvas.graphics.endFill();
        canvas.y=Math.ceil(stage.stageHeight-canvas.height);
    }
   
    // Call drawTiles to paint the canvas when your movie has loaded
    drawTiles(null);



Note! if you neet to be able to click your canvas then just use Sprite instead of Shape


Best,
Jakob E

BitmapProperties.png
0
 
IqAndreasCommented:
Attached is code showing how you could do it on the timeline, but I can gladly port it to being a class if you would prefer.

It creates a new Bitmap with a width as wide as the stageWidth and a hight the size of the passed in bitmap, docked to the bottom of the stage.

If you would like me to modify the code in any way to suit your needs better, or if there is any part of the code you would like me to explain, just ask. There may be a bug or two in the code, but if you have any problems, just post the error message and I will fix it up.

There is more information on BitmapData.copyPixels() in these links:
http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/display/BitmapData.html#copyPixels%28%29
http://gamedev.michaeljameswilliams.com/2010/02/28/blitting-movie-clips-flash-as3/

Cheers,
Andreas
var imageToTile:Bitmap = ...;
var imageToTileBMD:BitmapData = imageToTile.bitmapData;

var tileBitmap = new Bitmap();
this.addChild(tileBitmap);

//Start the initial drawing
redrawTiles();

stage.addEventListener(Event.RESIZE, redrawTiles);

function redrawTiles(ev:Event):void
{
    //Figure out how many tiles need to be drawn to fill the stage width
    var totalTiles:int = Math.ceil(stage.stageWidth / imageToTileBMD.width);
    var bmd:BitmapData = new BitmapData(stage.stageWidth, imageToTileBMD.height);
    var sourceRect:Rectangle = new Rectangle(0, 0, imageToTileBMD.width, imageToTileBMD.height);
    
    for (var i:int = 0; i < totalTiles; i++)
    {
        bmd.copyPixels(imageToTile, sourceRect, new Point(i * imageToTileBMD.width, 0));
    }
    
    tileBitmap.bitmapData = bmd;
    
    tileBitmap.x = 0;
    tileBitmap.y = stage.stageHeight - tileBitmap.height;
}

Open in new window

0
 
wal_toorAuthor Commented:
Hello all,

Thanks for your replies...

@ iqandreas
I have tried your solution but it gives me an error:
1067: Implicit coercion of a value of type flash.display:Bitmap to an unrelated type flash.display:BitmapData.
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

stage.addEventListener(Event.RESIZE, resizeListener,false,0,true);

// Create a variable to hold the bitmapData of your image and fill it with
// the data from your PixPattern class
 var bmd:BitmapData=new grass(0,0);
   
// Create a shape to act as canvas
var canvas:Shape=new Shape();
addChild(canvas);
   
// Create a function to draw the tiles to your canvas
// 1  clear the canvas
// 2  use your bitmapData as paint - remember to set repeat=true (third parameter)
// 3  draw a rectangle using stageWidth and bitmapData height
// 4  stop painting
// 5  align to bottom of stage
function drawTiles(e:Event):void {
	canvas.graphics.clear();
	canvas.graphics.beginBitmapFill(bmd,null,true,false);
	canvas.graphics.drawRect(0,0,stage.stageWidth,bmd.height);
	canvas.graphics.endFill();
	canvas.y = Math.ceil(stage.stageHeight-canvas.height);
}

// resize stage
function resizeStuff():void{
	var movieWidth:Number = stage.stageWidth;
	var movieHeight:Number = stage.stageHeight;
	
	backgroundMC.width = movieWidth;
	backgroundMC.height = movieHeight;
	
	big_header.x = movieWidth/2;
	big_header.y = 100;
	
	drawTiles(null);
}

// resize stage listener function
function resizeListener(e:Event):void {
	resizeStuff();
}

resizeStuff();
// Call drawTiles to paint the canvas when your movie has loaded
drawTiles(null);

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
wal_toorAuthor Commented:
Hey, part of the previous comment is missing... strange..

@ jacob

Nice short code.. But somehow a tile gets copies on the TopLeft of the page.
Check: http://www.skyboxdevelopment.nl/clients/pepijn/

I have posted the code in the previous comment.

greetz,
walter
0
 
Jakob_ECommented:
Hi Walter,

Be sure that the image is only in your library (not on the stage).

Best,
Jakob E  
0
 
IqAndreasCommented:
As for my code, which value did you set the image as?

Let's say your Bitmap it named "BackgroundImage" in the library. The code should look like this:
var imageToTile:Bitmap = new BackgroundImage();var imageToTileBMD:BitmapData = imageToTile.bitmapData;

If you already have the bitmap you want to copy on the stage, do like this:
var imageToTile:Bitmap = myBitmapThatIsOnTheStage;
var imageToTileBMD:BitmapData = imageToTile.bitmapData;
this.removeChild(myBitmapThatIsOnTheStage);

And then the rest of the code. Give it a try, and it should work.

If not, if you debug using CTRL+SHIFT+ENTER, you are told the exact line that the error is at. Post back EXACTLY what error it gives you, and it will be easier to debug.
0
 
wal_toorAuthor Commented:
@jakob

How stupid of me... yes it was the image in the stage... works perfectly!
0
 
wal_toorAuthor Commented:
@IqAndreas

Still getting errors...

line 27 1067: Implicit coercion of a value of type flash.display:Bitmap to an unrelated type flash.display:BitmapData.
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

stage.addEventListener(Event.RESIZE, resizeListener);

// --- tile
var imageToTile:Bitmap = new grass(0,0);
var imageToTileBMD:BitmapData = imageToTile.bitmapData;

var tileBitmap = new Bitmap();
this.addChild(tileBitmap);

//Start the initial drawing




function redrawTiles(ev:Event):void
{
    //Figure out how many tiles need to be drawn to fill the stage width
    var totalTiles:int = Math.ceil(stage.stageWidth / imageToTileBMD.width);
    var bmd:BitmapData = new BitmapData(stage.stageWidth, imageToTileBMD.height);
    var sourceRect:Rectangle = new Rectangle(0, 0, imageToTileBMD.width, imageToTileBMD.height);
    
    for (var i:int = 0; i < totalTiles; i++)
    {
        bmd.copyPixels(imageToTile, sourceRect, new Point(i * imageToTileBMD.width, 0));
    }
    
    tileBitmap.bitmapData = bmd;
    
    tileBitmap.x = 0;
    tileBitmap.y = stage.stageHeight - tileBitmap.height;
}
// ---



function resizeStuff():void{
	var movieWidth:Number = stage.stageWidth;
	var movieHeight:Number = stage.stageHeight;
	
	backgroundMC.width = movieWidth;
	backgroundMC.height = movieHeight;
	
	big_header.x = movieWidth/2;
	big_header.y = 100;
	
	redrawTiles(null);
}

resizeStuff();

function resizeListener(e:Event):void {
	resizeStuff();
}

Open in new window

0
 
wal_toorAuthor Commented:
Ey... again... whole pieces of my comments are ignored when posting strange..

@IqAndreas

here are the errors again:

@IqAndreas

Still getting errors...

line 27 1067: Implicit coercion of a value of type flash.display:Bitmap to an unrelated type flash.display:BitmapData.
0
 
wal_toorAuthor Commented:
And again pieces of my comments are ignored... now in richtext editing mode...

@IqAndreas

Still getting errors...

line 27 1067: Implicit coercion of a value of type flash.display:Bitmap to an unrelated type flash.display:BitmapData.
bmd.copyPixels(imageToTile, sourceRect, new Point(i * imageToTileBMD.width, 0));

line 7 1067: Implicit coercion of a value of type grass to an unrelated type flash.display:Bitmap.

var imageToTile:Bitmap = new grass(0,0);

I have posted the code below. The bitmap is in the library an has and the classname is 'grass'

By the way, what is the difference between your code and jakob's? Is one faster than the other or...

greetz,
walter
0
 
IqAndreasCommented:
Ugh... Sorry about that. :P

Line 27 is supposed to read like this:
bmd.copyPixels(imageToTile.imageToTileBMD, sourceRect, new Point(i * imageToTileBMD.width, 0));

As for the error on line #7, what type of object is Grass? Is it a MovieClip or a graphic? If it is a MovieClip, replace lines 7 and 8 with the following code:
var grassMC:grass = new grass();
var imageToTileBMD:BitmapData = new BitmapData(grassMC.width, grassMC.height);
imageToTileBMD.draw(grassMC);

That should make it work just fine.


Regarding the difference, my code creates a new Bitmap and draws the same image tiled several times onto it. Jakob's code creates a new Sprite or MovieClip, and draws a vector rectangle onto it, with an image as the background to the fill.

The difference in codes is actually quite small, however, his code is likely to generate the tiles a little faster, while my object will likely redraw faster once created, which is good for if you tween it or move it over time in any way. However, if you always keep it still at the bottom of the screen, there isn't any difference at all.

Should I explain what the code is doing better? Were you able to get it to work? Is there anything more I can help you with?


Good luck with your programming,
Andreas
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.