Actionscript 3.0 type downcast issue - actionscript-3

I have implemented a new class that extends MovieClip. It's name is base.MovieClipWithDelays ("base" here is a package name).
My scene contains such an object named Blah.
In Symbol Properties I checked Export for ActionScript and Export in first frame checkboxes.
I set Class Name as T_Idle_0.
And I specified it's Base class as base.MovieClipWithDelays.
The problem is that following code leads to the Type Error:
var dob:DisplayObject = getChild("Blah");
trace("SuperClass = " + getQualifiedSuperclassName(dob));
return MovieClipWithDelays(dob);
it outputs:
SuperClass = base::MovieClipWithDelays
TypeError: Error #1034: Type Coercion failed: cannot convert T_Idle_0#1ec59e9 to base.MovieClipWithDelays.
As you can see, it's superclass name is OK. Nevertheless, it fails to downcast it. How is it possible and how do I workaround it?

You cannot set the base class of a library MovieClip to a custom class. You can either set it to Sprite or MovieClip. To do what you want to do, you have two solutions:
1 . Manage everything (drawing, etc.) from your MovieClipWithDelays class. i.e. don't make it depend on a library object.
Or:
2 . Make your MovieClipWithDelays wraps a MovieClip instance.
var libraryMC:MovieClip = new SomeLibraryMovieClip();
var customMc:MovieClipWithDelays = new MovieClipWithDelays(libraryMC);
Then within MovieClipWithDelays, you'll need to have some function and properties to handle the wrapped MovieClip.

Related

How can I name Movieclips in a Movieclip from a Class in Flash?

I have a lot the same Movieclips placed inside a Movieclip. I want to name them, but doing it by hand for each of them would be an annoying task, so I want to do it through actionscript.
I have a Movieclip class named item_Potion (unrelated), and when it runs the constructor function we add 1 to a global variable named itemNumber, then we make the name name = String("item" + itemNumber); in simple terms, we make it item + itemNumber
Just to be clear, this class is bound to this Movieclip item_Potion.
Now here is the issue:
When I try changing the name by doing name = String("item" + itemNumber); I get the following error:
Error: Error #2078: The name property of a Timeline-placed object cannot be modified.
at flash.display::DisplayObject/set name()
at item_Potion()[E:\g\item_Potion.as:33]
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at mc_Map()[E:\g\mc_Map.as:15]
at Game()[E:\g\Game.as:82]
So this is now my question, how can I name the Movieclips from the class without the error?
Think of the "name property of a Timeline-placed object" as a "variable token" that will reference the object, thus needs to be immutable as the error message states!
A rational workaround would be to assign the objects with a custom class (probably derived from the MovieClip class) in which a dedicated field is there to hold the specific name of the object:
public class MySpecialMC extends MovieClip {
public var objName:String;
}
A quick workaround would be to provide the objects with the dynamic class of the very MovieClip class and store the "name" in a dynamic property:
myObj['objName'] = 'item' + itemNumber;

How to assign a custom object to bytesArray? As3

I have a TActor class and a function to_bytes() inside it that should compress it to a bytes array as in this example: http://jacksondunstan.com/articles/1642
public function to_bytes():ByteArray
{
registerClassAlias("TActor",TActor);
var bytes:ByteArray=new ByteArray();
bytes.writeObject(this as TActor);
bytes.position=0;
trace(bytes.readObject());
bytes.position=0;
trace(bytes.readObject() as TActor);
return bytes;
}
However, the first trace prints undefined and the second one null instead of [object TActor].
What do I do wrong?
It's important to note that the this keyword returns the current instance of the object. What you are currently doing is attempting to pass the this instance to writeObject, which will only work if there is an instance of TActor instantiated. So it would work in this scenario:
In some class where you instantiate TActor:
var tactor:TActor = new TActor();
tactor.to_bytes();
Then it should serialize correctly.
Also as we discovered in the comments, TActor is of type MovieClip, currently you cannot use writeObject() on Objects of type MovieClip. More specifically any object that is a dynamic class cannot be used in writeObject. Changing it to Sprite solved this particular case.

