how do I call a function if the image clicked is equal to its matching word? Actionscript3 - actionscript-3

When my random word appears the user has to memorise it and click the correct corresponding image to it. I'm trying to write the code that runs if the user selects the right image. I have paired my words and images in my array. I'm just unsure as how to go about calling this function.
This is what I've attempted so far, but this isn't working. I'm new to actionscript3 so excuse the lack of knowledge as I am trying to teach myself.
All help greatly appreciated!!

This is one way you can do this:
See code comments
basket.visible = false;
//------ Home Button ------\\
backhome1btn.addEventListener(MouseEvent.CLICK, goback1Click);
function goback1Click(event:MouseEvent):void{
gotoAndStop("homepage");
}
//-------------------
var score:int = 0;
var items:Array = new Array(); //store all food items in array
var wordsToShow:Array = new Array(); //store all words to show in array - this is the array that will keep track of which has been asked (or rather not asked yet)
//to reduce redundant code, call this with each food item (below)
function initFoodItem(item:MovieClip, word:String):void {
item.word = word; //forget the array, just store the word on the image as a dynamic property
item.addEventListener(MouseEvent.CLICK, foodClicked);
items.push(item); //add to array
wordsToShow.push(item); //add to array
item.visible = false;
}
initFoodItem(oc, "Orange Juice");
initFoodItem(sand, "Sandwich");
//...repeat for all other food items
//now randmize the words to show array:
wordsToShow.sort(function(a,b):int {
return(Math.random() > .5) ? 1 : -1;
});
var curAnswer:MovieClip; //a var to store the current correct answer
//this does the next question per se
function displayWord():void {
if(wordsToShow.length < 1){
//they've all been asked
gotoAndPlay("gameoverpage");
return;
}
curAnswer = wordsToShow.pop(); //assigns the last item in the array to the cur asnwer, and pop also removes that item from the array (so it won't get asked again)
randomword.text = curAnswer.word; //assign the text to the word value of this item
randomword.visible = true;
remember.visible = true;
}
remember.addEventListener(MouseEvent.CLICK, readyClick);
//when you click your ready button
function readyClick(e:MouseEvent):void {
//we have an array of all items, let's loop through it and change them all to be visible
for (var i:int = 0; i < items.length; i++) {
//items[i].alpha = 1; //alpha values are 0 - 1 in AS3
items[i].visible = true; //use visible instead of alpha if just toggling visibility, it's more efficient
}
randomword.visible = false;
remember.visible = false;
bask.visible = true;
notepape.visible = false;
//! another reason to use visible instead of alpha = 0, is alpha = 0 items will still be clickable! visible = false items cannot be clicked.
}
function foodClicked(e:MouseEvent):void {
if (e.currentTarget == curAnswer) {
//if the current target (the item clicked) is the same item as what we stored in curAnswer, you answered correctly, so do this:
score += 10; //or however much you get for answering correctly
gotoAndStop("listpage"); //not sure what this does?
displayWord();
}else {
//wrong
gotoAndStop("gameoverpage");
}
}

Related

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 would i make the buttons pressed in my calculator show up in my dynamic text box

I am making a calculator with a dynamic text box, buttons from 0-9, and +,-,/,*,=, and clear button. but for some reason everytime I press the buttons on my calculator, they don't show up in my dynamic text box like I need them to. My problem specifically is how do I make it that when the number buttons on my calculator are pressed, the numbers show up in my dynamic text box, like a proper calculator. I would really appreciate your help.
Here is my code:
import flash.events.MouseEvent;
var numbers:Array= [btnNum0,btnNum1,btnNum2,btnNum3,btnNum4,btnNum5,btnNum6,btnNum7,btnNum8,btnNum9];
var operations:Array = [btnAdd_,btnSubtract_,btnMultiply_,btnDivide_,btnEqual_,btnClear_];
var o:String;
var number1:Number;
var number2:Number;
function addListeners():void
{
for(var i:uint = 0; i < numbers.length; i++){
numbers[i].addEventListener(MouseEvent.CLICK, pressNumber);
}
for(i = 0; i < operations.length; i++){
operations[i].addEventListener(MouseEvent.CLICK, pressOperations);
}
btnClear.addEventListener(MouseEvent.CLICK, clearAll);
btnDot..addEventListener(MouseEvent.CLICK, addDot);
}
function pressNumber(event:MouseEvent): void
{
// find name of button pressed
var instanceName:String = event.target.name;
// get the number pressed fom the instanceName
var getNum = instanceName.charAt(6)
if(output.text == "0"){
output.text = "";
}
output.appendText(getNum);
}
function pressOperations(event:MouseEvent): void
{
var instanceName:String = event.target.name;
var currentOperator:String;
currentOperator = instanceName.slice(3,instanceName.indexOf("_"));
trace(currentOperator)
}
function clearAll(event:MouseEvent): void
{
output.text = "";
number1 = NaN;
number2 = NaN;
}
function addDot(event:MouseEvent): void
{
if(output.text.indexof(".") == -1){
output.appendText(".");
}
output.text = "0";
addListeners();
}
You shouldn't try to store information in the instance name. Use objects stored in arrays for the buttons. This is how you can handle everything like this.
Using objects stored in arrays to handle your buttons, the basic code to make a new button and set its properties (store information about the button in the instance):
var aButtons:Array = new Array();var i: int = 0;
for (i = 0; i < 10; i++) {
var mcButton: McButton = new McButton();
mcButton.iButtonValue = i;
mcButton.sButtonName = "Button Number " + i;
aButtons.push(mcButton);
}
Then you can reference the buttons by
aButtons[i]
aButtons[i].iButtonValue
You have first to set a value to your text field, because appendText() method can't append text to an empty text field (nothing will appear).
At the begining of your code:
output.text = '0';
To use property "name" you must set this property after creating instance. Like this:
var btnNum0:Button = new Button();
butNum0.name = "btnNum0";
If you don't do this "name" property will be empty that looks like your case.
UPDATE:
Helloflash is right in his comment to question. At first time I did not see that but in code more mistakes than I thought.
First of all you need to put off your init code from function addDot() to the begining of the code. At now this code will be never called because you try to add listeners into listener addDot().
output.text = "0";
addListeners();
Also change indexof to indexOf and remove extra dot from statement btnDot..addEventListener(MouseEvent.CLICK, addDot);. And big advice/request: use some formatting rules when you write a code (specially about brackets). Your code will be more clean and readable.

