MovieClip not responding to a function - actionscript-3

I have a complicated problem that I don't know where it comes from.
I have three movie clip in my first frame that each one call "homework" function.
Problem:
There is something wrong with the third one that if you click on it first it works correctly, but if you click on the other objects and then come back and try third one it doesn't work anymore.
I don't have this problem with the others MovieClip objects so how is this problem possible for third MC using the exact same function?
Here is the homeWork function:
function homeWork(a :int) :void
{
gotoAndStop(2);
cubeContainer.addChild(movieClip);
movieClip.x= 20;
movieClip.y= 20;
var j:int =0;
for( var i = a; i < (a+10); i++)
{
cubeContainer.addChild(photos[i]);
photos[i].width = 130;
photos[i].height = 130;
photos[i].x = j-80;
photos[i].y = stage.height-photos[i].height;
j += 90;
photos[i].doubleClickEnabled=true;
photos[i].addEventListener(MouseEvent.DOUBLE_CLICK ,covering);
dragAndDrop(photos[i]);
}
}

Related

remove life from stage after mouseclick as3 code is not working

i have added 5 life icons on a container in stage..now i want to remove them one by one by mouse click.it is working for first click(one child is removing from stage).but it is not working after that.what should i do.there is no error in code but not working.here is the code
var Lives:Number = 5;
var Spacing:Number = 5;
var nextX:Number = 0;
for(var i:int = 0; i < Lives; i++ )
{
var mc:MovieClip = new mcPlayerLives();
mc.x = nextX;
lives_container.addChild(mc );
nextX += mc.width + Spacing;
}
attackButton.addEventListener(MouseEvent.CLICK, removeLife);
function removeLife(event:MouseEvent):void
{
// Lives= Lives - 1;
if (lives_container.contains(mc))
lives_container.removeChild(mc);
}
You've defined the variable mc in the loop. When loop end, mc point to the last instance of the mcPlayerLives class. In the removeLife function you remove only last instance of the mcPlayerLives class.
Instead of
if (lives_container.contains(mc))
lives_container.removeChild(mc);
use
if (lives_container.numChildren)
lives_container.removeChildAt(0);
It means: if lives_container contains at least one child, remove the child.

AS3 Add Child at the position of another Child

Hey I have got some cavemen that when they build huts I want the huts to be added at the coords of the caveman I last clicked on which requires the ability to know exactly what caveman the user clicked on/tapped. Here is the code for spawning in the cavemen:
//////////////////////
///Starting Cavemen///
//////////////////////
var cavemanVar:Array = new Array(50);
for (var i:Number = 0; i < 50; i++)
{
cavemanVar[i] = 0;
}
var foo:MovieClip = new btn_caveman();
cavemanVar[0] = addChildAt(foo, 7);
var bar:MovieClip = new btn_caveman();
cavemanVar[1] = addChildAt(bar, 7);
cavemanVar[0].x = 335.50;
cavemanVar[0].y = 316.55;
cavemanVar[1].x = 335.50;
cavemanVar[1].y = 369.5;
stage.addEventListener(Event.ENTER_FRAME, example2);
function example2 (evt:Event) {
for (i = 0; i < 50; i++)
{
if (cavemanVar[i] != 0)
{
cavemanVar[i].addEventListener(TouchEvent.TOUCH_TAP, btn_cavemanMenu3);
}
}
}
function option1CavemenSpawn():void {
trace("using option 1")
actions += 1;
score += 5;
remaningActions += 1;
updateTextBox();
var foo6:MovieClip = new btn_caveman();
cavemanVar[2] = addChildAt(foo6, 7);
cavemanVar[2].x = 352.10;
cavemanVar[2].y = 260.80 + Math.random() * (392.40 - 260.80);
}
Any help would be great, I have tried using 'cavemanVar', 'cavemanVar[2]', 'cavemanVar[i]' and nothing is what I want it to be.
Hope I explained it properly it's a tricky thing to explain. I also have a move caveman feature I want to implement which would select the last clicked/tapped caveman and move it where the user clicks/taps so can any of this be done and if so how?
EDIT:
function btn_cavemanMenu3(event:TouchEvent):void {
btn_cavemanM.gotoAndStop(2);
trace('2');
allowBuildHut();
cancelTapCaveman();
allowTapCavemanClose();
if (remaningActions <= 2 || stone <= 29) {
cancelBuildHut();
}
}
Do you mean something like,
cavemanVar[i].addEventListener(TouchEvent.TOUCH_TAP, onTap);
function onTap(e:TouchEvent):void {
var caveman:btn_caveman = e.currentTarget as btn_caveman;
trace("caveman tapped --- (" + caveman.x + ", " + caveman.y + ")");
}
Okay, some things I noticed right away:
Attaching eventListeners with each frame, again and again. This will make your game slow if you make your game bigger. I'm not sure, but I think multiple event listeners with the same arguments don't stack, so it's not THAT bad.
Missing a return type for example2.
But aside from that, I think the reason that what you're trying to do doesn't work is because you're not referencing the selected caveman in your btn_cavemanMenu3 function. Via event.currentTarget you can reference the tapped caveman.
Currently, your question name and your question description conflict. What exactly do you wish to achieve? What is working and what isn't working right now?

