Add new instance of movieClip_A to position of movieClip_B - actionscript-3

I am creating a farm game and I am trying to drag an object (red spot) over the ground. When the object rolls over a soil square it highlights a different color. I am trying to drop the object onto the colored soil and have it plant some corn. My cornCrop movieClip is supposed to appear in the middle of the highlighted soil. I posted some code and a screenshot. In the code snippet i have some hard-coded x,y coordinates for the corn stalk to appear. How do I get the corn stalk to dynamically appear in the center of the highlighted soil movieClip? Plus, I can see that I should probably use some sort of array for the corn because I don't know how many times a user will want to plant them. I am not sure how to do that either.
ScreenShot URL: http://sdrv.ms/193vyIm
if (bucketCorn.hitTestObject(Grid.Cell_3_1))
{
var gridID = Grid.Cell_3_1;
//addCrop();
//myColorTransform.color = 0x00FF33;
//Grid.Cell_3_1.transform.colorTransform = myColorTransform;
trace("Yogi Bear!");
var cropCorn1 = new CropCorn();
cropCorn1.x = 50;
cropCorn1.y = 400;
addChild(cropCorn1);
}
if (bucketCorn.hitTestObject(Grid.Cell_3_2))
{
//addCrop();
//myColorTransform.color = 0x00FF33;
//Grid.Cell_3_2.transform.colorTransform = myColorTransform;
var cropCorn3 = new CropCorn();
Grid.Cell_3_2.addChild(cropCorn3);
}
Thanks,
Alex

For the x,y coordinates
cropCorn1.x = bucketCorn.x;
cropCorn1.y = bucketCorn.y;
or
cropCorn1.x = bucketCorn.x + Grid.Cell_3_1.width / 2;
cropCorn1.y = bucketCorn.y + Grid.Cell_3_1.height / 2;
for the array of corn
var cornArray:Array = new Array();
for (var i:int = 0;i<100;i++){
cornArray.push(CropCorn());
}
then just use each positon of array starting at 0. so
cornArray[0].x = bucketCorn.x;
cornArray[0].y = bucketCorn.y;
and on your next event
cornArray[1].x = bucketCorn.x;
cornArray[1].y = bucketCorn.y;

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 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.

If two sprites are visible, do something (AS3)

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.

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.