AS3 Getting which movieclip clicked on

So, I made a for loop to get several buttons in my project. It's a questionary, and I need to have a button to quickly select and navigate to any question there. I could do them all manually, but not only would my code be long and confusing, but also there are problems since there isn't always the same number of questions.
So right now I have:
function SetQuestionSquares():void{
for(var i:Number = 1; i <= TestProperties.QuestionLimit;i++){
var QuestionSquare:questionsquare = new questionsquare;
QuestionSquare.buttonMode = true;
QuestionSquare.mouseChildren = false;
QuestionSquare.x = NavLeft.x + (20 * i);
QuestionSquare.y = NavLeft.y;
QuestionSquare.questionsquaretext.text = i.toString();
addChild(QuestionSquare);
QuestionSquare.addEventListener(MouseEvent.CLICK, GoToQuestionNumber);
}
addChild(NavLeft);
addChild(NavRight);
}
function GoToQuestionNumber(e:MouseEvent):void{
WhichQuestion = ???; //I don't know what goes here.
UpdateQuestions();
trace("testing"); //Gets called correctly, so its working.
}
My problem is identifying which square was clicked. I need to have some way to grab the "e" (clicked) event, so I know which button the user clicked on.
You need .target property of the Event object:
WhichQuestion = e.target as questionsquare;
function GoToQuestionNumber(e:MouseEvent):void{
var WhichQuestion:DisplayObject = e.currentTarget as DisplayObject;
UpdateQuestions();
trace("testing");
}

Multiple movieclips all go to the same spot; What am i doing wrong?