Arranging items in an inventory

I'm working on an inventory system I made following a short tutorial that leaves you stranded. I've managed to get the items removed and rearrange to the correct order somewhat. For some reason though, if I click on the last item in my inventory, then on the first item, the items do not rearrange correctly.
public class Inventory {
var itemsInInventory:Array;
var inventorySprite:Sprite;
var itemNum:int;
public function Inventory(parentMC:MovieClip) {
itemNum=0;
itemsInInventory = new Array();
inventorySprite = new Sprite();
inventorySprite.x = 50;
inventorySprite.y = 360;
parentMC.addChild(inventorySprite);
}
public function makeInventoryItems(arrayOfItems:Array){
for(var i:int = 0; i < arrayOfItems.length; i++){
arrayOfItems[i].addEventListener(MouseEvent.CLICK, getItem);
arrayOfItems[i].buttonMode = true;
}
}
public function getItem(e:MouseEvent){
var item:MovieClip = MovieClip(e.currentTarget);
itemsInInventory.push(item);
inventorySprite.addChild(item);
item.x = (itemsInInventory.length-1)*40;
item.y = 0;
item.removeEventListener(MouseEvent.CLICK, getItem);
item.addEventListener(MouseEvent.CLICK, useItem);
}
public function useItem(e:MouseEvent){
var item:MovieClip = MovieClip(e.currentTarget);
itemNum = item.x;
inventorySprite.removeChild(item);
itemsInInventory.splice(item, 1);
sortInventory();
}
public function sortInventory(){
for(var i:int = 0; i < itemsInInventory.length; i++){
if(itemsInInventory[i].x > itemNum){
itemsInInventory[i].x -= 40;
}
}
itemNum=0;
}
}
I belive thats all the coding info I need to provide for help solving this mystery.
Also, a link to the game for testing. If you would like a link for a download of the game, please ask.
LINK
Instead of substracting 40px, just set their position again:
for(var i:int = 0; i < itemsInInventory.length; i++){
itemsInInventory[i].x = i*40;
}
Also, I did not even know that it is possible to give an object reference to the splice function, I would rather use:
itemsInInventory.splice(itemsInInventory.indexOf(item), 1);
And remove the event listener from the item when you delete it from the inventory in the useItem function.
item.removeEventListener(MouseEvent.CLICK, useItem);
EDIT:
With Flash Player 10, Adobe introduced the Vector class which is kind of the same as the Array class, but it can only store one data type. In your case it would be MovieClip or Sprite. The Vector class is singificantly faster and more developer friendly because you can see the help from the IDE when you are typing myVector[i].. I recommend using that instead, although there is nothing wrong with Array. It is just outdated a bit, but is helpful when you want to store more data types.
myVector:Vector.<MovieClip> = new Vector.<MovieClip>();

AS3-Having a mouse click affect object in an array's timeline

