Prevent height change of a DisplayObject - actionscript-3

Is there a way to prevent the automatic change of the height property of a DisplayObject? It automatically resizes to match content, though my swf file is 32 pixels height. The code below can show prove of this, first frame enemy.height is 32 but later is 27.5, and this messes up my script.
getRect() and getBounds() return exactly the same. Also, I want to know why in the first frame it shows the correct height and in the second it changes, it should show 27.5 from the beginning.
package {
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
private var enemy:Sprite;
[Embed(source = '../lib/enemy.swf')] private var swf:Class;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function update(e:Event):void {
trace(enemy.height);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
enemy = new swf();
addChild(enemy);
addEventListener(Event.ENTER_FRAME, update);
}
}
}

This has to do with the fact that you're instantiating a whole SWF, and 1 frame has to pass for it to be synced to the Main swf. What I would do is export the symbol in the .fla, then use the "embed symbol" syntax in Flex:
[Embed(source='enemy.swf#Symbol1')]
private var swf:Class;
In this case, the height will be consistent even in the first ENTER_FRAME. If it's not the height you want, you can use the invisible shape to set the bounds.

A "hacky" solution might be to add a shape to the enemy that has the max size you want, then set it to be invisible. I have created hit boxes for objects that way and it worked quite well.
One way would be to add it when creating the object in the Flash IDE. Just draw it and position it as you want the shape to be, then give it an instance name, like "sizeHolder". After you create the enemy you would then call
enemy.sizeHolder.visible = false;
In the Flash IDE you could place it on another timeline, then make that timeline invisible and lock it, so it wouldn't get in your way when editing the actual object.
The other way would be to add it by code. Draw the object in another DisplayObject, set it to invisible and then addChild it to enemy.

The enemy sprite animation sequence
will vary in height.This is part of
the animation process. Hence the
actual height per frame will vary
based on bounding box of the sprite.
As you very well observed this is the
default behavior.
The ways:
The One you are presently following storing height and using for calculations.(better)
As EyeSeeEm suggested if i understood him correctly having an invisible height sprite background with proper centering of the movie clip center point and centering of the sprite in each frame to be contained in the invisible height sprite bounds.
You will often find that you will come across features in action script not working the way you want it to.Whats important is that you adapt the coding to facilitate the solution . It is not hack y or inefficient when and coding/method allows for easily making further changes/extensions.
P.S:
This would depend on situation but personally i would rather the height be dynamic according to the sprite animation instance so any hits to the enemy just nearly over its head by projectiles doesn't actually kill the enemy.

Try
import flash.display.StageAlign;
import flash.display.StageScaleMode;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

Related

Bitmap inside a Sprite - But still not clickable? AS3

Basically I've got a bitmap which is an image that the user captures from a webcam which was previously stored as bitmapdata which I converted into a bitmap and added it onto the stage..
From here I want the bitmap to be selectable so I can do other things to it, so I realised I would need to add this into sprite in order to add event listeners onto it.
Having done so, for some reason my application ain't wanting to recognise the events added?
Here is the code I've got..
Bitmap..
//Create a new bitmap from the video capture
image = new Bitmap(bitmap,"auto",true);
//Set the width and height properties
image.width=150;
image.height=125;
//Set the stage position
image.x = 430;
image.y = 280;
stage.addChild(image);
Sprite..
var imageSprite:Sprite;
imageSprite = new Sprite();
imageSprite.x = 200;
imageSprite.y = 50;
imageSprite.addChild(image);
stage.addChild(imageSprite);
Event listener:
imageSprite.addEventListener(MouseEvent.MOUSE_DOWN, SelectWebImage1);
Function:
function SelectWebImage1(e:MouseEvent): void {
trace("Clicked");
}
I receive no errors from this but I noticed that when I have that code written in my application, all of the code underneath it doesn't seem to function?
I really don't know what i'm doing wrong, any help appreciated thanks!
When you set Sprite's dimensions, you implicitly set its scale, and also if you place some graphics by using width and height, the width and height includes any sprite's children, accounting for their position. You should place that bitmap into imageSprite and not set x,y proerties for the bitmap, this way you won't have to account for its position inside the sprite to position the bitmap.

AS3: MouseEvent not working?

