AS3 Traces Bitmap as "[object Shape]" / Bug or feature, going loco - actionscript-3

i need to use the GetPixel32 on an Object in a movieclip.
in order to get to that object i use:
var bitmap=clip.getChildAt(0);
//and then
bitmap.bitmapData.getPixel32(x, y);
however, even though the childobject is a png i get an error and using
trace(clip.getChildAt(0));
traces "[object Shape]"
so does Flash convert certain bitmaps into shapes?
please see the this fla ( http://www.sendspace.com/file/uycmm5 ) to test it yourself.
Any ideas?

Bitmaps placed in Flash's timeline are converted to shapes (with bitmapfill) on compilation,
(UPDATE)
unless the image in the library has a linkage name, in which case it works as expected and compiles to a Bitmap object.
You can however draw a new bitmap with that shape:
var shape:DisplayObject = clip.getChildAt(0);
var bmp:BitmapData = new BitmapData(shape.width, shape.height, true, 0);
bmp.draw(shape);
bmp.getPixel32(x, y);

Related

Collision detection kit with FlashPunk

I start creating my flash game using Flashpunk, for collisions i didn't want to use hitboxes because i had images (PNG) with transparent parts in them so i decided to use Collision Detection Kit, i have a problem when creating the collision list, it takes a display object as a parameter and doesn't accept flash punk spritemaps, i tried to cast the spritemap to a flash display object but it's not working, is there a way to use the CDK with flashpunk ?
override public function begin():void
{
_player = new Player(100, 100);// Entity
initCollision(_player.sprPlayer);// The Entity Spritemap
}
private function initCollision(player:Spritemap):void {
collisionChecker = new CollisionList(player); // Problem here
}
Well, you could create an empty BitmapData with the same width & height of your Spritemap and then "render" it to that BitmapData, like so:
var bmd:BitmapData = new BitmapData(64, 64, true, 0);
var sprite:Spritemap = _player.sprPlayer;
sprite.render(bmd, new Point(0,0), new Point(0,0));
collisionChecker = new CollisionList(bmd);
That should draw the spritemap's current frame to a BitmapData which you could then use for the CollisionList. The code above is an example that only demonstrates how to do this. For your actual code, it would be better to avoid constantly initializing new variables during your collision detection.

Stumped getting bitmaps from movieClips in an external Flash SWF library

My testbed is able to composite a thousand elements into clips on screen, but I can't extract a bitmap on the fly from an external swf for Starling or for export to png.
(I'm a bit of a code butcher, but have tried lot of variations and have looked through spritesheet generating examples))
I have seen the advice "You can't get bitmapData from a Class only displayObjects (MClip, Sprite)", My line: s = new AssetClass() below seems to address that.
Correct usage of addtoStage when loading external swf
I am able to generate a bitmap of an internal vector movieclip, and save it to a .png using as3corelib.PNGEncoder.as, but I end up with a blank png using clips from the external swf, running this in Flash Pro CC..
paraphrased code:
// swf load done handler:
testBitmap = new Bitmap(new BitmapData(w, h , true, 0x0));
var AssetClass:Class = getDefinitionByName("assetNameFromDatabase") as Class;
var s:MovieClip = new AssetClass(); // AddChild(s) functions properly
var m:Matrix = new Matrix(1, 0, 0, 1, 400, 300);
testBitmap.bitmapData.draw(s, m);
// addChild(testBitmap); or send to PNGEncoder rsult is blank
// internal clip test that does convert to bitmap
var b:MovieClip = new testdMovieClip();
var m:Matrix = new Matrix(1, 0, 0, 1, 200, 300);
testBitmap.bitmapData.draw(b, m);
//----------------------------
Thanks Vesper, Couldn't gfix things with your suggestion, I was actually already adding to a movieClip, just left it out of the simplified code sample, I did try some variates of adding an instance ahead of drawing to bitmap, still getting no results.
//--
*** Amendment: Looks like the libs have embedded "display but don't copy" protect code? can someone verify this.
I am using merged movieclip libraries provided in swf format, (I have individual fla source for the hundreds of resources in the library swfs that I hoped to avoid dealing with, their removing swf import from Flash Pro cc is a further agrrevation) This is public domain material from a retired game.
Using a Trillix trial, I examined the embedded Class files, along with the usual individual asset Class they had this code:
public override function get movieClipData():flash.utils.ByteArray
{
if (bytes == null)
{
bytes = flash.utils.ByteArray(new dataClass());
}
return bytes;
}
{
bytes = null;
}
internal static var bytes:flash.utils.ByteArray=null;
// the classes also have
import flash.utils.*;
import mx.core.*; // as well as embedded package mx files, is that for Flex?
I was looking at creating some code-less external library files for Air/iOS down the road, I may have to learn to ways to auto merge FLAs sooner than later.
I have seen weird behavior of width and height properties of shape/sprite objects while they are not added to display list, they return -100 million or something. So you should add, then draw, then remove. This trick helped me when I wrote a dynamically generated sprite.
testBitmap = new Bitmap(new BitmapData(w, h , true, 0x0));
var AssetClass:Class = getDefinitionByName("assetNameFromDatabase") as Class;
var s:MovieClip = new AssetClass(); // AddChild(s) functions properly
addChild(s); // !
var m:Matrix = new Matrix(1, 0, 0, 1, 400, 300);
testBitmap.bitmapData.draw(s, m);
removeChild(s);
addChild(testBitmap); // now should display properly

Scaling AVM1Movie for using with BitmapData in as3

I have a actionscript 2 SWF that I am wanting to export into a PNG, however the fact that it is loaded as a AVM1Movie in as3 is proving quite troublesome.
When you load the as2 swf in just the normal standalone flash player, you can right click -> zoom in and it scales well since its redrawing the vector data at the size. But when i'm trying to make the Loader object (that contains the loaded as2 swf) scale, whenever i draw it to a BitmapData object, i just get the original size of the swf with blank space around it, rather then having the swf scale to the new dimensions.
My code looks like this:
var theFile:File = File(event.target);
var dis:DisplayObject = this.mLoader.content;
dis.width *=2;
dis.height *=2;
var bd:BitmapData = new BitmapData(dis.width, dis.height, true, 0x00000000);
trace("display object height and width is " + dis.width + " " + dis.height);
bd.draw(dis);
var stream:FileStream = new FileStream();
stream.open(theFile, FileMode.WRITE);
stream.writeBytes(PNGEncoder.encode(bd)); // needs as3corelib
stream.close();
Alert.show("saved to " + theFile.nativePath );
But when I open up the resulting PNG File, I get this (red shows the transparent background):
Is there any way to make it so that when I draw the as2 swf to BitmapData, it scales it like it would in the flash player?
I believe you should be able to simply use scaleX and scaleY properties instead of attempting to multiple the height and width values.
var dis:DisplayObject = this.mLoader.content;
//dis.width *=2;
dis.scaleX = 2;
//dis.height *=2;
dis.scaleY = 2;
EDIT
Alternatively since the above isn't working for you try to use a matrix argument for the draw call.
var mat:Matrix = new Matrix();
mat.scale(2,2);
bd.draw(dis,mat);

How can I load a Papervision/Flex application (SWF) as a material on a Papervision plane?

I am trying to build a portfolio application similar to the used by Whitevoid. I am using Flex 4 and Papervision3D 2. I have everything working except for one issue. When I try to load an external SWF as a material on one of the planes, I can see any native Flex or Flash components in their correct positions, but the papervision objects are not being rendered properly. It looks like the viewport is not being set in the nested swf. I have posted my code for loading the swf below.
private function loadMovie(path:String=""):void
{
loader = new Loader();
request = new URLRequest(path);
loader.contentLoaderInfo.addEventListener(Event.INIT, addMaterial);
loader.load(request);
}
private function addMaterial(e:Event):void
{
movie = new MovieClip();
movie.addChild(e.target.content);
var width:Number = 0;
var height:Number = 0;
width = loader.contentLoaderInfo.width;
height = loader.contentLoaderInfo.height;
//calculate the aspect ratio of the swf
var matAR:Number = width/height;
if (matAR > aspectRatio)
{
plane.scaleY = aspectRatio / matAR;
}
else if (matAR < aspectRatio)
{
plane.scaleX = matAR / aspectRatio;
}
var mat:MovieMaterial = new MovieMaterial(movie, false, true, false, new Rectangle(0, 0, width, height));
mat.interactive = true;
mat.smooth = true;
plane.material = mat;
}
Below I have posted two pictures. The first is a shot of the application running by itself. The second is the application as a MovieMaterial on a Plane. You can see how the button created as a spark object in the mxml stays in the correct position, but papervision sphere (which is rotating) is in the wrong location. Is there something I am missing here?
Man. I haven't seen that site in a while. Still one of the cooler PV projects...
What do you mean by:
I cannot properly see the scene rendered in Papervision
You say you can see the components in their appropriate positions, as in: you have a plane with what looks like the intended file loading up? But I'm guessing that you can't interact with it.
As far as I know, and I've spent a reasonable amount of time trying to make something similar work, the MovieMaterial (which I assume you're using) draws a Bitmap of whatever contents exist in your MovieClip, and if you set it to animated=true, then it will render out a series of bitmaps - equating animation. What it's not doing, is displaying an actual MovieClip (or SWF) on the plane. So you may see your components, but this is how:
MovieMaterial.as line 137
// ______________________________________________________________________ CREATE BITMAP
/**
*
* #param asset
* #return
*/
protected function createBitmapFromSprite( asset:DisplayObject ):BitmapData
{
// Set the new movie reference
movie = asset;
// initialize the bitmap since it's new
initBitmap( movie );
// Draw
drawBitmap();
// Call super.createBitmap to centralize the bitmap specific code.
// Here only MovieClip specific code, all bitmap code (maxUVs, AUTO_MIP_MAP, correctBitmap) in BitmapMaterial.
bitmap = super.createBitmap( bitmap );
return bitmap;
}
Note in the WhiteVoid you never actually interact with a movie until it "lands" = he's very likely swapping in a Movie on top of the bitmap textured plane.
The part that you are interacting with is probably another plane that holds the "button" that simply becomes visible on mouseover.
I think PV1.0 had access to real swfs as a material but this changed in 2.0. Sadly. Hopefully Molehill will.
cheers

Is graphic object bitMapData type the same as bitmapData type?

The title might be a little misleading. Look at my code and I will explain
public static function loadTile(tileDir:String = "empty"):void
{
if(tileDir != "empty")
{
tPoint = new Point(0,0);
tRect = new Rectangle(0,0,30,30);
//load in tile sheet image
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT,tilesLoadInit);
loader.load(new URLRequest(tileDir));
}
}
private static function tilesLoadInit (e:Event):void {
tileImage = Bitmap(loader.content).bitmapData;
tileReady.dispatchEvent(new Event("TileReady"));
}
var tImage:BitmapData = new BitmapData(30,30);
tileNum = tileNumber;
tPoint.x = 0;
tPoint.y = 0;
tRect.x = 0;
tRect.y = 0;
tImage.copyPixels(tileImage,tRect,tPoint);
this.graphics.beginBitmapFill(tImage);
this.graphics.drawRect(0, 0,tWidth ,tHeight );
I create a empty bitMapData called tImage. I then take a predefined variable called tileImage which is a bitMapData as well and contains a picture of an image. tRect is predefined as well its width and height is 30x30. I copy a piece of the image and I put it in tImage. problem is that AS3 throws an error saying that tImage is a incorrect type
ArgumentError: Error #2015: Invalid BitmapData.
But clearly it isnt. my question is that is there something different about the data type of bitMapData and bitMapData type that the graphic object accepts ?
I am trying to do tiling with sprites. I want my tiles to be interactive, so that is why I am using the sprite object instead of using regular bitMaps to represent my tiles. You might be wondering why I wouldnt just use graphics.beginBitmapFill(tImage); and graphics.drawRect(0, 0,tWidth ,tHeight ); to pick out the tiles I want to use. Well reason being is because it turns out that drawRect() first and second parameters actually alter the location of where the actual sprite sits at.
So if I set the x and y properties of the sprite to x = 20, and y = 20. then I set my drawRect(20,20). it actually adds an extra 20 pixels to my x and y coords of my sprite. And I know the reason why, I just need to know a better way. Sorry for so much writing and thanks for your time!
It's not saying the type is wrong, it's saying the object is invalid. I expect you'd get a TypeError if the type was wrong.
You've also not stated where exactly the error is thrown, and are assuming the problem is with tImage on the 8th line. It looks more likely that the problem is with tileImage (which you've given no details about) on line 7.
This is probably because of Flash's inbuilt limit to the size of BitmapData objects. If the total number of pixels is larger than 16,777,215, Error #2015 is thrown.
You can read up on it in the docs: BitmapData, Right above "View the examples".
Here's a trick that used to work if you want to give it a shot: BitmapData workaround