Actionscript 3.0 Popup - actionscript-3

I'm trying to get a popup message to display for 1 second when the right answer is selected. All this pop up says is "Right Answer". I have made a function that makes the popup visible and I have put setTimeout in an if state (this if statement is if the right answer is selected). My code below and I would appreciate any help at all!
This is my function for the display
//------Popup--------//
right_ans.alpha = 0; //set to zero so message wont be displayed throughout game
//--------Popup function-------//
function DisplayAnswer(event:MouseEvent):void{
right_ans.alpha = 5;
}
This is the if statement with the setTimeout
if(event.target == pig) //object
{
currentQuestion++;
score = score + 5;
Score_txt.text = (score).toString();
setTimeout(DisplayAnswer, 1000);
}

Set alpha to 1, not 5. It accepts values from 0 to 1, being 0% to 100% opacity.

try this :
if(event.target == pig) //object
{
currentQuestion++;
score = score + 5;
Score_txt.text = (score).toString();
setTimeout(DisplayAnswer, 1000);
}
//------Popup--------//
right_ans.alpha = 0; //set to zero so message wont be displayed throughout game
//--------Popup function-------//
function DisplayAnswer():void{
right_ans.alpha = 0.5;
setTimeout(removeAnswer, 1000);
}
function removeAnswer():void{
right_ans.alpha = 0.0;
}

Related

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;
}
}

Blinking Random Number Generator ActionScript3

I need a random number generator on AS3 that blinks on a screen one random number per second (1-9). The random number is fine but I'm having a problem with the blinking part. It just stays permanent on the screen instead of blinking the number.
The dynamic textbox is called myNumbers. I've tried using myNumbers.visible = !myNumbers.visible on the event handler, but it didn't work.
My code:
var mytimer:Timer = new Timer(1000,10);
mytimer.addEventListener(TimerEvent.TIMER, timerHandler);
mytimer.start();
function timerHandler(event:TimerEvent):void{
var numbers:Number = Math.floor(Math.random() * (9 - 1 + 1) + 1);
myNumbers.text = numbers+"";
}
Any help is appreciated!
You can use the same Timer to generate a number (every second) and blinks your text field (every 0.5 second).
Take this code :
var number:int = 0;
var timer:Timer = new Timer(500);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
function timerHandler(event:TimerEvent):void{
if(timer.currentCount % 2 == 0){
text_field.alpha = 0.2; // you can use text_filed.visible = false;
} else {
text_field.alpha = 1; // you can use text_filed.visible = true;
number = Math.floor(Math.random() * 9) + 1;
text_field.text = String(number); // you can also write it : number.toString();
}
}
Which will give you something like this :
Hope that can help.
Hide the myNumbers before start a timer:
myNumbers.visible = false;
In the timerHandler add:
myNumbers.visible = true;
setTimeout(hideText, 500);
Add hideText function:
function hideText()
{
myNumbers.visible = false;
}

Hide button after click two times or more on as3

i am new on as3.
i want to ask how to hide button after click two times or more on as3.
the code below i got from code snippets, but the button hide after one click.
BTNhint.addEventListener(MouseEvent.CLICK, fl_ClickToHide);
function fl_ClickToHide(event:MouseEvent):void
{
BTNhint.visible = false;
}
You have just to count the button clicks and then after two clicks you can hide your button :
var click_counter:int = 0;
BTNhint.addEventListener(MouseEvent.CLICK, fl_ClickToHide);
function fl_ClickToHide(event:MouseEvent):void
{
click_counter ++; // you can write it : click_counter = click_counter + 1;
if(click_counter >= 2){ // you can write it : if(click_counter > 1)
BTNhint.visible = false;
}
}
You can use a constant (LIM) to determine how many times your button must be clicked, compare it to a variable (c) that is counting your clicks, and use your MouseEvent's target property to target your button itself when you want it to disappear:
var c:int = 0;
const LIM:int = 2;
BTNhint.addEventListener(MouseEvent.CLICK, hideMe);
function hideMe(event:MouseEvent):void
{
if(++c >= LIM) event.target.visible = false;
}

how to disable movieclip?

