If two sprites are visible, do something (AS3) - actionscript-3

I'm creating a memory like game. I built all the desktop, the cards generation. I now have two cards of each.
I'm trying to do the pairs delete system.
my function to show the color to find looks like this :
private function onClick(e:MouseEvent):void
{
if (vueDos)
{
vueDos = !vueDos;
faceCarte = new Sprite();
faceCarte.graphics.lineStyle(2,0x000000,.5);
faceCarte.graphics.beginFill(clr);
faceCarte.graphics.drawRoundRect(8,8,this.width - 16, this.height - 16, 10,10);
faceCarte.graphics.endFill();
var _t:TextField = new TextField();
_t.selectable = false;
_t.antiAliasType = "advanced";
_t.autoSize = "left";
_t.defaultTextFormat= new TextFormat(maFont.fontName,24,0x000000);
_t.text = couleur;
_t.x = (this.width - _t.width)/2
_t.y = (this.height - _t.height) >> 1;
faceCarte.addChild(_t);
faceCarte.cacheAsBitmap = true;
this.addChild(faceCarte);
}
if(!vueDos)
}
Does it exist a function wich see if the color of the card is visible (faceCarte), and limit the visibles carte to two then removeChild faceCart.
Thank you in advance

You have to make such a function yourself. It'll be better to assign a couleur property to the card itself, instead of putting it into the TextField and forgetting. This way you'll be able to open first card, get that property, then open second card and compare that one's property with what you received, if match, both cards will be removed.

Related

ActionScript 3 Adding images; different positions

