How to call function for object I want? - actionscript-3

I didnt know how to exactly ask the question in the title but I can explain it here. So I have this class for pawns in my game.
And in my main program i call a bunch of instances of it with different names.
var z1:ZeleniPijun = new ZeleniPijun();
var z2:ZeleniPijun = new ZeleniPijun();
Basicly I have functions for movement and other variables that I use in my code in the class.
I'm making a multiplayer game and z1 and z2 would be pawns that I move around.
Until now I have used Switch and by knowing the ID of the player and the pawn that was clicked I moved them around the board. That means I have a switch for selecting a player and a switch inside that switch for selecting a pawn. And every time it goes trough the switch it goes to the same code but with a "different name".
For example if I roll a 4 for pawn number 1 it does
z1.movePawn(4);
z1.location += 4;
and other stuff that I need it to do
and if I roll a 3 for pawn number 2 it does
z2.movePawn(4);
z2.location += 4;
and other stuff that I need it to do
I have to copy the same code 16 times and just change the name from z1 to z2 to z3 etc...
Is there anyway I can make a function that would do that for me?
Something like this:
public function doStuff(pawnName:String, number:int):void{
pawnName.movePawn(number);
pawnName.location = number;
and other stuff that I need it to do
}
and then I can just give it the parameters I want 16 times instead of copying the same code everywhere.

send to the doStuff function the object that you want to do changes like
public function doStuff(theObj:ZeleniPijun ):void{
theObj.movePawn(number);
theObj.location = number;
and other stuff that I need it to do
}
if you have many objects, put them in a collection, like an array an iterate on it something like
foreach (obj in collection){
doStuff(obj);
}
this is just more or less pseudo-code, but you get the idea

You can use the object ZeleniPijun as parameter and call the method passing the instance you want.
// example creating multiples objects
var numObjs : uint = 5;
var objectsControl : Vector.<ZeleniPijun> = new Vector.<ZeleniPijun>(numObjs);
var zeleninPijun : ZeleniPijun;
for (var i : int = 0; i < numObjs; i++)
{
zeleninPijun = new ZeleniPijun();
objectsControl[i] = zeleninPijun;
}
// if you want to animate one object
doStuff(objectsControl[0], 4);
// if you want to animate them all
for each (var zeleninPijunObj : ZeleniPijun in objectsControl)
{
doStuff(zeleninPijunObj, 4);
}
function doStuff(pawnObj:ZeleniPijun, location:int):void
{
pawnObj.movePawn(location);
pawnObj.location = location;
}

Related

Actions with a list of instances - AS3

