Copy link to clipboard
Copied
Hi,
Following Problem:
I want to get the BitmapData from a Child Bitmap of a Sprite. I can get the Bitmap but not the BitmapData. I dont want to save it in an extra variable.
(BitmapData(flySprite.getChildAt(0).bitmapData) // Doesnt Work
(Bitmap(flySprite.getChildAt(0)) // does Work but not with .bitmapData
How can I get the bitmapData without saving in a new Bitmap (that works...)? is there a way to call the BitmapData with "flySprite.flyBitmap.bitmapData"? How do i have to add the Bitmap, that this works?
my favorite solution would be not to use a Sprite at all, but i need the registrationpoint in center and after drawing the bitmap, the registration is in the top-left corner. I tried to chage it with
matrix.identity();
matrix.translate(-(flyBmp.width / 2), -(flyBmp.height / 2 ));
flyBmp.transform.matrix = matrix;
etc. pp.
It changed nothing... does the registration change back in every frame or something?
thanks, Megaloadon
Copy link to clipboard
Copied
what makes you think that child is a bitmap?
if it starts as a bitmap and is added to the stage using the ide, it's probably a shape. use trace(flySprite.getChildAt(0)) to confirm.
if you want it to remain a bitmap, assign it a bitmapdata class and then use actionscript to add it to the display, or add it to the display in the ide.
and registration points only make sense when discussing in the context of a parent. ie, the reg point is relative to the parent (and/or some other antecedent).
if you want to change a displayobjectcontainer's reg point, you can use:
function changeRegPt(dobj:DisplayObjectContainer,x:Number,y:Number){
var r:Rectangle = dobj.getBounds(dobj);
for(var i:uint=0;i<dobj.numChildren;i++){
dobj.getChildAt(i).x -= r.x+x;
dobj.getChildAt(i).y -= r.y+y;
}
dobj.x += r.x+x;
dobj.y += r.y+y;
}
Copy link to clipboard
Copied
Thanks for the Answer! I know its a Bitmap, because I added it to the Sprite and draw it from the BitmapData of a MovieClip. The trace returns [object Bitmap] or sthg.
I also dont want to change the Registrationpoint of the Container. I centered it already when adding the bitmap child.
Im programming a minigame and I found a running solution, but the game runs slow and chrashes after a moment. I dont understand why... I guess my code is inefficient.
would it be okay if I post some functions and let you have a look? I really have no idea why it keeps crashing
thank you for response!
Megaloadon
Copy link to clipboard
Copied
sure. post the (hopefully not to extensive) functions.
Copy link to clipboard
Copied
kglad Thank you very much!
In this part of the game I add fly characters to a random position on stage. they are tweened and animated. I didt want them to overlap, so I had to add a collision test and add a placeholder to the final position (my Bitmap) so the gap doesnt get caught away while tweening.
The hitDetection calculates till it finds a free spot, and i think theres the problem. I loop it as long as i would hit another Object. The less characters are on screen yet, the less propable it is to hit and the less often the loop repeats.
The Game crashes after adding about 15 Characters, I get an error from the checkCollision() function. The screen isnt that filled after 15 characters, so it shouldnt be so hard to calculate another free spot.
//adds fly every 2 seconds, turns them and puts the Bitmap on the final position
function addFlies(event:TimerEvent):void{
var fly:Fly = new Fly();
var flySprite:Sprite;
addChild(fly);
fly.setRandomStart();
flySprite = createSprite(fly);
addChild(flySprite);
addChild(fly);
fly.x = flySprite.x = fly.getStart().x;
fly.y = flySprite.y = fly.getStart().y;
flySprite.width *= scaleDown;
flySprite.height *= scaleDown;
flySprite.visible = true;
fly.addEventListener(MouseEvent.MOUSE_DOWN, deleteFlyContainer(fly.getID())); // adds Fly to Array
do{
fly.setRandomEnd();
flySprite.rotation = fly.turn();
flySprite.x = fly.getEnd().x;
flySprite.y = fly.getEnd().y;
}
while(checkCollision(flySprite));
tweenFlies(fly);
fliesArray.push([fly,flySprite]);
//trace(fly.getID());
}
//Checks Collision of new Character and already added Characters
function checkCollision(flySprite:Sprite):Boolean{
var newFly:Bitmap = (Bitmap(flySprite.getChildAt(0)));
var newPoint:Point = new Point();
var oldFly:Bitmap;
var oldPoint:Point = new Point();
var collision:Boolean = false;
newPoint.x = flySprite.x;
newPoint.y = flySprite.y;
for(var i:int = 0;i < fliesArray.length;i++){
oldPoint.x = fliesArray[1].x;
oldPoint.y = fliesArray[1].y;
oldFly = (Bitmap(fliesArray[1].getChildAt(0)));
if(newFly.bitmapData.hitTest(newPoint,255,oldFly.bitmapData,oldPoint,255))
collision = true;
}
return collision;
}
//creates Sprite/Bitmap of Character
function createSprite(fly:Fly):Sprite{
var bounds:Rectangle = fly.getBounds(this); // gets Bounds of Fly in a Rectangle
var flyBmpData = new BitmapData(bounds.width,bounds.height,true,0)
var flyOffset:Matrix = fly.transform.matrix;
flyOffset.tx = fly.x - bounds.x;
flyOffset.ty = fly.y - bounds.y;
flyBmpData.draw(fly,flyOffset);
var flyBmp = new Bitmap(flyBmpData);
var flySprite:Sprite = new Sprite();
flySprite.addChild(flyBmp);
flyBmp.x -= flyBmp.width/2;
flyBmp.y -= flyBmp.height/2;
return flySprite;
}
//Tweens Characters
function tweenFlies(fly:Fly):void{
TweenLite.to(fly, fly.tweenTime(200),{x:fly.getEnd().x, y:fly.getEnd().y, scaleX: scaleDown, scaleY: scaleDown, ease: Quad.easeOut, onComplete: wait(fly)});
}
Thank You for reading threw this! It was such a struggle for me to make the Collisiontest with bitmapdata possible, that my solution is very inefficient and the rerolling takes too much cpu...
Thanks for every tipp you have!!
Megaloadon
Copy link to clipboard
Copied
what's the width, height of your fly object's? what's your stageWidth,stageHeight?
Copy link to clipboard
Copied
Its 80x74 after scaleDown. the Stage is 800x450. Thats not the problem. Already tried it with the width and height *= 0.1 to see if it runs better, but it doesnt.
i think its because of all the transformations and passing objects etc in the checkCollision... Is there a faster way? I also dont like the Array and Container saving I did. Ive heard the getChildAt() method is also relatively slow.
Copy link to clipboard
Copied
you should try hitTestObject instead of using a shape-based bitmapdata hittest. it's not as accurate, but it's faster and good enough for what your doing with positioning.
also, it's not clear what the range is for the x,y used here:
flySprite.x = fly.getEnd().x;
flySprite.y = fly.getEnd().y;
p.s. that error isn't because of the inefficiency of the bitmapdata hittest. it's because of restrictions on the above x,y positions.
Copy link to clipboard
Copied
the Range is the whole stage. fly.getEnd() returns a random point on the stage. You think its because the function is rerolling too often? there also seems to be a mistake in the hittest, because I tried it with scale *= 2 so there would only fit 5 flies on the stage, but they started to overlap.. -.-
any Idea whats wrong here? I sat so long trying to get a pixel perfect collision and I dont want to give it up yet. Can I somehow make it run solid with my bitmapdata collision? refine the loop and the way i get the bitmapdata etc. ?
Ps: My program with Overlapping can handle 30 flies with only a bit framerate drop. It must be the collisiontest
Copy link to clipboard
Copied
UPDATE!!!
seems like the bitmapData doesnt react to the scaleDown, but the bitmap does. The code always adds about 15 flies, because thats what fits on stage with scaleDown *= 1... how can I fix this?
Copy link to clipboard
Copied
is there a way to draw the Bitmap of my movieclip with registration point in center, so i can easyly reach the bitmapdata and dont have problems with scaling etc. Isnt there a simpler way to get the Bitmapdata than my 1000 transformations way?
thanks for your help
Copy link to clipboard
Copied
again, use hittestobject, not a bitmapdata hittest. you don't need a pixel-perfect hittest for that.
Copy link to clipboard
Copied
It was the scaling... I scaled the Sprite and the Bitmap, but while drawing the BitmapData it was original size. Thats why it always crashed after exact 15 flies no matter how big I scaled them. I simply fixed it by scaling the Fly before drawing the Bitmap. With a scale of 0,2 i can easyly bring 100 flies to stage.
So the whole program runs right now! Can I prevent crashing with a try-catch in that case?
Anyways I still wonder how the transition matrix works. I found some threads on the Internet on changing the registrationpoint of an object without putting it in a sprite or something. they used the transformationmatrix for that, but it didnt work for me.
if i want the bitmap not in a sprite and with registration in cente, how would I do that?
PS: In the old Version for fly 15 the check collision function was called about 50.000 times till it found a free spot, so its no wonder that it chrashed huh?
Copy link to clipboard
Copied
PPS: If I draw my Bitmap with registrationPoint already in center, I only draw a quarter of the movieclip. The part from the center to the bottom-right corner. During drawing the registration is changed with:
var flyOffset:Matrix = fly.transform.matrix;
flyOffset.tx = fly.x - bounds.x;
flyOffset.ty = fly.y - bounds.y;
so I just have to change it back to center after drawing, but it didnt work. How must I do that?
Copy link to clipboard
Copied
The Error says:
A Script has executed for longer than the de.... (cant read more, because flash crashes)
at Main/checkCollisions()
Copy link to clipboard
Copied
EDIT:
I took a screenshot so you know what im talking about. The marked Fly is the Placeholder(bitmap) for the incoming fly on the bottom-left of the screenshot. on the bottom-right, the fly reached the endposition. You can still see the Movieclip beneath... normally theyre turned invisible! The Flies just shouldnt touch/overlapp on stage. Thats all I want
Find more inspiration, events, and resources on the new Adobe Community
Explore Now