In short, I have clickable objects with varying colours. I want these colours upon being clicked to appear in my placeholders (there will be 6). I currently have managed to code so that upon clicking any colour it is placed in the first placeholder.
In what way am I able to code to recognise that the first placeholder has been filled and that once filled, the second placeholder should become the target?
Preferably until the 6th has been filled and then stopped, so that the user can see all 6.
I am thinking something like a for loop would be fitting, but I am not sure how to go about it.
So far it's looking something like this:
//Placeholder
var placeHolder1:MovieClip = new MovieClip();
placeHolder1.x = 20;
placeHolder1.y = 245;
stage.addChild(placeHolder1);
//Placeholder2 (UNUSED CURRENTLY)
var placeHolder2:MovieClip = new MovieClip();
placeHolder2.x = 60;
placeHolder2.y = 245;
stage.addChild(placeHolder2);
//Click and select colours
var newBlue:cBlue = new cBlue();
numBlue.addEventListener(MouseEvent.CLICK, fBlue)
function fBlue(e:MouseEvent){
placeHolder1.addChild(newBlue);
}
var newRed:cRed = new cRed();
numRed.addEventListener(MouseEvent.CLICK, fRed)
function fRed(e:MouseEvent){
placeHolder1.addChild(newRed);
}
First, you probably want to learn about Arrays (or Vectors). Arrays/Vectors are lists, so you would put all your placeholders into an array:
var placeHolders:Array = [placeHolder1, placeHolder2];
Though, since there is a formula to your place holder creation, you probably would want to do this in a loop to make it DRYer (Don't Repeat Yourself)
This loop would create 10 place holders and add them to the array:
var placeholders:Array = new Array();
for(var i:int=0; i < 10; i++){
var placeHolder = new Sprite(); //if your not using timelines, just use Sprite instead of MovieClip as it's less overhead
placeHolder.x = 20 * (i + 1); //i starts at 0, and goes to 9
placeHolder1.y = 245;
stage.addChild(placeHolder); //add it to the display list
placeholders.push(placeHolder); //add it to the array
}
Now (continuing to be DRY), attached the same event listener to all your color buttons:
numBlue.addEventListener(MouseEvent.CLICK, selectColor);
numRed.addEventListener(MouseEvent.CLICK, selectColor);
In that event handler I've called 'selectColor' (see code comments)
function selectColor(e:Event):void {
//get the first element in the array
var placeHolder:Sprite = placeholders.shift(); //shift removes the first item from the array, and returns it
placeHolder.addChild(e.currentTarget); //e.currentTarget refers to item that you attached the event listener to, in this case either numBlue or numRed
}
So to summarize, this gets the first placeholder in the array, remove that item from the array, then adds color button that was clicked as a child of that placeholder.

How to create a button that makes a new text field appear on screen?

I've been having trouble getting this button to work. I want it so that whenever you click it, a new text field pops up that you can type stuff in. This is supposed to be for a trivia-like game, where the user inputs their own questions and answers. Here's the code so far...
This is the text field's properties -
QuestionTextField = new TextField();
QuestionTextField.defaultTextFormat = SmallTextFormat;
QuestionTextField.textColor = 0x660000;
QuestionTextField.x = stage.stageWidth * 0.1;
QuestionTextField.y = 200;
QuestionTextField.width = stage.stageWidth * 0.8;
QuestionTextField.height = 20;
QuestionTextField.selectable = false;
QuestionTextField.type = TextFieldType.INPUT;
QuestionTextField.border = true;
QuestionTextField.multiline = true;
QuestionTextField.wordWrap = true;
And this is the function that is supposed to create a new text field every time the button is clicked-
private function AddQuestionButtonClicked(m:MouseEvent){
for(var i = Questions.length; i>=1; i--){
container_buttonsMC.addChild(QuestionTextField);
Questions.push(QuestionTextField);
QuestionTextField.y += 20
}
}
Notes : "Questions" is an array that holds the number of text fields there are, container_buttonsMC holds all of the buttons on that are on the game's main menu.
The problem is that whenever I click it, it 1. Doesn't actually create a new text field, but instead moves it a certain amount of pixels down, and 2. It sort of duplicates the text field's position...if that makes ANY sense at all. If I click on the button once, it will move the text field down by 20 pixels. If I click on it again, it will move it down by 40 pixels, then by 80, and so on...
I also traced the length of the array, and surprisingly enough, the number that appeared would double every time I clicked it. However, only one text field is visible (apparently). It probably has something to do with the for loop's action, but I don't know for sure. Does anyone have an idea as to what the problem is? (Thanks in advance, I'm still new to AS3 and programming in general)
First, each need to create a new textfield every time you click the button, rather than adding it to the stage. With what you have at the moment, you only created one text field.
Secondly, you only want to do add one more text field, right? So instead of using a loop, which will create multiple new text fields, just create one extra text field and add it to the list.
The code will look something like
private function AddQuestionButtonClicked(m:MouseEvent){
var QuestionTextField:TextField = new TextField()
QuestionTextField.defaultTextFormat = SmallTextFormat;
QuestionTextField.textColor = 0x660000;
QuestionTextField.x = stage.stageWidth * 0.1;
QuestionTextField.y = 200;
QuestionTextField.width = stage.stageWidth * 0.8;
QuestionTextField.height = 20;
QuestionTextField.selectable = false;
QuestionTextField.type = TextFieldType.INPUT;
QuestionTextField.border = true;
QuestionTextField.multiline = true;
QuestionTextField.wordWrap = true;
// You can adjust the 50 here to control the spacing between text fields
QuestionTextField.y += 50 * Questions.length
container_buttonsMC.addChild(QuestionTextField);
Questions.push(QuestionTextField);
}

How to push instantiated MC into Array dynamically?

Im really stuck. I have 5 MC´s that are being spliced from one array at a certain time. In that same function I want to push another movieclips into another array. The two arrays holds mc's that represent right or wrong answers. So when one question is being given a correct answer that questions visualisation alters.
This function holds a incrementing variable as I do want the mc's to be pushed by the user and one at the time. The thing is I cant seem to refer them properly.
I´ve tried
pQuestSum = this[pQuest + pQuestNumber];
and
pQuestSum = this[pQuest] + pQuestNumber;
and pretty much everything I´ve imagined would work...but the problem is I havent tried
the right thing.
when I trace pQuestSum (which would be the reference) I get an error saying thats its not a number.
this is one of 5 mc's named from 1-5:
var passedquest1:PassedQuest = new PassedQuest();
this is the vars that i try to to build a reference of
var pQuest = "passedquest";
var pQuestNumber = 1;
var pQuestSum;
var questCorrArray:Array = [];
if(event.target.hitTestObject(questArray[ix])){
removeChild(questArray[ix]);
questArray.splice(ix,1);
pQuestNumber ++;
pQuestSum = this[pQuest] + pQuestNumber;
trace("pQuestSum"); // NaN
questCorrArray.push(pQuestSum);
//trace(questArray.length);
pointsIncreased = false;
questPoints = 0;
}
How do I refer an existing movieclip when the reference consists of both a string and a number? Hope I made myself somewhat clear:)
If you had an instance of an object on your timeline called "passedquest1" (as an example), then you could access it this way:
var myObj = this["passedquest" + 1];
Or,
var pQuest = "passedquest";
var pQuestNumber = 1;
var myObj = this[pQuest+ pQuestNumber.toString()];
When you do this: pQuestSum = this[pQuest] + pQuestNumber;, you are trying add the number to an object (this[pQuest]), unless you have number/int var called "passedquest", this will result in NaN.

AS3 class instances names

I really wonder. I made a MovieClip class Apple, I wrote a function that creates a new instance with a name "apple". Each time a new instance is pushed into an Array "apples". I call the function 5 times and I get 5 apples. I can manipulate them by calling them i.e. apples[0]. And when I trace my array I see 5 [object Apple] things. So maybe I don't really understand the structure of AS3 objects but shouldn't each object have a name?
When I set apple.name and get an array with 5 different names, I can't manipulate objects by names like apple1.x = 10. How does computer know which apple is where if each has own coordinates? Is the only way to call them: apples[0]-apples[4]? And if I create a code that should be same for all apples, how should I address the function, to "this"? Cause when I write class code I don't have any names yet...
For example, if I want to make Apple class a picture(MovieClip) that can be dragged, create any number of apples, up to a million, I can't possibly add apples[0].addEventListener, apples[1].addEventListener ... apples[1000000].addEventListener to the code. How do I make it global?
I'm asking cause when I'm directly coding for a specific instance, it has a name and I know exactly what am I addressing. And working with a class and making many objects I kinda don't... Sorry, I'm green
You don't need names to be able to access and manipulate your instances.
You can do something like this:
var apples:Array = new Array();
for (var i:int = 0; i < 100; i++)
{
var apple:Apple = new Apple();
apples.push(apple);
apple.x = Math.random() * 500;
apple.y = Math.random() * 500;
addChild(apple);
apple.addEventListener(MouseEvent.CLICK, onAppleClick);
}
function onAppleClick(e:MouseEvent):void
{
var ind:int = apples.indexOf(e.currentTarget);
var apple:Apple = apples[ind];
trace(ind);
apples[ind].visible = false;
//or
//apple.visible = false;
}
The same problem, huh? :)
For example Apple extends Sprite and inherits property name.
It's public, this means that you can change its name.
var apple:Apple = new Apple() ;
apple.name = "MegaApple" ;
Also, if you add the apple to stage, you can get him via name.
stage.addChild(apple) ;
get apple back:
var oldApple:Apple = stage.getChildByName("MegaApple") ;
But that never means, that you can use apple like that:
MegaApple.move() - because name of apple is supposed to be a property of apple, not a name of a variable.
Of course, you can create a lot of apples manually:
var apple1 = new Apple() ;
var apple2 = new Apple() ;
var apple3 = new Apple() ;
But if they all behave the same way, there is no point in doing. That's why you store them into array.
Hope you understand what I mean.