I'm going crazy with this. I have a few bears on the stage and have listed them in an array. I want them to change their animation frame when clicked as long as they are not on the "down" animation frame to begin with. Below is the code. The problem occurs below the //check if they get hit line.
//put the bears in an array
var bearsArray: Array = new Array();
for (var i=0; i<numChildren;i++) {
if (getChildAt (i) is bear_mc) {
bearsArray.push(getChildAt(i));
}
}
//move them up and down
addEventListener(Event.ENTER_FRAME,upAndDown);
function upAndDown(event:Event){
if (Math.random() < 0.02){
var randomBear = Math.floor(Math.random() * 9);
bearsArray[randomBear].gotoAndPlay("popup");
}
}
//check if they get hit
for (var j:int = 0; j < bearsArray.length; j++){
bearsArray[j].addEventListener(MouseEvent.CLICK, hitBears);
}
function hitBears(e:MouseEvent){
for (var k: int=0; k<numChildren; k++){
if (bearsArray[k].currentFrame != "down"){
trace("clicked");
bearsArray[k].gotoAndPlay("surprised");
}
}
}
currentFrame returns an integer, not string. If you want to use string, you have to use currentFrameLabel or currentLabel.
EDIT: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/MovieClip.html#currentLabel
If you want to control only one bear, remember that you don't need to cycle through them (actually that would serve no purpose as you would be checking every one of them). The better (and correct) approach would be this:
function hitBears(e:MouseEvent){
var bear:MovieClip = e.currentTarget as MovieClip;
if(bear.currentLabel != "down") { //or currentFrameLabel, depends how your mc is set up
trace("clicked");
bear.gotoAndPlay("surprised");
}
}
I got it working by checking a hittest with the mouse instead of just checking the click. That works for some reason.

How would I code a statement that will choose 5 random frames out of 12 in Flash ActionScript 3?

I'm sure this question has been asked a million times in a million ways, but I would appreciate the help anyway. I am working on a Flash Mastermind clone and have a movie clip with 12 colored "pegs" and a "hole" image. How would I code a statement that will pick five random frames and not just the first five frames? I have the barest idea, but I'm not entirely sure if it's right:
var totalColors:Number = 12;
var maxColors:Number = 5;
var chosenColors:Array:
for(var i:Number = 1; i<totalColors; i++)
{
chosenColors[i] = Math.floor(Math.random()*totalColors)+1
}
Thanks a lot in advance for your help!
Please note that the movieclip has been rearranged since I wrote this; I moved the first frame - the "hole" to another layer.
EDIT: Pan has helped a lot since I first asked this question. To test it I decided to expand on my Bejeweled clone code. I added five more shapes to the original 7. At first I thought the line "newPiece.type = Math.ceil(Math.random() * chosenColors.length);" inside the loop, so I commented the quoted line, which was outside of the j loop and part of the original code, and replaced it with this:
newPiece.type = chosenColors[j];
I am very sorry if this seems elementary to some; I am not the strongest programmer, especially when making games. I am far better at ASP.NET and UI design, but game development has always appealed to me for some weird, possibly insane reason. Anyway, here is part of the method for creating a new jewel. The two for loops are pan's code for choosing seven random frames out of twelve. Unfortunately, the movie still picks the first seven frames from the movie clip.
//i goes through all of the possible colors and adds them to the temp array
for (var i:uint = 1; i <= newPiece.totalFrames; i++)
{
temp.push(i);
}
//j chooses seven colors out of the array of all possibilities
for (var j:int = 0; j < numPieces; j++)
{
//index is the frame that has been chosen randomly
var index:int = int(Math.random() * temp.length);
chosenColors.push(j);
chosenColors[j] = temp[index];
//remove the index
temp.splice(index, 0);
}
newPiece.type = Math.ceil(Math.random() * chosenColors.length);
Again, if I've confused anyone with my bad code to English translation, here is an image of my running game and its Jewel movieclip so you will hopefully see what I mean.
var totalColors:Number = 12;
var maxColors:Number = 5;
var chosenColors:Array = [];
var temp:Array = [];
for(var i:Number = 1; i <= totalColors; i++)
{
temp.push(i);
}
for (var j:int = 0; j < maxColors; j++)
{
var index:int = int(Math.random()*temp.length);
chosenColors[j] = temp[index];
//remove the index
temp.splice(index, 1);
}