Remove sprite from stage in as3 - actionscript-3

I have this code for a message to appear on stage when player finishes drag and drop. I would like this sprite to be removed when a button is clicked for the next frame. Can someone help me with the code?
stage.addEventListener(Event.ENTER_FRAME, EntFrame);
function EntFrame (e:Event):void
{
if (CntP1+CntP2+CntP3+CntP4+CntP5+CntP6+CntP7+CntP8 == 40)
{
var w:int = 400, h:int = 200;
var win:Sprite = new Sprite();
win.name = "Mywin";
addChild(win);
// draw rounded rect with subtle vertical linear gradient fill and blue stroke
win.graphics.lineStyle(4,0x0077ff);
var mat:Matrix = new Matrix();
mat.createGradientBox(w, h, 90 * (Math.PI / 180));
win.graphics.beginGradientFill(GradientType.LINEAR,[0xffffff,0xeeeeee],[1.00,1.00],[0,255],mat);
win.graphics.drawRoundRect(0,0,w,h,15,15);
// show center "YOU WIN!" text
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.defaultTextFormat = new TextFormat("Arial, Verdana",36,0x454545,true);
tf.text = "Κέρδισες!";
tf.selectable = false;
win.addChild(tf);
tf.x = w/2 - tf.width/2;
tf.y = h/2 - tf.height/2;
// add a drop shadow
var dropShadow:DropShadowFilter = new DropShadowFilter(3,45,0,.35,8,8,1,3);
win.filters = [dropShadow];
// center the graphic
win.x = stage.stageWidth/2 - win.width/2;
win.y = stage.stageHeight/2 - win.height/2;
}
}

Your code isn't written well and needs rewriting to ensure reuse or scalability of your project, but here's a quick way out.
make a holder Sprite, something like
var messageHolder:Sprite = new Sprite();
addChild(messageHolder);
add all the messages to that holder in any fashion you like. When you need to erase the contents of that holder, call following method:
function clearHolderContents(holder:DisplayObjectContainer):void
{
if (holder.numChildren < 1)
return; // no need to continue this method if the target is empty
for (var i:int = holder.numChildren - 1; i >= 0; i--)
removeChild(holder.getChildAt(i));
}
This method can clear contents of any DisplayObjectContainer => use it for your messageHolder:
clearHolderContents(messageHolder);
Hope that helps!

Related

Flash: get absolute position of e.currentTarget