Changing text with AS3 in a for loop - works for first one, others don't

I have a movieclip called Tab that has two text-fields: named toptxt and bottomtxt. When I create new instances of Tab in a for loop and change the text, only the first instance's text is changed. The rest is the default text in the movieclip.
Here is the code I am using:
for(var i = 0; i < 5; i++){
var newTab = new Tab();
newTab.toptxt.text = nameArray[i]; //nameArray is fine
trace(newTab.toptxt.text); //returns expected value, textfield isn't
newTab.bottomtxt.text = jobs[i];
bottom.addChild(newTab); //bottom is a class var.
newTab.x = i * (newTab.width + 3);
}
Even if I change nameArray[i] to "Test", only the first one works.
This problem does not occur if I don't do it in for loops, however I'd like to do it in a for loop.
Here is a screenshot of the problem: http://i.imgur.com/hgPZ5.png
Pull your declaration of var newTab = new Tab(); outside of the for loop, so your code looks like this:
var newTab:Tab;
for(var i:int = 0; i < 5; i++){
newTab = new Tab();
newTab.toptxt.text = nameArray[i]; //nameArray is fine
trace(newTab.toptxt.text); //returns expected value, textfield isn't
newTab.bottomtxt.text = jobs[i];
bottom.addChild(newTab); //bottom is a class var.
newTab.x = i * (newTab.width + 3);
}
Actionscript is becoming confused when you create an instance and assign newTab as a pointer to it, instead of creating a pointer or reference initially, and then creating new instances and adding them to your displayList.
Also, trace your output of nameArray[i] and confirm that those values are correct (i.e. trace(nameArray[i]);. It's possible the data isn't set properly earlier in your code.