what is the best way to do an action with many instances at the same time?
Lets say I have 50 movieclip instances called A1 to A50, and I want to run an action with only A20 to A35.
For example:
(A20-A35).gotoAndStop(2)
You want an algorithm operation called loop. You are not able to abstractly address things in bunches at once, but you can loop and iterate the bunch one by one which produces basically the same result. Please read this: https://en.wikipedia.org/wiki/Control_flow#Loops When you need to do a quantity of similar operations it is always loop.
With regard to your problem:
// Loop iterator from 20 to 35 inclusive.
for (var i:int = 20; i <= 35; i++)
{
trace("");
// Compose the name of the MovieClip to retrieve.
var aName:String = "A" + i;
trace("Retrieving the MovieClip by name", aName);
// Retrieve the instance by its instance name.
var aChild:DisplayObject = getChildByName(aName);
// Sanity checks about what exactly did you find by that name.
if (aChild == null)
{
// Report the essence of the failure.
trace("Child", aName, "is not found.");
// Nothing to do here anymore, go for the next i.
continue;
}
else if (aChild is MovieClip)
{
// Everything is fine.
}
else
{
// Report the essence of the failure.
trace("Child", aName, "is not a MovieClip");
// Nothing to do here anymore, go for the next i.
continue;
}
// Type-casting: tell the compiler that the child is actually
// a MovieClip because DisplayObject doesn't have gotoAndStop(...)
// method so you will get a compile-time error even if you are
// sure the actual object is a valid MovieClip and definitely has
// the said method. Compile-time errors save us a lot of pain
// we would get from run-rime errors otherwise, so treasure it.
var aClip:MovieClip = aChild as MovieClip;
trace(aClip, "is a MovieClip and has", aClip.totalFrames, "frames.");
if (aClip.totalFrames < 2)
{
// Nothing to do here anymore, go for the next i.
continue;
}
// Now you can work with it.
aClip.gotoAndStop(2);
}
Now that you understand the while idea step by step, if you are sure all of them are present and all of them are MovieClips you can go for a shorter version:
for (var i:int = 20; i <= 35; i++)
{
(getChildByName("A" + i) as MovieClip).gotoAndStop(2);
}
UPD: You can as well address children with square bracket access operator.
for (var i:int = 20; i <= 35; i++)
{
// You can skip type-casting as this["A" + i] returns an untyped reference.
this["A" + i].gotoAndStop(2);
}
Yet there are differences and complications. Method getChildByName(...) always returns a DisplayObject with the given name (or null if none found). Square brackets operator returns an untyped OOP field of the current object.
It will not work with dynamically added children (unless you pass their references to the respective fields).
It will not work if "Automatically Declare Stage Instances" publish option is off.
Finally, this["A" + 1] and A1 are not exactly the same because the latter could refer to a local method variable rather than object member.
I'm not saying that square brackets are evil, they're as fine, yet, as always, programming is not a magick thus understanding what you are doing is the key.

How to Adjust Volume in an Audio loop?

How would someone change sound levels of a music playing in a loop? For example, I'm making a game and at a certain frame I want the music level (music.wav) to be decreased to half of its volume.
How could someone do this in AS3?
You are using the word "loop" in a confusing way. In programming, a loop usually refers to one of the "for" loops that looks like this:
for (var i:int = 0; i < 10; i++)
{
//do stuff 10 times
}
I surmise that this is not what you mean by loop, but rather that you would like a MovieClip or the main timeline to decrease the volume of a Sound object at the end of n frames. Or do you just mean the music itself is looping? Hopefully you see the value of asking well written questions. That being said..
Mind you, I haven't tried this, but according to my reference book (ActionScript 3.0 Cookbook by Lott, Schall & Peters) you need to use a SoundTransform object which specifies the volume at which you want the sound to be set. Try this:
var _sound:Sound = new Sound(music.wav); // creates a Sound object which has no internal volume control
var channel:SoundChannel = _sound.play(); // creates a SoundChannel which has a soundTransform property
var transform:SoundTransform = new SoundTransform(); // SoundTransform objects have a property called "volume". This is what you need to change volume.
Now in your loop (or on the frame event that you are using) do this:
transform.volume *= 0.9; // or whatever factor you want to have it decrease
//transform.volume /= 1.1; // or this if you prefer.
channel.soundTransform = transform; //
So anytime you want the volume to decrease by this incremental amount, run this bit of code. Of course, you need to make sure that any variables you set are accessible in the code that is referencing them. One way that comes to mind to do this is with a function.
private function soundDiminish(st:SoundTransform, c:SoundChannel, factor:Number = 0.9):void
{
st.volume *= factor;
c.soundTransform = st;
}
Now, whenever you want to diminish the volume just call the soundDiminish function.
Maybe your frame event looks like this:
function onLoadFrame(fe:Event):void
{
soundDiminish(transform, channel); // 3rd parameter optional
}
If you only want this function to be called every 20 frames then:
function onLoadFrame(fe:Event):void
{
// this is a counter that will count up each time this frame event happens
frameCount ++;
if (frameCount >= 20)
{
soundDiminish(transform, channel); // 3rd parameter optional
frameCount = 0; // reset the frame counter
}
}

How to display player lives in game AS3