How do one cast a instance of subclass to its superclass?

So I have this superclass grid class, and a subclass of the grid class named GrassTile1, GrassTile2, etc... all of the instance of the subclasses are stored in an array. How am I suppose to convert the instance of subclass to its superclass referencing to the array?
private var backgroundGrid = []; //the array which the grids are stored in, in the main class.
public class Grid extends MovieClip
{
protected var node :PathfindNode; //the variable I wish to access, from an instance of subclass.
public function Grid(){
node = new PathfindNode();
}
}
public class GrassTile1 extends Grid { //every subclass of Grid will extends Grid
public function GrassTile1() {
// constructor code
}
}
function getBackgroundGrid(i:int,j:int):Grid{ //in the main class
return Grid(backgroundGrid[i][j]); // this line gives me an error
}
TypeError: Error #1034: Type Coercion failed: cannot convert GrassTile1#2905d5f1 to Grid.
I've tried accessing backgroundGrid[i][j].node and other ways to work around that I could think of and failed. Any Idea?
Try :
return backgroundGrid[i][j] as Grid;
Personally, Grid seems like a bad class name to use. I think Tile makes more sense, as that GrassTile1 is not a grid as I logically understand a grid. A grid might contain a collection of tiles, so doesn't sound logical to use that as a class name for tiles.
Also, where is the line where you actually call the getBackgroundGrid method ? You should try casting there, as opposed to in that method. I believe that will solve the problem.
I can't verify the line throwing the error, so we are assuming that it's the return statement. But, it could be on the other side where you are calling getBackgroundGrid.
UPDATE : I have tried a .fla using what you are describing and it works just fine, I get no error. Which is why I'm thinking we are missing something here and maybe the definition of the class is not being used. Can you put a trace in your constructors to verify what you expect is actually happening ?

Actionscript 3 instance name in class is not working

I have set the instance name of MovieClip to char and when i try to compile this code i get 2 Errors:
package com.game
{
import flash.display.MovieClip;
import flash.events.*;
public class game extends MovieClip
{
var gravity = 0.8;
var velocity = 0;
char.addEventListener(Event.ENTER_FRAME,isHitted);
function isHitted(event:Event):void
{
if (char.hitTestObject(level1))
{
velocity++;
char.y -= gravity+velocity;
}
else
{
}
}
Errors:
.../game.as, Line 13 1120: Access of undefined property char.
../game.as, Line 13 1120: Access of undefined property isHitted.
First off, it sounds like this class definition is the definition for the instance you are referring to, if it is, you should use 'this' instead of 'char'
Also, you typically do not specify method calls like:
char.addEventListener(Event.ENTER_FRAME,isHitted);
outside of methods when declaring a class. Instead, that line of code should exist inside of a constructor or a method that is called during the instantiation of the MovieClip.
You need to make 'char' accessible to 'game' before being able to use it.
One way is to pass 'char' as parameter when you instantiate 'game'.
Two ways of doing this are described in the answer of #lee-burrows in Access caller object when using composition in AS3

Dynamic Class Initiation AS3

I´m trying to initialize a class, based on a concatenation of a string and a number.
All my classes are public.
This is my code:
public function setCurrentPath(pathNumber:String)
{
var pth_class:Class = getDefinitionByName('Pth'+pathNumber) as Class;
var pth:MovieClip = new pth_class();
addChild(pth)
pth.getXY();
}
So I´m getting Error #1065.
Any help?
Yes I have up on my class file import flash.utils.*
Is your pth_class variable null?
If so, there are a couple of reasons this might be the case:
1) You haven't input the correct fully qualified class name of your class. E.g com.myClasses.Pth1
or
2)
If you're instanciating classes dynamically like this and there is no other "regular" reference to the class (such as blah = new Pth1()) then the "Pth1" class won't be included in the compilation process.
To get around this I think you can supply arguments to the compiler to force it to compile those classes OR you can manually include references to them in your existing code:
p1:Pth1;
p2:Pth2;