When I click on it nothing is being outputted. Is there a reason why the MouseEvent is not being applied to the rectangle. Where am I going wrong?
My Code:
import flash.display.Shape;
import flash.events.MouseEvent;
stop();
var rectangle001:Shape = new Shape;
rectangle001.graphics.beginFill(0x00D783);
rectangle001.graphics.drawRect(10, 10, 50, 50);
rectangle001.addEventListener(MouseEvent.CLICK, rectangle001Click);
function rectangle001Click (event:MouseEvent){
trace("Hello World!");
}
addChild(rectangle001);
All answers appreciated.
You should use Sprite instead of Shape if you want mouse interactivity.
Quoting from an answer on this page:
Shape is the one with the least possibilities. Use it when you only want a DisplayObject with graphics, and no mouse interaction.
Sprite is the parent class of quite everything you need. Since it is a DisplayObjectContainer, you can use it as a basic container for other components. You can also catch mouse events on this one.
MovieClip is a Sprite with the ability to use frames. Only use it for frame-by-frame animation (Flash style).

How to add/get Sprite to/from UIComponent

How to add Sprite to BorderContainer (UIComponent)?
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(10,0);
sprite.graphics.moveTo(40,40);
sprite.graphics.lineTo(60,60);
mybordercontainer.addChild(sprite);
//mybrodercontainer is id of BorderContainer created in mxml
This code doesnt work. I cant see Sprite on my BorderContainer. How can I add Sprites on UIComponents, so I can see them? I tried this and it kinda worked:
var comp:UIComponent = new UIComponent();
comp.addChild(sprite);
myborderconteiner.addElement(comp);
But I dont think, that this is a right way to add Sprites to UIComponents. Is there another method to do that?
Second problem:
When I have few Sprites added to my UIComponent (lines/circles/images or others) how can I receive an object Sprite from that UIComponent, which is containing all Sprites added before to that UIComponent?
I need to create Bitmap from that Sprite and do some things.
I hope I make myself clear
Use the SpriteVisualElement as container. That should serve nicely as a container or Sprite substitute. You could also draw in the UIComponent itself.

Movieclip stacking in Actionscript

I'm building a game of which the interface is one of the first items to load on screen. Sound button, pause and all the bits -
During the game - all manor of things are dynamically added and removed to the stage. Therefore my interface goes behind my game scene.
How do I ensure the movieclip always stays on top?
Can I override the addChild of my Document Class and every time a new child is added, I restack the interface to the top?
You can use setChildIndex to rearrange objects that are already contained within a MovieClip or Sprite. For example, if you have an object called container, which contains a redBall, blueBall and many other ball objects, you can use the following to make sure redBall is behind everything else:
container.setChildIndex(redBall, 0);
Equally you can make sure that blueBall will be displayed infront of everything else using:
container.setChildIndex(blueBall, container.numChildren-1);
addChildAt will sort you out for adding children straight into their correct position, and setChildIndex will allow you to re-position objects already placed. Hope that helps.
debu
Look into addChildAt, it allows you to specify the index that the new object should be added too.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
A good strategy is to keep all interface elements in one parent Sprite/MovieClip, and all game assets in another. (With the interface one on top)
With your guys suggestion I made this, apparently, if you addChild an object already on the screen, it's simply reindex'd to the top. Does this look ok?
private var topLevelChildrenArray:Array = [];
public function addTopLevelChild(child:DisplayObject):DisplayObject
{
topLevelChildrenArray.push(child)
return this.addChildAt( child, this.numChildren - 1 );
}
override public function addChild(child:DisplayObject):DisplayObject
{
this.addChildAt(child, this.numChildren);
for each(var topChild:DisplayObject in topLevelChildrenArray)
{
super.addChild(topChild);
}
return child
}

Deleting a shape via code

Pretty basic question here, but its still got me a little confused..
I have an object(navigation menu bar) that I want to change the colors on with code, so in an updateColor function, I get the bounds of the object (which is a drawing shape contained in a movieclip) and redraw a new shape on top of it with the new color, but I've noticed that the last shape still exists behind this redraw.
I tried using obj.graphics.clear(); before the redraw but that didn't get rid of the original shape. Is there another command that I'm overlooking?
Unless you drew the object you wish to remove within the same graphics object, clearing won't work. You need to remove the DisplayObject.
Depending on the number of children you can do:
obj.removeChildAt(0);
This also removes movieclips / buttons you placed on the stage manually.
If you have a reference to the DisplayObject you wish to remove you can simply do
obj.removeChild(backgroundClip);
Note that you can also change the color of a DisplayObject directly:
import flash.geom.ColorTransform;
...
public var test:MovieClip; //instance on stage
...
var cf:ColorTransform = test.transform.colorTransform;
cf.color = 0xff0000;
test.transform.colorTransform = cf;
while(this.numChildren)
{
this.removeChildAt(0);
}
Will clear child object on this MovieClip,
if it's clearing too much, then put the shape drawing in a subclip, and clear the subclip.