AS3 As3IsoLib Adding Sprite - actionscript-3

I'm trying to add an image to a sprite then add it to the grid. The original size of the image is 276x202. However when it's been added to the grid it increases in size.
http://i.imgur.com/P1Jlq.png
The result is
http://i.imgur.com/0UPBH.png
public class main extends MovieClip
{
public function main()
{
var view:IsoView = new IsoView();
view.setSize((stage.stageWidth), stage.stageHeight);
view.clipContent = true;
addChild(view);
var gridHolder:IsoScene = new IsoScene();
view.addScene(gridHolder);
var scene:IsoScene = new IsoScene();
view.addScene(scene);
graphics.beginFill(0x000000, 1);
graphics.drawRect(0, 0, 800, 600);graphics.endFill();
var grid:IsoGrid = new IsoGrid();
grid.cellSize = 40;
grid.setGridSize(20, 20, 0);
gridHolder.addChild(grid);
gridHolder.render();
//var box:IsoBox = new IsoBox();
//box.setSize(40, 40, 40);
//box.moveTo(80, 80, 0);
//scene.addChild(box);
var player:IsoSprite;
var myLoader:Loader;
myLoader=new Loader();
myLoader.load(new URLRequest('imgs/DesertTankNE.png'));
//myLoader.width = 5; //Makes image disappear no matter what value is set.
//myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, OnComplete); //Doesn't change anything if we say on completion of loading image add it to the sprite.
player = new IsoSprite();
player.sprites = [myLoader];
//player.setSize(1,1,0); //Doesn't seem to affect anything no matter what size specified.
//player.width = 2; //Same as above
scene.addChild(player);
scene.render();
}
}
I've tried setting the width and height of the image when loading it and also tried setting the size of the sprite. The former makes the image not appear no matter what value is set and the latter doesn't seem to affect anything.

There is absolutely nothing wrong with your as3isolib code, and the image is not being resized in any way by code. Compare the tank image to the size of the grid cells (which should be 20 pixels width by 20 pixels height) and you should see that their relative sizes are ok.
The only problem there is that the whole flash stage is being resized. Are you testing your flash movie on the browser perhaps? Make sure you aren't setting the flash movie's width and height as 100% of its container in the HTML. If the flash movie is in a div and flash is told to be a width and height of 100%, it will stretch out to whatever size the div is.
Seeing your code I think you want your stage size to be 800x600; set your flash movie to those dimensions using the metatag SWF, for example:
[SWF(width="800", height="600", frameRate="30", backgroundColor="#FFFFFF")]
If you are using Flash Builder, you might need to clean your project a couple of times (Project -> Clean) to clear the previous compiler settings. Test your SWF movie outside of the broswer (double click the SWF file to open it on your local flash player) and make sure it has the proper dimensions. You should see the tank and the grid cells the right size now.
If you want to test it in the browser, don't use the HTML wrapper generated by Flash Builder (or Flash Pro). Make your own html using swfobject and set the correct width and height, for example:
<script type="text/javascript">
swfobject.embedSWF("myIsoTank.swf", "flash_container_div", "800", "600", "10", "expressInstall.swf");
</script>
This should get rid of your problem.

Related

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);

Movieclip -> BitmapData and origin

I'm trying to draw a MovieClip to a BitmapData so that it looks exactly the same as if I had done addChild(movieclip).
I can't seem to figure out what magic formula I need to use to keep the animation in place around it's origin.
This is the relevant bit of code:
private function update(e:Event):void
{
var bounds:Rectangle = movieClip.getBounds(movieClip);
bitmapData = new BitmapData(maxMCwidth, maxMCheight, true, 0x0);
bitmapData.draw(movieClip, new Matrix(1, 0, 0, 1, maxMCwidth - (bounds.x + bounds.width), maxMCheight - (bounds.y + bounds.height)));
bitmap.bitmapData = bitmapData;
}
Full code here: http://pastebin.com/KyU5FPeJ
And this is what the result looks like:
http://www.swfcabin.com/open/1339173476
The top animation is done using addChild(mc). The bottom animation is done using bitmapData.draw. Notice how the sword on the right doesn't move horizontally in the bottom version. Almost as if the whole animation was getting right-aligned.
Here's also a link to my flashdevelop project with the full code in case anybody wants to play around with it: https://www.dropbox.com/s/gvt4scknqdian2a/bitmapdatadrawing.zip
I just want both versions to look the same. What do I need to change to my bitmapData drawing code to make this happen?
Ok I figured it out!
The cause of the problem was that I'm not calculating maxMCwidth or maxMCheight correctly. I was going through the movieclip looking for the widest/highest single frame. BUT that doesn't take into account that the position of bounds across frames changes. To get the actual maximum width/height across the whole animation, I used this code:
maxBounds = new Rectangle();
for (var i:uint = 0; i < movieClip.totalFrames; i++)
{
var tempBounds:Rectangle = movieClip.getBounds(movieClip);
maxBounds = maxBounds.union(tempBounds);
movieClip.nextFrame();
}
Then this allowed me to fix the translation matrix:
bitmapData.draw(movieClip, new Matrix(1, 0, 0, 1, -maxBounds.x, -maxBounds.y));
And like this it works for every animation I've tested.
Ok I can't get your project to run since you didn't supply a main mxml.
However, I think I found your issue.
I don't think getBounds is returning the values you think they are.
I can't look into the skeleton swc but I have a feeling there is on object off the top or bottom of the screen in it and the way you coded it would cause it to shrink down to make it fit.
getBounds is probably adding that to the height.
bitmapData = new BitmapData(movieClip.width, movieClip.height, true, 0x0);
bitmapData.draw(movieClip, new Matrix(1, 0, 0, 1, movieClip.width/2, movieClip.height/2 ));
bitmap = new Bitmap(bitmapData);
bitmap.x = 70;
bitmap.y = 200;
Remember untested code here. :(

In AIR/AS3 How to capture image of whats visible on the stage and save that image as anything like jpg/pdf

In AIR/AS3 Flex Mobile for Android project.
How can I capture an "image" of whats visible on the view
then just save that image as anything like jpg/pdf to the SD card?
Basically a screenshot on Android using AS3.
private function getBitmapData( target:DisplayObject ) : BitmapData
{
//target.width and target.height can also be replaced with a fixed number.
var bd : BitmapData = new BitmapData( target.width, target.height );
bd.draw( target );
return bd;
}
Create the byte array using JPEGEncoder and save this to Your sd card. In some case if the width and height of the target is not working, You can use the getbounds method to get the bounds of the object and from the bounds take the width and height.

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

How to get the size of an embedded image / swf?

Normally if you were loading an image from a URL you would do the following:
m_image = new Image();
m_image.addEventListener(Event.COMPLETE, image_completeHandler, false, 0, true);
m_image.source = "http://www.example.com/image.jpg";
private function image_completeHandler(event:Event):void
{
// Image content has now loaded, we need to wait for it to validate it's size
m_image.addEventListener(FlexEvent.UPDATE_COMPLETE, image_updateCompleteHandler, false, 0, true);
}
private function image_updateCompleteHandler(event:FlexEvent):void
{
// Do stuff with width / height
}
But, if you set the source to an embedded image class, the complete event doesn't appear to fire. So my question is, how can you get the width / height of an embedded image / swf?
The instatiation of any embedded asset is syncronous (I think the only exception is Loader.loadBytes), so as soon as you do it you can access all its properties:
image = new EmbeddedImage();
trace(image.width, image.height);