Hey everyone so having a little trouble trying to accomplish this. I understand how to add lives and display them through a Dynamic Text Field on the stage. My game is set up right now to where this happens and whenever the player dies a live decrements so it works fine.
But I want to display and Image of all 3 lives a custom Movie Clip that I drew in Flash CS6 to represent the lives. So All 3 lives will be displayed in the game and once the player dies one of the lives images is removed.
I have some idea on what to do. For instance I created a "for loop" to display all 3 images on the screen and created variables to place them horizontally next to each other with a space of 30 pixels.
But I'm not sure if this is the correct way to approach this. Also kind of confused on how I would remove one of the images when the player dies?
Her is my code so far:
public var playerLives:mcPlayerLives;
private var nLives:Number = 3;
private var startPoint:Point;
private var aPlayerLivesArray:Array;
In my main class Engine:
aPlayerLivesArray = new Array;
addPlayerLivesToStage();
Then the addplayerlivestostage function:
public function addPlayerLivesToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) - 300, (stage.stageHeight / 2) - 200);
var xSpacing:Number = 30;
for (var i = 0; i < nLives; i++)
{
trace(aPlayerLivesArray.length);
playerLives = new mcPlayerLives();
stage.addChild(playerLives);
playerLives.x = startPoint.x + (xSpacing * i);
playerLives.y = startPoint.y;
aPlayerLivesArray.push(playerLives);
}
}
So like i stated above everything works fine and it does display the 3 images that represent the lives, but would this be the correct approach or is there an easier method?
i think you're using right way to add lives.
and for removing them, you don't need to remove all and add new lives, you can remove the last element of lives array, so, it's done, i think thats already an easy method
so, you can implement this
for (var i = 0; i < nLives; i++)
to make a better usage for "adding lives in-game (earning lives)"
something like
for (var i = aPlayerLivesArray.length; i < nLives; i++)
but don't forget to decrease array length by 1 after removing last element of livesArray when player dies
Looks pretty close to a reasonable approach. I would have a blank container movieclip on stage where you want the lives icons to display. Create one life icon in your library and link it for export with actionscript. When you generate your game view, you can populate this container with the starting value of three lives. Place the first one, then place the subsequent ones based on the first location.
Some untested code:
NOTE: The following presumes your container clip for the lives is named lives_container and your link instance name for the life icon in the library is Life_icon.
var numberOfLives:Number = 3;
var iconSpacing:Number = 5;
var nextX:Number = 0;
for(var i:int = 0; i < numberOfLives; i++ )
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
This way you could add extra lives easily if the player gained any by adding new icons at the last nextX value, like so:
function addLife():void
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
or remove them as the player loses them:
function removeLife():void
{
var numberOfLivesDisplayed:Number = lives_container.numChildren();
lives_container.removeChildAt( numberOfLivesDisplayed - 1 );
nextX -= icon.width + iconSpacing;
}
Using a container clip for the lives icons makes adjusting the location of the life icons easier if it becomes necessary later.

Snakes and Ladders AS3.. how can a movie clip climb a ladder?