So I'm trying to shoot multiple bullets out of my body and it all works except I have an odd problem of just one bullet showing up and updating to set position for the new ones.
I have a move able player thats supposed to shoot and I test this code by moving the player and shooting. Im taking it step by step in creating this.
The result of tracing the bulletContainer counts correctly in that its telling me that movieclips ARE being added to the stage; I Just know it comes down to some kind of logic that im forgetting.
Here's My Code (The Bullet it self is a class)
UPDATE*
Everything in this code works fine except for I stated earlier some code seems reduntned because I've resorted to a different approaches.
BulletGod Class:
public class bulletGod extends MovieClip{
//Register Variables
//~Global
var globalPath = "http://127.0.0.1/fleshvirusv3/serverside/"
//~MovieCLips
var newBullet:bulletClass = new bulletClass();
//~Boolean
var loadingBulletInProgress:Number = 0;
var shootingWeapon:Number = 0;
//~Timers
var fireBulletsInterval = setInterval(fireBullets, 1);
var bulletFireEvent;
//~Arrays
var bulletArray:Array = new Array();
var bulletType:Array = new Array();
var bulletContainer:Array = new Array();
//~Networking
var netBulletRequest:URLRequest = new URLRequest(globalPath+"bullets.php");
var netBulletVariables:URLVariables = new URLVariables();
var netBulletLoader:URLLoader = new URLLoader();
//~Bullet Image Loader
var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest();
public function bulletGod() {
//Load every bullet for every gun
//Compile data to be requested
netBulletVariables.act = "loadBullets"
netBulletRequest.method = URLRequestMethod.POST
netBulletRequest.data = netBulletVariables;
netBulletLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
netBulletLoader.addEventListener(Event.COMPLETE, getBulletImages);
netBulletLoader.load(netBulletRequest);
}
private function getBulletImages(bulletImageData:Event){
//Request every bullet URL image
//Set vars
var bulletData = bulletImageData.target.data;
//Load images
for(var i:Number = 0; i < bulletData.numBullets; i++){
bulletArray.push(bulletData["id"+i.toString()]);
bulletType.push(bulletData["bullet"+i.toString()]);
//trace(bulletData["id"+i]+"-"+bulletData["bullet"+i]);
}
//All the arrays have been set start firing the image loader/replacer
var imageLoaderInterval = setInterval(imageReplacer, 10);
}
private function imageReplacer(){
//Check to see which image needs replacing
if(!loadingBulletInProgress){
//Begin loading the next image
//Search for the next "String" in the bulletType:Array, and replace it with an image
for(var i:Number = 0; i < bulletType.length; i++){
if(getQualifiedClassName(bulletType[i]) == "String"){
//Load this image
mRequest = new URLRequest(globalPath+"ammo/"+bulletType[i]);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadImage);
mLoader.load(mRequest);
//Stop imageReplacer() while we load image
loadingBulletInProgress = 1;
//Stop this for() loop while we load image
i = 999;
}
}
}
}
private function loadImage(BlackHole:Event){
//Image has loaded; find which array slot it needs to go into
for(var i:Number = 0; i <= bulletType.length; i++){
if(getQualifiedClassName(bulletType[i]) == "String"){
//We found which array type it belongs to; now replace the text/url location with the actual image data
var tmpNewBullet:MovieClip = new MovieClip;
tmpNewBullet.addChild(mLoader);
//Add image to array
bulletType[i] = tmpNewBullet;
//Restart loadingBullets if there are more left
loadingBulletInProgress = 0;
//Stop for() loop
i = 999;
}
}
}
//###############################################################################################################################################
private function fireBullets(){
//If player is holding down mouse; Fire weapon at rate of fire.
if(shootingWeapon >= 1){
if(bulletFireEvent == null){
//Start shooting bullets
bulletFireEvent = setInterval(allowShooting, 500);
}
}
if(shootingWeapon == 0){
//The user is not shooting so stop all bullets from firing
if(bulletFireEvent != null){
//Strop firing bullets
clearInterval(bulletFireEvent);
bulletFireEvent = null
}
}
}
private function allowShooting(){
//This function actually adds the bullets on screen
//Search for correct bullet/ammo image to attach
var bulletId:Number = 0;
for(var i:Number = 0; i < bulletArray.length; i++){
if(bulletArray[i] == shootingWeapon){
//Bullet found
bulletId = i;
//End For() loop
i = 999;
}
}
//Create new bullet
//Create Tmp Bullet
var tmpBulletId:MovieClip = new MovieClip
tmpBulletId.addChild(newBullet);
tmpBulletId.addChild(bulletType[bulletId]);
//Add To Stage
addChild(tmpBulletId)
bulletContainer.push(tmpBulletId); //Add to array of bullets
//Orientate this bullet from players body
var bulletTmpId:Number = bulletContainer.length
bulletTmpId--;
bulletContainer[bulletTmpId].x = Object(root).localSurvivor.x
bulletContainer[bulletTmpId].y = Object(root).localSurvivor.y
//addChild(bulletContainer[bulletTmpId]);
}
//_______________EXTERNAL EVENTS_______________________
public function fireBullet(weaponId:Number){
shootingWeapon = weaponId;
}
public function stopFireBullets(){
shootingWeapon = 0;
}
}
}
BulletClass:
package com{
import flash.display.*
import flash.utils.*
import flash.net.*
import flash.events.*
public class bulletClass extends MovieClip {
public var damage:Number = 0;
public function bulletClass() {
//SOME MOVEMENT CODE HERE
}
public function addAvatar(Obj:MovieClip){
this.addChild(Obj);
}
}
}
Well ... if I may say so, this code looks quite wrong. Either something is missing from the code or this code will never make the bullets fly.
First off, you can set x and y of the new bullet directly (replace everything after "orientate this bullet from players body" with this):
tmpBulletId.x = Object(root).localSurvivor.x;
tmpBulletId.y = Object(root).localSurvivor.y;
Perhaps this already helps, but your code there should already do the same.
But to let these bullets fly into any direction, you also need to add an event listener, like so:
tmpBulletId.addEventListener(Event.ENTER_FRAME, moveBullet);
function moveBullet(e:Event) {
var movedBullet:MovieClip = MovieClip(e.currentTarget);
if (movedBullet.x < 0 || movedBullet.x > movedBullet.stage.width ||
movedBullet.y < 0 || movedBullet.y > movedBullet.stage.height) {
// remove move listener, because the bullet moved out of stage
movedBullet.removeEventListener(Event.ENTER_FRAME);
}
// remove the comment (the //) from the line that you need
MovieClip(e.currentTarget).x += 1; // move right
// MovieClip(e.currentTarget).y -= 1; // move up
// MovieClip(e.currentTarget).x -= 1; // move left
// MovieClip(e.currentTarget).y += 1; // move down
}
This example lets your bullet fly to the right. If you need it flying into another direction, just comment out the line with the "move right" comment and uncomment one of the other lines.
This is of course a very simple example, but it should get you started.
I hope this helps, and that my answer is not the wrong answer to the question.
As far as I have expirienced it you can have only one copy of MovieClip object added to specific child. Best approach is to use ByteArray for the clip source and instantiate new MovieClip and pass the ByteArray as a source. It have something to do with child/parent relation since a DisplayObject can have only one parent (and a way to detach the object from scene too).
Well i ended up writeing the whole code from scratch for a 3rd time and ran into a similar problem and just for reference to anybody else that comes to a problem thats random as this one i found that problem was likly does to a conversion error somewhere that doesn't necessarily break any compiling rules. Just that i was calling a movieclip and not the class it self.

