Duplication in AS3 - actionscript-3

So, I've been wondering about this for a while, because if it doesn't work for this new game I'm going to manually have to create hundreds of different movieclips. So, here is what I want to know:
Say if I was developing a game about "Ice Cream" Where you have to create different scoops for your customers.To get an ice cream cone you click the cone and one generates, you can drag it. How do I do this? What I would usually do is create a hundred ice cream cones, make them all invisible, and when it's clicked make the first one visible and if it's clicked again, see if the first one is visible and make the second one visible and so forth. I obviously know they are is an easier way.. but I don't know what that is.
I heard about Duplicating Movie Clips but I read somewhere that it was removed in AS3.

It's possible and quite easy in fact.
1) Click an object and get the class name.
2) Create an new instance of that class and put it in the display list.
3) Move that new instance on every frame to the mouse coordinates until you detect the MouseEvent.MOUSE_UP event.
You will have to tweak the code to fit your project, but this it how it goes. I haven't tested it, but it should work.
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
var duplicate;
var className;
original.addEventListener(MouseEvent.MOUSE_DOWN,duplicateMe);
public function duplicateMe(event):void {
className:Class = Class(getDefinitionByName(getQualifiedClassName(event.target)));
duplicate = new className;
addChild(duplicate);
duplicate.addEventListener(MouseEvent.MOUSE_UP,endDrag);
duplicate.addEventListener(MouseEvent.ENTER_FRAME,update);
}
public function update(event):void {
event.target.x = mouseX;
event.target.y = mouseY;
}
public function endDrag(event):void {
event.target.removeEventListener(MouseEvent.ENTER_FRAME,update);
}

The movieclip type is like the blue print of a movieclip. One can create as many of those movieclips as one needs. For example the movieclip type cat can have an instance with the name Simba. So:
var Simba:Cat = new Cat();
In flash you can simply select the right export to actionscript option to export the type.

Related

as3 creating a custom property in Emanuele Feronato's "Flash Game Development by Example"

I recently picked up Emanuele Feronato's Flash Game Development by Example to try and help expand my knowledge of game design and actionscript 3, and I'm stuck on the first chapter where we're building basically a memory match two game where you have ten sets of tiles and you try and match them up by clicking on them.
In the code I'm stuck on, Mr. Feronato is adding the tiles to the stage using a for loop and addChild, here's the code in particular:
// tile placing loop
for (i:uint=0; i<NUMBER_OF_TILES; i++) {
tile = new tile_movieclip();
addChild(tile);
tile.cardType=tiles[i];
tile.x=5+(tile.width+5)*(i%TILES_PER_ROW);
tile.y=5+(tile.height+5)*(Math.floor(i/TILES_PER_ROW));
tile.gotoAndStop(NUMBER_OF_TILES/2+1);
tile.buttonMode = true;
tile.addEventListener(MouseEvent.CLICK,onTileClicked);
}
// end of tile placing loop
In the 5th line, you can see that he creates a custom property of the tile variable called "cardType," but when I try and run the code I get the error "Access of possibly undefined property cardType through a reference with static type Tile." I have the class Tile extending MovieClip, and the main class extends Sprite, but as far as I can tell I've written the code exactly as in the book and can't get past this. I thought about just using a normal int variable cardType to hold tiles[i] but later on you use the cardType property on a mouse event so I'm a little stuck.
Has something changed in Flash that no longer allows you to create custom properties in this way? Or did I just do something stupid that I'm not catching.
As always, thank you so much for the help.
ActionScript supports dynamic classes, in which properties may be added during runtime. Without the dynamic keyword, a class is sealed, meaning its properties may not be altered.
MovieClip is an example of a dynamic class.
Instantiating a MovieClip from code (or MovieClip instance created in Flash Professional), adding this property would be supported:
var tile:MovieClip = new MovieClip();
tile.cardType = "custom value";
However from code, even if extending MovieClip you must add the dynamic keyword:
package {
import flash.display.MovieClip;
public dynamic class Tile extends MovieClip {
/* ... */
}
}
Now, you may add properties to your Tile instance:
var tile:Tile = new Tile();
tile.cardType = "custom value";

How do I build a movie clip in Actionscript 3