I am using Adobe Flash CS5, Action Script 3.0. I want to disable my movie clip. How to do that?
My code:
var index:Array = ([0,1,2,3]);
var radioGroup1:RadioButtonGroup = new RadioButtonGroup("question1");
rb1.group = radioGroup1;
rb2.group = radioGroup1;
rb3.group = radioGroup1;
rb4.group = radioGroup1;
b1.addEventListener(MouseEvent.CLICK, submitclick,false);
function submitclick(event:MouseEvent):void
{
if (radioGroup1.selectedData == null)
{
b1.mouseEnabled = false;
//ExternalInterface.call("Test","Please selecte one answer");
//return;
} else {
if (radioGroup1.getRadioButtonIndex(radioGroup1.selection) == 2)
{
myscore += 10;
}
}
if (compquest>=maxquest)
{
gotoAndStop(1,"Scene 6");
}
else
{
MovieClip(this.root).gotoAndStop(1, "Scene " + questions[compquest++]);
}
}
I want to disable this b1 movieclip. So anyone could tell me what am I doing wrong?
If, by disable, you mean to make it unclickable and faded like a disabled button. Just reduce the alpha a bit and set its mouseEnabled property to false.
function submitClick(event:MouseEvent){
b1.alpha = .6;
b1.mouseEnabled = false;
}
This way the user will not be able to click it and it appear disabled.
First you could write, because event.target is p1:
function submitclick(event:MouseEvent):void
{
event.target.mouseEnabled = false;
}
On the other hand, the condition you want to evaluate in your if statement is probably false:
radioGroup1.selectedData == null
Therefore the associated code isn't executed:
b1.mouseEnabled = false;
You should test in your function and before your if statement:
trace(radioGroup1.selectedData == null);

How can I get rid of non-null hitTestObject error with already instantiated objects?