Okay, wasn't sure about the title.
But here's what I am trying to achieve:
Basically i am trying to do something like a quiz, where you can drag and drop the answers into a field. And if they are correkt it should snap the answer field position.
It should be something like
if(myobject.hitTestObject(targetField) && isCorrectAnswer()) {
myobject.x = targetField.x;
myobject.y = targetField.y;
}
But it's not really working.
So here is what I have:
/**
* Generating dragable answer fields based on an array.
**/
function generateAnswer():void {
// creating text format
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0x0066FF;
myFormat.size = 24;
myFormat.align = TextFormatAlign.CENTER
// reference array to store all textfields
var referenceArray:Array = new Array();
// iterate through all answers in vocabListItems and generate textfields
var i:int;
for (i = 0; i < vocabListItems.length; i++) {
var answerField:TextField = new TextField();
// Setting text to current answer
answerField.text = vocabListItems[i];
answerField.width = 140;
answerField.height = 40;
answerField.x = 60+ i*150;
answerField.y = 410;
answerField.background = true;
answerField.backgroundColor = 0xffffff;
answerField.setTextFormat(myFormat);
answerField.selectable = false;
answerField.type = TextFieldType.DYNAMIC
// store the textfield in a container so drag and drop
// will work
var textContainer:Sprite = new Sprite();
textContainer.addChild(answerField);
addChild(textContainer);
referenceArray.push(textContainer);
}
for each (var item in referenceArray) {
item.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
item.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
}
And then I start my drag
var start_x:Number;
var start_y:Number;
function startDragging(e: MouseEvent):void {
var object = e.currentTarget;
start_x = e.currentTarget.x;
start_y = e.currentTarget.y;
object.startDrag();
}
And my stop dragging
function stopDragging(e:MouseEvent):void {
e.currentTarget.stopDrag();
if (e.currentTarget.hitTestObject(targetField)) {
e.currentTarget.x = targetField.x;
e.currentTarget.y = targetField.y;
} else {
e.currentTarget.x = start_x;
e.currentTarget.y = start_y;
}
}
So the problem however is, that e.currentTarget.x is starting from 0. And not from the absolute position on the screen. Its always a relative value, so if i drag it to the targetField its x and y is something like -100, -40
If I set it to the targetField x and y it disappears somewhere in the nirvana of the screen.
targetField is in this case just a rectangle drawn on the stage with a x and y of 160
How can I position it to the absolute x and y?
Here's a screenshot
So the top field is the targetField which is only a rectangle with x 161 and y 191.
The field on the bottom are the dragable fields which are the e.currentTarget. But currentTarget.x is always 0.
EDIT
Your e.currentTarget is going to be the textContainer, which you haven't set an x/y on so it will naturally be 0.
It would seem to make more sense to move the container, and not the actual text field when you create it, like so:
for (i = 0; i < vocabListItems.length; i++) {
var answerField:TextField = new TextField();
// Setting text to current answer
answerField.text = vocabListItems[i];
answerField.width = 140;
answerField.height = 40;
//answerField.x = 60+ i*150; //don't move the text field, move the container later
//answerField.y = 410;
answerField.background = true;
answerField.backgroundColor = 0xffffff;
answerField.setTextFormat(myFormat);
answerField.selectable = false;
answerField.type = TextFieldType.DYNAMIC
// store the textfield in a container so drag and drop
// will work
var textContainer:Sprite = new Sprite();
textContainer.x = 60+ i*150;
textContainer.y = 410;
textContainer.addChild(answerField);
addChild(textContainer);
referenceArray.push(textContainer);
//Also, as an aside, there is no reason to loop through the array after this, just add the listeners here
textContainer.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
textContainer.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
End Edit
To translate the coordinates from one object to another, you can use the localToGlobal and globalToLocal methods of a display object.
Something like this:
var globalPoint:Point = targetField.localToGlobal(new Point());
var destinationLocalPoint:Point = e.currentTarget.parent.globalToLocal(globalPoint);
e.currentTarget.x = destinationLocalPoint.x;
e.currentTarget.y = destinationLocalPoint.y;
What I'm doing here, is first, getting the global coordinates of the targetField. So it's taking a point (at 0,0) relative to targetField and translating that relative to the stage.
Then I'm making a new Point object that takes that global coordnate set, and translate that to the parent of e.currentTarget.

Multiple sprites added in loop, but only last sprite clickable

I have multiple bitmap images added into sprites(each image added into 1 sprite) in a loop, then all the sprites added to 1 _contentHolder(Sprite) then that is added to a viewport.
What the problem is, the multiple sprites that are added inside the loop, everything displays with no problem but only the last sprite added is clickable. None of the sprite added before it is clickable. Wondering what the problem is, they are not overlapping and when i hover the mouse over the top of all the sprites, it turns into the mouse clicker but it just won't click.
Thanks for your time!
My code:
function onImageLoaded(e:Event):void {
loadedArray.push(e.target.content as Bitmap);
for(var i:int = 0; i < loadedArray.length; i++){
var currentY1:int = 200;
var image: Sprite= new Sprite;
e.currentTarget.loader.content.height =200;
e.currentTarget.loader.content.y += currentY1;
image.mouseChildren = true; // ignore children mouseEvents
image.mouseEnabled = true; // enable mouse on the object - normally set to true by default
image.useHandCursor = true; // add hand cursor on mouse over
image.buttonMode = true;
image.addChild(loadedArray[i]);
_contentHolder.addChild(image);
}
newArray.push(image);
var viewport:Viewport = new Viewport();
viewport.y = 0;
viewport.addChild(_contentHolder);
var scroller:TouchScroller = new TouchScroller();
scroller.width = 300;
scroller.height = 265;
scroller.x = 10;
scroller.y = 100;
scroller.viewport = viewport;
addChild(scroller);
image.addEventListener(MouseEvent.CLICK, gotoscene);
}
loadImage();
Edit:
function gotoscene(e: MouseEvent):void{
var index:Number;
index = newArray.indexOf(e.target);
trace(index);
blackBox.graphics.beginFill(0x000000);
blackBox.graphics.drawRect( -1, -1, stage.width, stage.height);
blackBox.alpha = 0.7;
addChild(blackBox);
var originalBitmap : BitmapData = loadedArray[index].bitmapData;
var duplicate:Bitmap = new Bitmap(originalBitmap);
duplicate.width = stage.width;
_contentHolder1.addChild(duplicate);
// Use counter here to only add _contentHolder1 once
//Assuming that `samedata` is a class member (I can't see the rest of your code)
addChild(_contentHolder1);
}
Edit2:
private var image:Array = new Array;
//In the For loop
image[i] = new Sprite();
image[i].addChild(loadedArray[i]);
image[i].addEventListener(MouseEvent.CLICK, gotoscene);
function gotoscene(e:MouseEvent):void{
index = image.indexOf(e.target);
trace(index);
}
You should move image.addEventListener(MouseEvent.CLICK, gotoscene); statement into the loop where you add child sprites. Once you do, the listener will be added to all of the sprites, not just the last one that's currently stored in image variable, and is the only one that responds to your clicks.
for(var i:int = 0; i < loadedArray.length; i++){
var currentY1:int = 200;
var image: Sprite= new Sprite;
e.currentTarget.loader.content.height =200;
e.currentTarget.loader.content.y += currentY1;
image.mouseChildren = true; // ignore children mouseEvents
image.mouseEnabled = true; // enable mouse on the object - normally set to true by default
image.useHandCursor = true; // add hand cursor on mouse over
image.buttonMode = true;
image.addEventListener(MouseEvent.CLICK, gotoscene); // <-- THIS
image.addChild(loadedArray[i]);
_contentHolder.addChild(image);
}
And for all that is holy, learn to indent your code, so that you will be able to visually find the start and end of your loops and see if a certain statement is within the loop or not.
I did work for a few years in AS3 and this was a weird an usual problem. I used to solve it with a function that adds the event to each clip:
function someFunction():void {
for (...) {
var image:Sprite = new Sprite();
addSceneListener(image);
}
}
function addSceneListener(mc:Sprite):void {
mc.addEventListener(MouseEvent.CLICK, gogoscene);
}

as3 getting object coordinates

Hello everyone so i have a piece of code witch creates some circles, and after i move them with another function i want to get their center coordinates so i can draw lines from center to center of circles, but i don`t have any idea how to do it ... if you can suggest me 1 , here is the code witch creates the circle :
function new_sond(event:MouseEvent):void
{
if (i<9)
{
i++;
q=i;
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0x0099FF, 1);
btn.graphics.drawCircle(400, 300, 15);
btn.graphics.endFill();
var s:String = String(q);
btn.name=s;
var textField = new TextField();
textField.mouseEnabled=false;
textField.text = i;
textField.width = 10;
textField.height = 17;
textField.x = 395; // center it horizontally
textField.y = 292; // center it vertically
btn.addChild(textField);
this.addChild(btn);
}
}
the code with is mooving them is :
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownH);
this.addEventListener(MouseEvent.MOUSE_UP, mouseUpH);
function mouseDownH(evt:MouseEvent):void {
var object = evt.target;
object.startDrag();
}
function mouseUpH(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
And the code where i draw the lines between them :
function click1(e:MouseEvent):void{
e.currentTarget.removeEventListener(MouseEvent.CLICK, click1);
var i:int;
i=1;
if (e.target.name!=null){
trace(e.target.name);
sx=mouseX;
sy=mouseY;
stage.addEventListener(MouseEvent.CLICK,click2);
}
}
function click2(e:MouseEvent):void{
e.currentTarget.removeEventListener(MouseEvent.CLICK, click2);
fx=mouseX;
fy=mouseY;
var i:int;
i=2;
trace(e.target.name);
var line:Shape = new Shape();
line.graphics.lineStyle(1,0x0066FF,1);
line.graphics.moveTo(sx,sy);
line.graphics.lineTo(fx,fy);
this.addChild(line);
var inputField:TextField = new TextField();
inputField.border = true;
inputField.type = TextFieldType.INPUT;
str=inputField.text;
trace(str);
inputField.width = 23;
inputField.height = 18;
inputField.x = (sx+fx)/2;
inputField.y = (sy+fy)/2;
addChild(inputField);
}
The thing is i want to draw the line from center to center, but i get the mouseX and mouseY coordinates to draw, because i don`t know how to take the center coordinates of an object.... what i get is : http://gyazo.com/6003630d549209ec5e16ccfffe0ee689
But i want the lines to be drawn from center, if someone has any suggestions please help
Sorry for the long post, i just don`t know where i need to put the piece with will center them so i wanted to give the hole code where it can be placed.... I will appreciate very much any idea .
Well, if you drew the circle at 0,0 and moved the btn object .x and .y to 400,300 like this:
btn.graphics.drawCircle(0,0,15);
btn.x = 400;
btn.y = 300;
Then as you drag btn around the screen, btn.x , btn.x (or in the click handler, e.target.x and e.target.y) would always be the center of the circle.
Alternately, if you can't or don't want to do it that way, you can get the bounds of btn (with respect to this coordinate system, since that's where line is being drawn), and since it's a circle, then center of the bounds will be the center of the circle:
var btn:Sprite = e.target;
var bounds:Rectangle = btn.getBounds(this);
var center_x:Number = bounds.x + bounds.width/2;
var center_y:Number = bounds.y + bounds.height/2;

actionscript Blinking tooltip when addChild(textfield);

Here is piece of class which called right after i already drawn some objects in it, problem is when i have sprite.addChild(textfield) included it starting to blink alot.
addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
private function mouseOverHandler(e:MouseEvent):void{
//creating a new tooltip instance
var tooltip:Sprite = new Sprite();
/*//we tell the holder to hold our tooltip
holder = tooltip;
//adding text to the tooltip
//tooltip.myText = "ASS";
//positioning the tooltip on the stage
holder.x = stage.mouseX;
holder.y = stage.mouseY - 15;
//adding the tooltip to the stage*/
textfield.selectable = false;
textformat.align = TextFormatAlign.CENTER;
textformat.size = 12;
textformat.color = 0x000000;
textfield.defaultTextFormat = textformat;
textfield.x = x;
textfield.y = y;
textfield.width = width;
textfield.height = height;
textfield.text = myName;
sprite.graphics.lineStyle(2,0x00BB00);
sprite.graphics.beginFill(0xFFFFFF, 1);
sprite.graphics.drawRect(x, y, width, height);
sprite.graphics.endFill();
sprite.addChild(textfield);
sprite.x = stage.mouseX;
sprite.y = stage.mouseY - 15;
tooltip.addChild(sprite);
//holder.addChild(tooltip);
addChild(sprite)
}
private function mouseOutHandler(e:MouseEvent):void{
//we remove the holder when the cursor is outside our button
removeChild(sprite);
}
//we create this function to move the tooltip everytime the cursor is moved
private function mouseMoveHandler(e:MouseEvent):void{
sprite.x = stage.mouseX;
sprite.y = stage.mouseY - 15;
}
Even i'm not sure about that, this might explain your problem. You can give more information for better solution.
"when you add sprite, it calls mouseOutHandler, cause you add your sprite under your cursor. And you remove the sprite with //removeChild(sprite); and mouseOverHandler calls again. And it goes like that."

ActionScript 3.0 Getting Size/Coordinates From Loader Content

i'm attempting to position a textfield to the bottom left of an image that is added to the display list from the Loader() class. i don't know how to access the width/height information of the image.
var dragSprite:Sprite = new Sprite();
this.addChild(dragSprite);
var imageLoader:Loader = new Loader();
imageLoader.load(new URLRequest("picture.jpg"));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, displayPic, false, 0, true);
function displayPic(evt:Event):void
{
dragSprite.addChild(evt.target.content);
evt.target.removeEventListener(Event.COMPLETE, displayPic);
}
var tf:TextField = new TextField();
tf.text = "Picture Title";
tf.width = 200;
tf.height = 14;
tf.x //same x coordinate of dragSprite
tf.y //same y coordinate of dragSprite, plus picture height, plus gap between picture and text
addChild(tf);
within the displayPic function, i could assign the evt.target.content.height and evt.target.content.width to variables that i could use to position the text field, but i assume there is a more appropriate and direct way?
There is no direct way since you have to wait the image to be loaded to access width, and height.
But you can place you text as soon as the complete is done if it`s fit your design. Store the value into some var so you can reuse it when moving the sprite.
//...
var tf:TextField = new TextField();
tf.text = "Picture Title";
tf.width = 200;
tf.height = 14;
addChild(tf);
var imageLoader:Loader = new Loader();
imageLoader.load(new URLRequest("picture.jpg"));
imageLoader.contentLoaderInfo.addEventListener(
Event.COMPLETE, displayPic, false, 0, true
);
var offsetX:Number=0;
var offsetY:Number=0;
function positionText():void {
tf.x=dragSprite.x + offsetX;
tf.y=dragSprite.y + offsetY;
}
function displayPic(evt:Event):void {
var li:LoaderInfo=evt.target as LoaderInfo;
if (li===null)
return;
li.removeEventListener(Event.COMPLETE, displayPic);
var dob:DisplayObject=li.content;
if (dob!==null) {
dragSprite.addChild(dob);
// set only once the offset depending on the loaded image
offsetX = ...//
offsetY = dob.height+gap //...
// position text using the offset setted
// so you can reuse the function when moving your sprite
positionText();
}
}