Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Get BitmapData inside Sprite

Community Beginner ,
Apr 14, 2017 Apr 14, 2017

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

TOPICS
ActionScript
964
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2017 Apr 14, 2017

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;

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

kglad

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2017 Apr 14, 2017

sure.  post the (hopefully not to extensive) functions.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2017 Apr 14, 2017

what's the width, height of your fly object's? what's your stageWidth,stageHeight?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2017 Apr 14, 2017

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

kglad

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2017 Apr 14, 2017

again, use hittestobject, not a bitmapdata hittest. you don't need a pixel-perfect hittest for that.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 15, 2017 Apr 15, 2017

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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 15, 2017 Apr 15, 2017
LATEST

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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

The Error says:

A Script has executed for longer than the de.... (cant read more, because flash crashes)

at Main/checkCollisions()

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 14, 2017 Apr 14, 2017

kglad

Flies.PNG

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines