Removing child override by another code - actionscript-3

I have a button that automatically adds a child and takes away health once clicked. I also made the button take away 0 if the child = true. However, I have another button that once clicked, it should move to another frame and remove the child. For some reason, it isn't removing the child. Before, I didn't have the button take away 0 if the child = true and the removeChild worked fine. The code is all in a frame named actions on the main timeline.
var createGirlText = new GirlSpeechBoxClass();
if(EnergyNumber <= 0) {
Girl_btn.buttonMode = false;
Girl_btn.mouseEnabled = false;
}
Girl_btn.addEventListener(MouseEvent.CLICK, GirlTalk);
Girl_btn.buttonMode = true;
function GirlTalk(event:MouseEvent){
addChild(createGirlText);
createGirlText.x = 350.95;
createGirlText.y = 488.95;
EnergyNumber -= 10;
if(createGirlText = true){
EnergyNumber -= 0;
}
if(EnergyNumber < 0) {
EnergyNumber = 0;
}
if(EnergyNumber <= 0) {
Girl_btn.buttonMode = false;
Girl_btn.mouseEnabled = false;
}
}
//Action for clicking Main Button
BacktoOutside_btn.addEventListener(MouseEvent.CLICK, gotoMainArea2);
BacktoOutside_btn.buttonMode = true;
function gotoMainArea2(event:MouseEvent){
gotoAndStop("MainArea");
MovieClip(this.root).removeChild(createGirlText);
}

Try createGirlText.parent.removeChild(createGirlText);
It's also worth testing if the parent exists before removing it.

Related

OpenFL - can someone explain __combinedVisible property of flash.display.Bitmap

Im using a Bitmap for a button in OpenFL. What im seeing when I set myBitmap.visible = true is that the bitmap does not become visible.
It seems I need to call myBitmap.__CombinedVisible = true as well for it to be drawn. I can't find any documentation for this property on how to use it properly.
I'm also noticing the first time I switch between 2 bitmaps that the bitmap made visible does not appear right away, but the one made invisible disappears right away. Any time after that it behaves properly and the switch happens instantly.
Could this have something to do with __CombinedVisible?
You can see the bitmap switching code below inside of my button.
private function update() : Void {
if( state == ButtonState.OVER ){
this.over.visible = this.over.__combinedVisible = true;
this.up.visible = this.down.visible = false;
}else if( state == ButtonState.UP ){
this.up.visible = this.up.__combinedVisible = true;
this.down.visible = this.over.visible = false;
} else if( state == ButtonState.DOWN ){
this.down.visible = this.down.__combinedVisible = true;
this.up.visible = this.over.visible = false;
}else if( state == ButtonState.CLICK ) {
this.up.visible = this.up.__combinedVisible = true;
this.over.visible = this.down.visible = false;
this.enabled = false;
dispatchEvent(new Event("CLICK"));
}
}
So after a bunch of testing I'v narrowed it down to this: If I set visible to false prior to assigning the BitmapData this __combinedVisible member seems to need to be used. If I do it right after setting the BitmapData it still needs this.
If I let the bitmap draw for 1 frame then set visible to false. visible = true works after this happens and I can now see the bitmap.
But if it doesn't draw once then visible = true does not show the bitmap.
Can I not create an empty bitmap this way and assign the BitmapData later? It works on the up state as I never set visible = false prior to it being drawn the first time.
Okay so after tons of testing and trying to get this to work it just won't.
There is a bug here where if visible is set to false before drawing the bitmap to the canvas it won't draw it until __combinedVisible is set to true. This always causes a flash when drawing the bitmap for the first time as well, so its not feasible to use.
I went and used alpha instead of visible. This works properly and as expected.
If someone can get this working with visible I will accept that answer.
private function update() : Void {
if( state == ButtonState.OVER ){
this.over.alpha = 1;
this.up.alpha = this.down.alpha = 0;
}else if( state == ButtonState.UP ){
this.up.alpha = 1;
this.down.alpha = this.over.alpha = 0;
} else if( state == ButtonState.DOWN ){
this.down.alpha = 1;
this.up.alpha = this.over.alpha = 0;
}else if( state == ButtonState.CLICK ) {
this.up.alpha = 1;
this.over.alpha = this.down.alpha = 0;
this.enabled = false;
dispatchEvent(new Event("CLICK"));
}
}

Making layers invisible with mouse click

Is it possible to make it so that when you click on a button the first time, a specific layer will become invisible... and then once you click on the button a second time, a different layer would become invisible, and so on? If so could I see an example? Thanks!
What I've tried :
/************************* RESET BUTTON **************************/
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event) : void
{
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
penny.visible = true;
maskee4.visible = true;
card.visible = false;
greencard.visible = true;
}
The idea is, once I hit the reset button once, the layer named card, will disappear. Underneath that a layer will be there, which is titled greencard. Once I hit the reset button a second time I want the greencard to disappear. As you see above, I was just doing (property name).visible = false;. This works for the first card but not any after because they would not appear.
If I understand you correctly, you could try something like this below :
reset_btn.addEventListener(MouseEvent.CLICK, reset);
var clickCount : int = 0; //# start with zero since no clicks yet
card.visible = true;
greencard.visible = true;
function reset(e:Event) : void
{
clickCount += 1; //# adds +1 to current count of clicks
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
penny.visible = maskee4.visible = true; //# if same value (true) you can chain them like this
if ( clickCount == 1) //if now 1 click
{
card.visible = false;
}
if ( clickCount == 2) //if now 2 clicks
{
greencard.visible = false;
}
}

How to check if user clicked on smaller object before larger object?

Hey Everyone so I am currently working on a game and the objective is for the user to click on objects on the stage. But the user has to click on the largest objects first before the user clicks on the smaller objects. I wanted to make it that if the user clicks on a smaller object first and not the larger one then the game will be over. I thought I could go about setting this up with booleans for each object on the stage but my if statements arent cutting it here is how I have it set up:
Here are my objects and booleans I use:
//Add box references
public var box_1:MovieClip;
public var box_2:MovieClip;
public var box_3:MovieClip;
public var box_4:MovieClip;
//Booleans
private var b1:Boolean;
private var b2:Boolean;
private var b3:Boolean;
private var b4:Boolean;
now I set all the Booleans to false and if the user clicks on one of the objects I set the Boolean to true.
Here are my if statements tied to my main ENTER_FRAME Listener:
private function level_1():void
{
if (b1)
{
mainScreen.box_1.gotoAndPlay("B1GONE");
b1 = false;
}else
if (b2)
{
mainScreen.box_2.gotoAndPlay("B2GONE");
b2 = false;
}else
if (b3)
{
mainScreen.box_3.gotoAndPlay("B3GONE");
b3 = false;
}else
if (b2 && !b1)
{
endGameCondition();
}
}
On this statement:
if (b2 && !b1)
{
endGameCondition();
}
I was trying to state that if box_2 is true meaning that its clicked on and box_1 hasnt been clicked on yet which is the larger object then the game is now over due to the user not clicking on the largest object first. I have it setup to where box_1 is the largest object and the others are the next size down.
Can anyone see why this isnt working correctly or if there is a better method in doing this?
**** UPDATE HOW MY MAIN CLASS IS SETUP NOW **************
Where I add all my Movie clips and variables:
public class boxTapEngine extends MovieClip
{
//Screens
private var mainScreen:mcMainScreen;
//Add box references
public var box_1:MovieClip;
public var box_2:MovieClip;
public var box_3:MovieClip;
public var box_4:MovieClip;
private var aBoxesArray:Array;
in my constructor function:
aBoxesArray = [box_1, box_2, box_3, box_4];
//AddMainScreen
mainScreen = new mcMainScreen();
mainScreen.x = (stage.stageWidth / 2);
mainScreen.y = (stage.stageHeight / 2);
stage.addChild(mainScreen);
//Initiate numbers
nLevel = 1;
for each(var box:MovieClip in aBoxesArray)
{
box.addEventListener(MouseEvent.CLICK, boxClick);
}
finally on the boxClick function:
private function boxClick(e:MouseEvent):void
{
var box:MovieClip = e.currentTarget as MovieClip; //get a reference to one that was just clicked
box.mouseEnabled = false; //we'll use this as a flag to know if it's been clicked yet
box.gotoAndPlay("BGONE");
//check to see if previous boxes have been clicked.
//this will iterate through all the boxes in order
for (var i:int = 0; i < aBoxesArray.length; i++)
{
if(aBoxesArray[i] == box) return; //if we've reached the currently clicked box, all is good, no need to keep checking so let's exit this loop and function
if (!aBoxesArray[i].mouseEnabled)
{ //one of the previous boxes hasn't been clicked yet
endGameCondition();
}
}
}
Probably isn't working because your final else if statement won't ever be reached (because you're handling b2 == true earlier on which will then bypass all other else statements). Plus your setting b2 to false when you handle it earlier, so it will always be false by the time it gets your final statement.
You need to move that final else if before you check for the other things. See code comments:
//Do this first, and not as a else if
if (b2 && !b1){
endGameCondition();
return; //no need to check checking things if it's game over
}
//now you can do the rest
if (b1)
{
mainScreen.box_1.gotoAndPlay("B1GONE");
b1 = false;
}else
if (b2)
{
mainScreen.box_2.gotoAndPlay("B2GONE");
b2 = false;
}else
if (b3)
{
mainScreen.box_3.gotoAndPlay("B3GONE");
b3 = false;
}
As an aside, you don't need the enter frame handler, you can just check everything on click. Something like this would work:
var boxes:Array = [box_1,box_2,box_3,box_4]; //make sure this is in order of what needs to be clicked first
//if you wanted to actually sort them dynamically based off total size (regardless of what order you've stuffed them in the array), you could add in something like this, which will order them from biggest to smallest:
boxes.sort(function(a,b){
//compare which item has a greater total area (width * height)
if(a.width * a.height > b.width * b.height) return -1; //A is bigger, so put a before b in the array
if(a.width * a.height < b.width * b.height) return 1; //put b before a in the array
return 0; //return 0 if they are the same
});
for each(var box:MovieClip in boxes){
box.addEventListener(MouseEvent.CLICK, boxClick,false,0,true);
}
function boxClick(e:Event):void {
var box:MovieClip = e.currentTarget as MovieClip; //get a reference to one that was just clicked
box.mouseEnabled = false; //we'll use this as a flag to know if it's been clicked yet
box.gotoAndPlay("BGONE");
//or you could just do this to get rid of the box:
if(box.parent) box.parent.removeChild(box);
//check to see if previous boxes have been clicked.
//this will iterate through all the boxes in order
for(var i:int=0;i<boxes.length;i++){
if(boxes[i] == box) return; //if we've reached the currently clicked box, all is good, no need to keep checking so let's exit this loop and function
if(!boxes[i].mouseEnabled){ //one of the previous boxes hasn't been clicked yet
endGameCondition();
}
}
}
//Store your clips in an array
var myClips:Array = [mc1,mc2,mc3,mc4];
//get the clip sizes and store it to an array.
var sizes:Array = new Array();
for (var i:uint = 0; i < myClips.length; i++) {
sizes.push(myClips[i].width);
}
//apply Numeric array sort.
sizes.sort(Array.NUMERIC);
function onClickAction(e:MouseEvent):void {
//Check wheather the array is empty or not.
if (sizes.length != 0) {
//Check wheather the clicked object bigger or not.
if (e.target.width == sizes[sizes.length - 1]) {
trace("Bigger");
e.target.alpha = .5;
sizes.splice(sizes.length-1,1);
} else {
trace("Smaller");
}
}
}

how can i removeChild?

I have problem with removeChild in XML button menu
im calling button temp from library with Linkage
here is my code where i write it
var genButton:butonProba;
var i:uint = 0;
for each (var page:XML in generacijeXML.gener.generation) {
genButton = new butonTest();
genButton.butonText.text = page.#name;
genButton.source = page.source.toString();
genButton.butonText.autoSize = TextFieldAutoSize.LEFT;
genButton.x = 16 + i*225;
genButton.y = -30;
genButton.buttonMode = true;
genButton.mouseChildren = false;
addChild(genButton);
i++;
}
and everything is normal.....
now when i want to make 1 more button when i click on it i want to remove all xml buttons which i call before
im trying simple like this
close.addEventListener(MouseEvent.CLICK, closed);
function closed(event:Event):void {
genButton.removeChild(0);
}
and this
close.addEventListener(MouseEvent.CLICK, closed);
function closed(event:Event):void {
removeChild(genButton);
}
but dont work
does any1 have idea how can i do that ???
I would add all buttons in one container. Create the container as an instance member and add it to the stage in the constructor or your init method:
public var buttonContainer:Sprite = new Sprite();
addChild(buttonContainer);
In your loop add all the created buttons to this container:
...
genButton.buttonMode = true;
genButton.mouseChildren = false;
buttonContainer.addChild(genButton);
i++;
in you click handler remove all children from the container:
close.addEventListener(MouseEvent.CLICK, closed);
function closed(event:Event):void {
while(buttonContainer.numChildren > 0 )
{
buttonContainer.removeChildAt(0);
}
}
hope that helped

How to make carousel loop back to beginning

I have a 800w movieclip containing 4 panels next to each other, each with 200 width (See picture here). When I click and drag then mouse_out, it detects the direction of the mouse and move the panels by 200 either left or right depending on the direction.
My problem is I want this to loop, so when it gets to the very left panel, it'll continue on to the left, and visa versa when it gets to the very right panel, I should be able to continue with the click and drag motion.
I'm not sure if this is considered a carousel.
Anyhow this is what I have so far. I've made 2 comments "What happens now" toLeftTween() and toRightTween() to indicate where I'm stuck.
import com.greensock.*;
import com.greensock.easing.*;
var selectX:Number = 0;
var mouseX1:int = 0;
var mouseX2:int = 0;
var mcPosX:int = 0;
var contents:MovieClip = all_mc;
var draggable:Boolean = true;
contents.buttonMode = true;
contents.mouseChildren = false;
contents.x = 0;
contents.y = 70;
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
function mouseDownHandler(e:MouseEvent):void {
//select the correct point on mc
selectX = contents.x - mouseX;
//for prediction direction later - mouse point 1
mouseX1 = stage.mouseX;
//trace("1: " + mouseX1);
// move mc with mouse
if (draggable) {
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
} else {
trace("unable to drag");
}
}
function mouseUpHandler(e:MouseEvent):void {
//for prediction direction later - mouse point 2
mouseX2 = stage.mouseX;
//trace("2: " + mouseX2);
//remove mc move with mouse
removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
//check for direction of the mc based on mouseX1 and mouseX2
mouseDirection();
}
function onEnterFrameHandler(e:Event):void {
contents.x = parent.mouseX + selectX;
}
function mouseDirection():void {
if (mouseX1 > mouseX2) {
trace("to the left");
toLeftTween();
} else if (mouseX1 < mouseX2) {
trace("to the right");
toRightTween();
} else {
trace("nothing happened");
}
}
function toLeftTween():void {
if(contents.x<1 && contents.x>199) {
mcPosX = 0;
trace("to left - Panel 1");
} else if(contents.x<-1 && contents.x>-199) {
mcPosX = -200;
trace("to left - Panel 2");
} else if(contents.x<-201 && contents.x>-399) {
mcPosX = -400;
trace("to left - Panel 3");
} else if(contents.x<-401 && contents.x>-599) {
mcPosX = -600;
trace("to left - Panel 4");
} else if(contents.x>-600) {
//What happens now?
}
var toLeftTween:TweenLite = new TweenLite(contents,0.25, {x:mcPosX});
}
function toRightTween():void {
if(contents.x<-601 && contents.x>-799) {
mcPosX = -600;
trace("to right - Panel 4");
} else if(contents.x<-401 && contents.x>-599) {
mcPosX = -400;
trace("to right - Panel 3");
} else if(contents.x<-201 && contents.x>-399) {
mcPosX = -200;
trace("to right - Panel 2");
} else if(contents.x<-1 && contents.x>-199) {
mcPosX = 0;
trace("to right - Panel 1");
} else if(contents.x<-2) {
//What happens now?
}
var toRightTween:TweenLite = new TweenLite(contents,0.25, {x:mcPosX});
}
Good work. The solution is actually quite simple, when you see it.
You need to check the distance between your starting mouse point and your current mouse point, every frame, which it looks like you're doing with selectX and mouseX. Your problem is that when you go past a certain distance, you have no logic to handle your loop.
Because it's a loop, you want to check whether the distance between your starting point and current point is greater than the width of your carousel movieclip, which is 800. If so, you need the logic to loop back on itself. (However, I'm not sure why your toLeftTween and toRightTween functions check that contents.x is in a negative range....I suppose that's because of the registration point on the movieclip?)
(Edit: I see what you did - why you have the negative numbers. You're sliding the movieclip to the left as needed. Now that I'm looking at the way you did this, the modulus won't actually work because you're checking a range between -600 and 200, instead of a range between 0 and 800...)
You'll need something like this.
function toLeftTween():void {
// If contents.x is divisible by the width of the movieclip, it's greater than the mc width.
// We check this here, and grab the remainder.
if (contents.x > 800 || contents.x < -600)
contents.x = contents.x % 800; // Modulus operator. Returns remainder.
if(contents.x<1 && contents.x>199) {
mcPosX = 0;
trace("to left - Panel 1");
} else if(contents.x<-1 && contents.x>-199) {
mcPosX = -200;
trace("to left - Panel 2");
} else if(contents.x<-201 && contents.x>-399) {
mcPosX = -400;
trace("to left - Panel 3");
} else if(contents.x<-401 && contents.x>-599) {
mcPosX = -600;
trace("to left - Panel 4");
} else if(contents.x>-600) { // I think you flipped a sign here... -lunchmeat
//What happens now?
// Due to the modulus, we should never find ourselves in this situation!
}
var toLeftTween:TweenLite = new TweenLite(contents,0.25, {x:mcPosX});
}
That should do the trick, more or less. You'll need to add this to both tween functions. (It might need a little tweaking.) Let me know if you run into any problems. Good luck!
if you want something like
(Note:numbers stands for panels, and index 0 is initial point.)
for index 0
1 - 2 - 3 - 4
for index 1
2 - 3 - 4 - 1
for index -1
4 - 1 - 2 - 3
Seems like you heading wrong way.
First if u need continues loop you have to move movieclips that is out of view to the end. And you need a clone of first element at the end of items for continues look. I would prefer to use bitmapData of content so you wont need a clone of first element and it ll compute faster and the way is easier.