I am having this problem in developing this snakes and ladders game and i am very much hoping that you guys can help me out. i already created the board and the avatar. only thing is i cant make the avatar move up the ladder, and move down with the snake. can somebody help me? i am very much desperate right now, and every help is appreciated, thank you guys!
EDIT:
here's the code that i have written so far here are some of the codes I have written so far..
stop();
var xCoord:Array = [141,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251];
var yCoord:Array = [675,670,670,670,670,670,670,670,670,670,670,602,602,602,602,602,602,602,602,602,602,534,534,534,534,534,534,534,534,534,534,466,466,466,466,466,466,466,466,466,466,399,399,399,399,399,399,399,399,399,399,331,331,331,331,331,331,331,331,331,331,262,262,262,262,262,262,262,262,262,262,195,195,195,195,195,195,195,195,195,195,127,127,127,127,127,127,127,127,127,127,60,60,60,60,60,60,60,60,60,60];
var arrSquares:Array = new Array(xCoord.length);
var spaceIndex:Number = 0;
var delay:Number = 400;
var tm:Timer = new Timer(delay);
tm.addEventListener(TimerEvent.TIMER, mover);
tm.addEventListener(TimerEvent.TIMER_COMPLETE, moveDone);
spinner.addEventListener(MouseEvent.CLICK, doSpin);
var total:Number =0;
function doSpin(mevt:MouseEvent):void {
var rn:Number = Math.round(5*Math.random()+1);
txtCount.text = String(rn);
total = total + rn;
txtTotal.text = String(total);
txtCount.visible = true;
spinner.removeEventListener(MouseEvent.CLICK, doSpin);
tm.reset();
tm.repeatCount = rn;
tm.start();
}
function mover(tevt:TimerEvent):void {
spaceIndex = (spaceIndex+1)%(xCoord.length);
chip.x = xCoord[spaceIndex];
chip.y = yCoord[spaceIndex];
}
function moveDone(tevt:TimerEvent):void {
spinner.addEventListener(MouseEvent.CLICK, doSpin);
txtCount.visible = false;
}
i dont know where to put the if statement of executing the motion tween attached to the chip(avatar)
Well here are my initial thoughts. I would create an animation with your character who you want to move up and down. To make it simple, make an animation for climbing, then one for falling. It's really easy to do, just use the tween option on the timeline after inserting your keyframes.
Looks like you've created your animations. Now, whether or not he slides up or falls down depends on where your snakes and ladders are. Only you know that, so at those particular spots on your board (for example, x = 200 and y = 200) we want the if statement to occur. But we only want it to occur after your avatar is done moving. Probably create a new function and add the following to the mover function
var checkX:Number = chip.x;
var checkY:Number = chip.y
checkLandingSpace(checkX,checkY);
Now let's make a function checkLandingSpace which will check if we are on a shoot or ladder
function checkLandingSpace(checkX:Number,checkY:Number):void
{
if (checkX = (your point) || (another point) //first check all x points...continue like this for all points where a ladder is...the || means or
{
if (checkY = (your points....etc)
{
mc_avatarLadder.play(); //choose your instance name to be mc_avatar, then play the tween
}
}
}
Or check this post for equating one variable to any element in an array If [Get Variable] is equal to [Array]
Now write the that for your ladder. Then do the exact same thing with all of your shoots points. Except, make a new animation with instance name mc_avatarShoot then just say mc_avatarShoot.play();
After that, make sure on the last frame for both instances, you just put in gotoAndStop(1); just to make sure it's ready next time you go to play the animation.
Of course, adjust your timer appropriately. This should pretty much do it, there might be a couple things to adjust for your own game, but follow this and understand it and you'll get it.

AS3: How can I construct this Linkage problem?

I want to do something like this with AS3, but I'm new to AS3 and I'm not sure how to go about the coding.
What I need to do is I have 1 x blank MC called all_mc, inside that I need to have 200 x empty_mc all lined up one after another on the x axis.
Each empty_mc is 100px wide and load from a Linkage in the library called panelClass (which is a MovieClip).
The empty_mc itself is called emptyClass in the library.
I need the all_mc to display on the stage from start. It should look like this image. The I need 200 of these red squares.
I know instead of adding all 200 MCs manually, I should be making a loop? But I can not get my head around it for the life of me. Can someone please kindly help me out?
Just make a loop and dynamically create your MovieClips:
var mcWidth:Number = 100; // Using hardcoded value because MovieClip.width is not always reliable (if the MovieClip contains shapes with strokes, etc.)
for (var i:int = 0; i < 200; i++) {
var mc:panelClass = new panelClass();
all_mc.addChild(mc);
mc.name = "empty_mc" + i; // set a name so that it can be accessed later on
mc.x = mcWidth * i;
}