How do I create the AS3 equivalent of a moviescript with multiple frames?
If I were using the Flash IDE, I would put whatever stuff I wanted on frame 1, other stuff on frame 2, etc. and step through the frames as the user clicks the "Next" button. Or perhaps put in keyframes and tweens and let the system play through the frames at a fixed rate.
I don't see a way to do this in AS3, even though all the descriptions I've seen say that Flash CS3 turns your timeline and frames into ActionScript, and I would like to know how to do the same without having the Flash IDE (e.g., working in Flex).
Let's take a simple example: I have 3 frames. Frame 1 contains the splash page (a lot of text and a button). Frame 2 contains one image, one label, and one button that says "Next". Frame 3 contains two images and one label.
How would you build that in AS3?
Flash CS
You will put your logic code in key frame, and do something with the text,button etc. It's hard for multi uses to edit and work on it.
AS3 use IDE like Flash Builder
Flash CS will is just used to make animation swf
Assume we have a swf named A.swf
A.swf
mySymbol (have a link name like com.mySymbol)
subSymbol1(named subSymbol1)
nameLabel(named label1)
addressLabel(named label2)
subSymbol2(named subSymbol2)
nameLabel(named label1)
addressLabel(named label2)
Here is how you use A.swf in flash builder
Class MyView {
public function MyView() {
var loader:Loader = new Loader();
var url:String = "A.swf";
var urlReq:URLRequest = new URLRequest(url);
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(urlReq, loaderContext);
}
private function onLoadComplete(e:Event):void {
//now you can get defined symbols in A.swf
var c:Class = getDefinitionByName(" com.mySymbol");
//get a mySymbol instance
var mc:MovieClip = new c();
//add to parent
some.addChild(mc);
/*what you said you got three frames,
Just like set like subSymbol1 and subSymbol2 in this A.swf
add some text in subSymbol1 and other in subSymbol2 */
mc.subSymbol1.visible = false;
mc.subSymbol2.visible = true;
}
}
It could make the program and view indenpendent in a way.
You would most likely just create each of those frames as an individual Sprite.
When you want to switch between them, you'd use removeChild() to hide the old one and addChild() to show the new one.
If you want to get fancy you can add Tweens (either built-in or from a tweening engine). This would allow you to fade between the frames, or scale them in, or slide from left to right, or whatever.
If you need to do more complex sequenced animations you can look into something like TimelineLite to help with that.

Unable to access children in movie clip

Inside flash cs6 I have drawn a flash movieclip in which I set export settings as abc.Gameboard. Inside gameboard I have a bunch of pieces (symbol:Piece) which I export as abc.Piece - both base class set to MovieClip and with class files. The piece has frame labels like hit, over etc.. My problem is accessing the pieces in code so I can eg. gotoAndPlay("mine") - at the moment the event only fires once which is the last piece on the board.
I can set the frame action on this last piece but would like to figure out how to do same for each piece.
I add a gameboard to the stage like so
var gb:Gameboard = new Gameboard();
gb.name = "gb001";
contextView.addChild(gb);
Then
contextView.addEventListener(Event.ADDED, thingAdded);
private function thingAdded(event:Event):void
{
var type:String = event.target.toString();
switch(type)
{
// this runs only once - i want it to run for each piece that is inside the symbol
case "[object Piece]":
var p:MovieClip = event.target as Piece;
p.gotoAndPlay("mine");
break;
}
}
or if there's a better way that would be great.. this looks pretty clunky
Edit: Bit more info about how I'm trying to build the gameboard
Draw a collection of shapes in illustrator - mask it (Gameboard region). Import into Flash as Graphic. Convert graphic to several movie clip symbols (So JSFL can drill down and access masked pieces) - run JSFL script & create 00's of pieces. Then I set export settings on Piece and Gameboard and add Gameboard to the contextView.
I actually wrote an entire article about this once. The ADDED event should fire once for every DisplayObject that gets added. Are you sure that you're not using ADDED_TO_STAGE, which does not bubble? If you're using ADDED_TO_STAGE, then you need to set the useCapture flag to true to get it to fire for all children.
If you want to involve RobotLegs in the process, probably the better way is to simply create a "marker" Class for each specific button that you want to have behave in a different way, then register a mediator for each Class that will manage the behvior. Robotlegs already has the hooks built in to listen for ADDED_TO_STAGE and do this.
However, you could also consider using the Flash IDE for what it's for, which is putting stuff on stage. In that case, your GameBoard instance will be ready in the constructor of your main document Class for you to do whatever you want with it.
MPO is that logic that is outside Gameboard shouldn't know or care how it works internally, and honestly it probably shouldn't even be GameBoard's responsibility to handle simple stuff like button over states and things. That should be up to the button itself. If the buttons don't need to toggle or anything beyond what SimpleButton handles, you can just declare the button instances as Button in the library instead of MovieClip and get all that stuff for free instead of coding it yourself.
Part of being a good coder is in being able to figure out ways not to code everything.
in their Gameboard inside Piece? I want know exactly your Gameboard Structure.
If you're right. try this:
function thingAdded(e:Event):void
{
if(!e.target is Gameboard) return;
var mc:Gameboard = Gameboard(e.target);
var i:int = 0;
while(i<mc.numChildren)
{
if( mc.getChildAt(i) is Piece)
{
var piece:Piece = Piece(mc.getChildAt(i));
piece.gotoAndStop(2);
}
i++;
}
}
Here is my Sample code: Gameboard