Dynamic text within one UILoader in ActionScript-3

I want to show some dynamic text and that is read from a php file within xml. Here in swf player i just set three button. Two button for text and one button for images. This all are working fine but the swf background covered by the white background. Here is the normal view and some of this code snippet
normal view image http://outshinebd.com/sm/Flash/normal_view.png http://outshinebd.com/sm/Flash/normal_view.png
Code :
btnItem.addEventListener(MouseEvent.CLICK, showItem);
//btnItem.addEventListener(Event:event, showItem);
function showItem(event:Event):void
{
imgLoader.alpha =0;
textLoader.alpha=0;
imgLoader3.alpha=0;
imgLoader4.alpha=0;
imgLoader5.alpha=0;
imgLoader2.alpha=0;
var itemLoader:URLLoader = new URLLoader();
itemLoader.load(new URLRequest("http://localhost/sm/flash/productdata"));
itemLoader.addEventListener(Event.COMPLETE , onItemLoad);
function onItemLoad(e:Event):void
{
var myLoader:XML = new XML(e.target.data);
xmlList = myLoader.children();
//this values array will hold all of the values we need to paginate
var values:Array = new Array();
//defining the 'i' variable so we can use it multiple times in for loops
var i:int;
for(i = 0; i < xmlList.length(); i++){
//textLoader.text = xmlList[i].elements("productname");
values[i] = xmlList[i].elements("productname");
}
//the current page we're on
var page:int = 1;
//the limit of values we need per page
var limit:int = 1;
//the current row that we're working on
var row:int = 0;
//The total pages that we have
var totalPages:int = Math.ceil(values.length/limit);
function createValues():void{
//this will always limit the amount to the limit variable
//but, "i" will act as a marker for which part of the values
//array that we're going to use
for(i=(page-1)*limit;i<page*limit;i++){
//checks if there actually is a value where "i" is
//otherwise we'll get some undefined movieclips
if(i < values.length){
var newValue:UILoader = new UILoader();
//sets the coordinates based on the row
newValue.x = 5;
newValue.y = 5+newValue.height*row;
//sets this guys value to the correct part of the array
textLoader.text = values[i];
//changing this guys name so we can reference it later
newValue.name = 'value'+row;
//adds the mc to stage
addChild(newValue);
//move onto the next row
row ++;
}
}
//then we reset the rows so we can use the variable again
row=0;
}
//function to remove the mc's
function removeValues():void{
//this loop will run once for each mc on stage
for(i=0;i<limit;i++){
//get the object in the current row and kill it!
removeChild(getChildByName('value'+i));
}
}
//next page and previous page functions
function prevPage(event:MouseEvent):void{
//checking if the current page isn't too low
if(page > 1){
//take away all of the objects so we can make new ones
removeValues();
page --;
createValues();
//then update the page text
//updateString();
}
}
function nextPage(event:MouseEvent):void{
//checking if the current page isn't too high
if(page < totalPages){
removeValues();
page ++;
createValues();
//updateString();
}
}
//then we place the movieclips onto the stage
createValues();
//adding listeners to the buttons
btnPrev.addEventListener(MouseEvent.CLICK, prevPage);
btnNext.addEventListener(MouseEvent.CLICK, nextPage);
}
}
And the view after clicking the button
after clicking image http://outshinebd.com/sm/Flash/after_click.png http://outshinebd.com/sm/Flash/after_click.png
I'm stacked with in the last two days. Please give me a solution.
It seems that you are using an input TextField or a TextTield with a border and a background, just turn them off:
textLoader.border=textLoader.background=false;