I am a beginner/intermediate AS3 "programmer" trying to complete a skeeball-like flash-based game for a university assessment, and I'm doing myself serious mental damage trying to get even basic object (ball) collisions working with scoring targets on my stage. I'm using a power bar type variable to determine the force of the ball roll which is translated into a tween to create a smooth movement up my "lane" and into the scoring area (this is overhead perspective). The targets are instances of movie clips inside a larger movie clip that is made up of all the components of the game table. Even though my game table and scoring components have already been instantiated when I release the ball, I am getting the typical non-null errors:
ballSpeed is 552
targetArray value is [object upperScoringAreaCTarget_mc]
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at SkeeBlast_7_fla::MainTimeline/ballTargetScore()
at SkeeBlast_7_fla::MainTimeline/rollBall()
at SkeeBlast_7_fla::MainTimeline/releaseBall()
Here is my ball release function:
function releaseBall(event:MouseEvent):void
{
rollBall();
gameElements.removeEventListener(MouseEvent.MOUSE_MOVE, moveBall);
}
function rollBall():void
{
ballSpeed = rollPower * 12;
trace("ballSpeed is " + ballSpeed);
ballFriction();
ballGravity();
//ball.y -= ballSpeed;
//var myBallTween:Tween = new Tween(ball,"y",Strong.easeOut,ball.y,ball.y - ballSpeed,3,true);
myBallTween = new Tween(ball,"y",Strong.easeOut,ball.y,ball.y - ballSpeed,3,true);
myBallTween.start();
ballTargetScore();
}
and my collision detection and scoring function:
//match targets to scoring values which should be tied to determineScore()
function ballTargetScore():void
{
var targetValue:String;
var targetArray:Array = new Array(gameTable.upperScoringArea.upperScoringAreaCTarget,
gameTable.upperScoringArea.upperScoringAreaLtTarget,
gameTable.upperScoringArea.upperScoringAreaRtTarget,
gameTable.middleScoringArea.middleScoringAreaTargetTop,
gameTable.middleScoringArea.middleScoringAreaTargetMiddle,
gameTable.middleScoringArea.middleScoringAreaTargetLower,
gameTable.lowerScoringArea.lowerScoringAreaTarget);
if (ball.hitTestObject(gameTable.tableDisplay))
{
myBallTween.stop();
}
else
{
for (var i:uint; i < targetArray.length; i++)
{
if (targetArray[i] != null)
{
trace("targetArray value is " + targetArray[i]);
if (ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaCTarget))
{
targetValue = gameTable.upperScoringArea.upperScoringAreaC_text.text;
}
if (ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaLtTarget))
{
targetValue = gameTable.upperScoringArea.upperScoringAreaLt_text.text;
}
if (ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaRtTarget))
{
targetValue = gameTable.upperScoringArea.upperScoringAreaRt_text.text;
}
if (ball.hitTestObject(gameTable.upperScoringArea.middleScoringAreaTargetTop))
{
targetValue = gameTable.middleScoringArea.middleScoringAreaU_text.text;
}
if (ball.hitTestObject(gameTable.upperScoringArea.middleScoringAreaTargetMiddle))
{
targetValue = gameTable.middleScoringArea.middleScoringAreaM_text.text;
}
if (ball.hitTestObject(gameTable.upperScoringArea.middleScoringAreaTargetLower))
{
targetValue = gameTable.middleScoringArea.middleScoringAreaL_text.text;
}
if (ball.hitTestObject(gameTable.upperScoringArea.lowerScoringAreaTarget))
{
targetValue = gameTable.lowerScoringArea.lowerSA_text.text;
}
else
{
trace("no hit");
}
}
}
}
//gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
determineScore(targetValue);
//return targetValue;
}
It's all still a bit messy as I tinker trying to find the right combination.
I need to first get a basic ball<->target or boundary collision working, but ultimately, I'd like to try to figure out how to control the collisions conditionally since many of the targets are aligned vertically like a skeeball table. Will I be able to measure the speed of the ball as it is tweening/rolling? Will I be able to apply gravity correctly so that the ball falls and if it catches one of the arcs beneath the scoring target, it will roll along the arc until it 'falls into the hole'? I think I will have issues with the bounding box of my objects on that one.
Thanks for any help,
Alan
Here's the response to Vesper with a cleaned up function (thanks) and new error.
function ballTargetScore():void
{
var targetValue:String;
var targetArray:Array = new Array(gameTable.upperScoringArea.upperScoringAreaCTarget,
gameTable.upperScoringArea.upperScoringAreaLtTarget,
gameTable.upperScoringArea.upperScoringAreaRtTarget,
gameTable.middleScoringArea.middleScoringAreaTargetTop,
gameTable.middleScoringArea.middleScoringAreaTargetMiddle,
gameTable.middleScoringArea.middleScoringAreaTargetLower,
gameTable.lowerScoringArea.lowerScoringAreaTarget);
var targetTextArray:Array = new Array(gameTable.upperScoringArea.upperScoringAreaC_text.text,
gameTable.upperScoringArea.upperScoringAreaLt_text.text,
gameTable.upperScoringArea.upperScoringAreaRt_text.text,
gameTable.middleScoringArea.middleScoringAreaU_text.text,
gameTable.middleScoringArea.middleScoringAreaM_text.text,
gameTable.middleScoringArea.middleScoringAreaL_text.text,
gameTable.lowerScoringArea.lowerSA_text.text);
for (var i:uint; i < targetArray.length; i++)
{
if (targetArray[i] != null)
{
trace("targetArray value is " + targetArray[i]);
if (ball.hitTestObject(targetArray[i]))
{
targetValue = targetTextArray[i];
trace('targetValue becomes',targetValue);
}
}
}
determineScore(targetValue);
}
and the error:
ballSpeed is 432
targetArray value is [object upperScoringAreaCTarget_mc]
targetArray value is [object upperScoringAreaLtTarget_mc]
targetArray value is [object upperScoringAreaRtTarget_mc]
targetArray value is [object middleScoringAreaTargetTop_mc]
targetArray value is [object middleScoringAreaTargetMiddle_mc]
targetArray value is [object middleScoringAreaTargetLower_mc]
targetArray value is [object lowerScoringAreaTarget_mc]
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at SkeeBlast_7_fla::MainTimeline/determineScore()
at SkeeBlast_7_fla::MainTimeline/ballTargetScore()
at SkeeBlast_7_fla::MainTimeline/rollBall()
at SkeeBlast_7_fla::MainTimeline/releaseBall()
Thanks for the assistance.
The rules, which I'm sure are necessary, are making me turn this into a really long question. :)
Anyway, I sort of figured out the error about the DisplayObject, but the program still isn't working correctly.
I fixed the error by adding my gameElements MC to my removeChild call in the determineScore function, which is below; however, the ball still isn't removed, even with the error gone, and the targetValue and the score never update (or show up in the trace from above).
function determineScore(scoreEvent:String):void
{
if ( scoreEvent == "D-O" || scoreEvent == "2XB" || scoreEvent == "?")
{
if (scoreEvent == "D-O")
{
ballCount += 1;
gameTable.tableDisplay.BR_text.text = ballCount - 1;
gameTable.tableDisplay.BR_text.embedFonts = false;
gameElements.removeChild(ball);
if (ballCount > 0 )
{
initBall();
}
else
{
drawEnd();
}
}
else if (scoreEvent == "2XB")
{
ballCount += 2;
gameTable.tableDisplay.BR_text.text = ballCount - 1;
gameTable.tableDisplay.BR_text.embedFonts = false;
gameElements.removeChild(ball);
if (ballCount > 0 )
{
initBall();
}
else
{
drawEnd();
}
}
else
{
determineScore(allRandomScore(allScoresArray));
}
}
else
{
scoreTotal += Number(scoreEvent);
ballScore = Number(scoreEvent);
gameTable.tableDisplay.Score_text.text = scoreTotal;
gameTable.tableDisplay.Score_text.embedFonts = false;
gameElements.removeChild(ball);
if (ballCount > 0 )
{
initBall();
}
else
{
drawEnd();
}
}
}
Thanks for looking at this. I feel like I'm finally making a little bit of progress.
Ok, continuing along with yet another update.
gameElements is the primary empty MC that I add all the other MC, like the game table and the ball, to so that when I go back to the main menu, I can remove everything at once.
var gameElements:MovieClip = new MovieClip();
var gameTable:MovieClip = new table_mc();
var ball:MovieClip = new blastBall();
and from my drawGame function:
...
stage.addChildAt(gameElements, 1);
gameElements.addChild(gameTable);
initBall();
...
and initBall:
function initBall():void
{
//resize ball
ball.height = 18;
ball.width = 18;
//place ball on table in correct location
ball.x = gameTable.x;
ball.y = gameTable.height - 20;
gameElements.addChild(ball);
//reduce number of remaining balls;
ballCount -= 1;
//hide the mouse and connect its movement to ball
Mouse.hide();
gameElements.addEventListener(MouseEvent.MOUSE_MOVE, moveBall);
}
Hope there's no limit to this entry. :)
Here's the little addition I put in determineScore to pick up the "results" from ballTargetScore (or lack thereof, really):
if (scoreEvent == null)
{
trace("scoreEvent is null");
gameTable.tableDisplay.BR_text.text = ballCount - 1;
gameTable.tableDisplay.BR_text.embedFonts = false;
gameElements.removeChild(ball);
if (ballCount > 0)
{
initBall();
}
else
{
drawEnd();
}
}
(haven't cleaned up anything else yet) Still trying to get that first collision to work. When I started catching the null value, initBall and drawEnd sort of started to work (ok, it still doesn't really do what I want but at least there was a response).
Well, you have an array of your targets, and the error you receive means that some of its elements are null. But, when you iterate through the array, you for some reason check against the entire set of targets, not checking if any of them are null. I don't understand why. Seeing that you need a text variable to be assigned if a hit is detected, I advise you making another array with corresponding indexes that will contain all the texts you want to assign.
var targetTextArray:Array=(gameTable.upperScoringArea.upperScoringAreaC_text.text,
gameTable.upperScoringArea.upperScoringAreaLt_text.text,
gameTable.upperScoringArea.upperScoringAreaRt_text.text,
gameTable.middleScoringArea.middleScoringAreaU_text.text,
gameTable.middleScoringArea.middleScoringAreaM_text.text,
gameTable.middleScoringArea.middleScoringAreaL_text.text,
gameTable.lowerScoringArea.lowerSA_text.text);
Then, when you iterate through targetArray, you no longer need to check what was that target in order to retrieve the correct text. You do:
for (var i:uint; i < targetArray.length; i++)
{
if (targetArray[i] != null)
{
trace("targetArray value is " + targetArray[i]);
if (ball.hitTestObject(targetArray[i])) {
targetValue=targetTextArray[i];
trace('targetValue becomes',targetValue);
}
}
}
Update: Okay, let's clean up your determineScore() function. It looks like you are correctly adding and removing your ball, but it's possible you do something of this twice. Removing the ball twice without adding it back will net you this error. Currently I can't get if gameElements.removeChild(ball); gets called twice within that function.
function determineScore(scoreEvent:String):void
{
var reBall:Boolean=false; // should we make another ball roll, given the score
var reDisplay:Boolean=false; // should we set new text
if ((scoreEvent==null)||(scoreEvent=="")) return; // we haven't scored
if ( scoreEvent == "D-O" || scoreEvent == "2XB" || scoreEvent == "?")
{
if (scoreEvent == "D-O")
{
ballCount += 1;
reBall=true;
reDisplay=true;
}
else if (scoreEvent == "2XB")
{
ballCount += 2;
reBall=true;
reDisplay=true;
}
else
{
determineScore(allRandomScore(allScoresArray));
// hey, what are we doing here? We seemingly receive a "?" as an input,
// and we roll a random value out of a set given elsewhere. Okay
return; // as good measure, because we don't have to do anything more
}
}
else
{ // if we're here, we assume we have a numeric score passed inside, right?
scoreTotal += Number(scoreEvent);
ballScore = Number(scoreEvent);
reBall=true;
reDisplay=true;
}
// Now look, we always have to launch a new ball or display end, and
// we always have to redraw score textfield. But look, you are always calling
// determineScore with some value, while you should do it only if you hit something!
// So I added starting clause of "if null or empty string".
if (reDisplay) {
// we have to update text
gameTable.tableDisplay.BR_text.text = ballCount - 1;
gameTable.tableDisplay.BR_text.embedFonts = false;
}
if (reBall) {
// we have to remove ball and launch another, if we have any left
gameElements.removeChild(ball);
if (ballCount > 0 )
{
initBall();
}
else
{
drawEnd();
}
}
}