Practical way of getting a picture of a library object

I´m making a level creator for my platformer game on AS3. I´m looking for a way of getting a graphical representation of a library object on my .fla, so the user can insert that object on the world on the desired coordinate. What I mean with this is that I just want a picture of the first frame of the mc, without taking its properties and methods (without the need to make a .jpg containing that image), because that´s when problems begin to appear, and I just want the object functionality on play mode, not the level creator.
Let´s say, for example, a ball that bounces all the time by updating its location every frame. On the level creator I just want to get the ball picture to insert it on the desired location. If I take the whole ball object to the level creator it won´t stop bouncing and it will mess things up.
I hope I´m clear... I just want to know if there is a practical solution to this; if not then I´ll make a class where all the world objects would extend to, that has a init() function that initializes all the object functionality, so it´s called only on play mode and not on level creator. Thanks for reading anyway.
What you're doing wrong is adding functionality directly to the MovieClip.
Please read one of my previous answers that covers this concept in more depth.
MovieClips should be used for the display only, representing the graphics of an actual game class, for example:
public class Player
{
// Graphics that represent the Player.
protected var display:MovieClip;
// Constructor.
public function Player()
{
display = new PlayerMovieClip();
}
}
Anyways, once you fix that you can take a Bitmap sample of MovieClips using BitmapData and its draw():
// Assume that 'mc' is your MovieClip.
var sample:BitmapData = new BitmapData(mc.width, mc.height, true, 0);
sample.draw(mc);
// This is your image.
var texture:Bitmap = new Bitmap(sample);

Interaction between classes

In my main Actionscript file i have a instance of a body class that moves the person body arms legs etc. and a gun class which has methods and properties to do with the person gun.
Right now i have a function in the Main class which is called move gun and looks like this and is called everyframe to move the gun to the bodys arm. I was hoping to move this function to the guns class so i could call it like gun.moveGun(); but the body dosent exist inside the gun variable. so i wonder if i could call the body.getArm(); function from inside the gun. I know i could call the function and pass the bodys arm location to it from the main file. But don't know if this is the best way to do it.
private function moveGun():void
{
gun.x = body.getArm('left').x;
gun.y = body.getArm('left').y;
}
It seems like keeping the gun related functions inside the gun class is the best way to organise everything but i dont know how to do this.
Also depending what button someone clicks at the start the person will either have a basketBall or gun in there hand. Ive added the swf online at Here so you can see how it works. i just wanna change how its organised because the main file is very full and though i should learn how to organise things better. There are lots of other part of the program that would be organised better if i knew how to get the object to interact or what is the best way to do it. Starting to think passing the x,y coordinates to the moveGun function inside the gun Class is the best way. If so just tell me please and ill do that.
From the code you posted, I think you need to move the gun with every frame to stick to the player's arm.
The answer you're looking for is Composition, since every person gets one and only one gun, I think you better put a reference (variable) in the person class for its gun.
and here is your player (person) class:
class Person
{
private var m_gun:Gun;
public function Person()
{
this.m_gun = new Gun();
}
// a function which is called each frame
private function updateFrame()
{
// Here you can provide your own logic in Gun class
this.m_gun.doSomething();
}
}
generally, you want to communicate between classes using the built-in event listener and dispatcher system. if 'something' happens - regardless of 'where' that occurs - dispatch an event. whenever something should react, it should have a listener.
for example, from the main class you mentioned, you might want to dispatch an event:
private function moveGun():void
{
var e:Event = new Event('moveGun', true);
dispatchEvent(e);
}
then the appropriate instance (the body? - not sure how you have things set up) listen for that:
body.addEventListener('moveGun', moveGunHandler, false, 0, true);
function moveGunHandler(event:Event):void{
gun.x = body.getArm('left').x;
gun.y = body.getArm('left').y;
}
the above is obviously psuedo-code since i have no way of knowing how your display list is set up. also, i used simple string literal event types - best practice would probably be to use custom event classes with event types defined as static constants.