as3 - Creating common objects for all methods - actionscript-3

I'm building an application using Flash CS6 and AS3, where there will be loads of texts. So I want to create only one text format object for all of them. I am using this code:
public class MyClass extends MovieClip {
public var formatTitle = new TextFormat();
formatTitle.size = 50; <-- ERROR HERE
public function MyClass(){
buildHome();
}
public function buildHome(){
var title:TextField = new TextField();
title.text = "HOME";
title.defaultTextFormat = formatTitle;
addChild(title);
}
}
But I'm getting the error: Access of undefined property formatTitle where it says formatTitle.size = 50. But it's here above it! What am I missing?
Thanks in advance.

You need to move formatTitle.size = 50; at the beginning of the constructor. You can't have code like this outside of a method.
public function MyClass(){
formatTitle.size = 50;
buildHome();
}

Related

AS3 - Problems with IExternalizable

So, i've been working with ByteArrays a lot recently and i'm running into some annoying problems that make me want to rip my hair out.
basically, i'm trying to save project data for an application that i'm making to compile characters for a game into one file. the project consists of custom objects, vectors, vectors of vectors, and even vectors of vectors of custom objects! i figured the best way to write all this data properly would be to use the IExternalizable interface with the readExternal and writeExternal commands. so here's what i'm doing.
i write all the project data to an object, then write that object into a ByteArray, and save it to a file:
// probject means project object !
mProbject= { };
// Register vector as class, just to prevent any errors about that just in case
registerClassAlias("vec_core.timeline.KeyFrame", Vector.<KeyFrame> as Class);
// single KeyFrame Object
mProbject.currentFrame = Main.getInstance().animationList.selectedItem.currentKeyFrame;
// a Vector.<Vector.<KeyFrame>>
mProbject.frames = Main.getInstance().animationList.keyFrameVectorVector;
// an unsigned int
mProbject.selectedItemIndex = Main.getInstance().animationList.entries.indexOf(Main.getInstance().animationList.selectedItem);
// Vector.<String>
mProbject.animationNames = Main.getInstance().animationList.animationNames;
// String
mProbject.projectPath = nativePath;
//String
mProbject.projectName = name;
mByteArray = new ByteArray();
mByteArray.writeObject(mProbject);
mByteArray.compress();
return mByteArray;
inside the KeyFrame class though, there is two more vectors of custom objects:
private var mHitboxes:Vector.<Hitbox>;
private var mHitboxSprites:Vector.<HitboxSprite>;
so i set up both of those classes and my KeyFrame class to use IExternalizable:
public class HitboxSprite extends Sprite implements IExternalizable
{
public function readExternal(input:IDataInput):void
{
trueBounds.x = input.readFloat();
trueBounds.y = input.readFloat();
trueBounds.width = input.readFloat();
trueBounds.height = input.readFloat();
mHitbox = input.readObject();
}
public function writeExternal(output:IDataOutput):void
{
output.writeFloat(trueBounds.x);
output.writeFloat(trueBounds.y);
output.writeFloat(trueBounds.width);
output.writeFloat(trueBounds.height);
output.writeObject(mHitbox);
}
}
public class Hitbox implements IExternalizable
{
public function readExternal(input:IDataInput):void
{
mName = input.readUTF();
mType = input.readUnsignedInt();
mEnabled = input.readBoolean();
mKnockback = input.readBoolean();
x = input.readFloat();
y = input.readFloat();
width = input.readFloat();
height = input.readFloat();
addMultipleTags(input.readUTF());
}
public function writeExternal(output:IDataOutput):void
{
output.writeUTF(mName);
output.writeUnsignedInt(mType);
output.writeBoolean(mEnabled);
output.writeBoolean(mKnockback);
output.writeFloat(mX);
output.writeFloat(mY);
output.writeFloat(mWidth);
output.writeFloat(mHeight);
output.writeUTF(getAllTags());
}
}
public class KeyFrame implements IExternalizable
{
public function readExternal(input:IDataInput):void
{
mID = input.readUnsignedInt();
mLabel = input.readUTF();
}
public function writeExternal(output:IDataOutput):void
{
output.writeUnsignedInt(mID);
output.writeUTF(mLabel);
}
}
but when it gets to the writeObject() method of the "root" ByteArray, i get the error:
[Fault] exception, information=ArgumentError: Error #2004: One of the parameters is invalid.
this is probably the single most annoying problem i've ever had. it seems like i've tried everything and nothing is working.
does anyone else have experience with this? am i doing something wrong??
i'd appreciate any help i can get on this. i just wanna continue making my game :<
Like mentioned in the comment section, you were looking for this. What rang the bell for me was the "Sprite" class you extended. That made me suspicious in the matter that you were trying to externalize visualizable content.

AS3 Accessing a class property that relies on URLLoader

I'm facing some problems in AS3. For example, I have two classes Car.as and ReadXML.as as follows:
Car.as
public class Car{
public function get price():String{
var priceXML:ReadXML = new ReadXML('price.xml');
return priceXML.file;
}
}
ReadXML.as
public class ReadXML{
public var file:XML;
public var loader:URLLoader;
public function ReadXML(fileName:String):void{
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, _loadComplete);
loader.load(new URLRequest(fileName));
}
private function _loadComplete(e:Event):void{
file = new XML(loader.data);
loader.removeEventListener(Event.COMPLETE, _loadComplete);
}
}
But when I try to access the price property,
var carObj:car = new Car();
trace(carObj.price)
it returns null which I presume is because the URLLoader hasn't been finished. So what is an alternative or solution to this? Thanks!
I think loading an XML file every time you want to check an instance's 'price' property is the problem.
I'd recommend loading the XML file as part of your application's initialisation, and including the _loadComplete function as part of that initialisation; When the XML is loaded, your application can then continue and instantiate as many 'new Car()'s as it fancies - no delay will be required if the XML is pre-loaded.

How do you access a dynamic text field from a package / class?

I tried the following line of code inside a class, but it results in an errormessage.
textbox1.text = this.attribute1;
Error description: 1120: Access of undefined property textbox1.
package yourpackage
{
public class MyClass
{
public var dynamicText:TextField;
public function MyClass(){
dynamicText = new TextField();
}
}
}
Now you can create a new instance from this class:
package yourpackage
{
public class MyOtherClass
{
public var myInstance:MyClass;
private var attribute1:int = 0;
public function MyOtherClass(){
myInstance = new MyClass(); //create new instance
myInstance.dynamicText.text = String(attribute1); //set the text of it's
//dynamicText textfield's text to the attribute you want
}
}
}
The error you get actually says that textbox1 is not a defined variable in the current context, or the access modifier is private, thus you can't access it only from within the class. You can create static variables which you can access from anywhere like this:
MyClass.dynamicText.text = "something";
The above code assumes that you declared the dynamicText as a static variable.
public static var dynamicText:TextField = new TextField();
Thanks for your help! However I managed to access and change the text of my textfield by the following two lines of code inside my clickHandler function.
var r:MovieClip = MovieClip(root);
TextField(r["textbox1"]).text = this.navn;
Even though I didn't fully understand your code, I guess it involved creating a text field for each of the objects inside my class?
I will by the way, as you recommended, continue my reading on classes. :)
Thanks again.

AS3 Error accessing parent methods and variables

I'm learning AS3 and I understand that there are a bunch of related questions here with this type of error but I can't seem to figure it out.
I'm getting this error:
TypeError: Error #1034: Type coercion failed: cannot convert bej_cs5_fla::MainTimeline#330ae041 in Board.
at BoardTimer/gameOver()
at BoardTimer/countdown()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
I have to classes. Class Board and class BoardTimer.
Board:
public class Board extends MovieClip {
//Attributes
public var boardSide:uint;
public function Board(dimention:uint) {
boardSide = dimention;
// Code goes here
}
}
BoardTimer:
public class BoardTimer extends Board{
public function BoardTimer(dimention:uint)
{
boardSide2 = dimention;
super(dimention);
gameTimerBox = new TextField();
myTimer = new Timer(1000,count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
}
}
And some BoardTimer methods:
function countdown(event:TimerEvent):void
{
gameTimerBox.x = 700;
gameTimerBox.y = 200;
gameTimerBox.textColor = 0xFFFFFF;
gameTimerBox.text = String((count)-myTimer.currentCount);
if (gameTimerBox.text == "0")
{
gameOver();
gameTimerBox.text = String("Game Over");
}
addChild(gameTimerBox);
}
function gameOver()
{
trace(Board(parent).boardSide);
}
In one frame I have this:
dimention=10;
var boardTimer_mc= new BoardTimer(dimention);
boardTimer_mc.x=25;
boardTimer_mc.y=25;
addChild(boardTimer_mc);
and in another I have this:
var dimention:uint=10;
var board_mc: Board = new Board(dimention);
board_mc.x=25;
board_mc.y=25;
addChild(board_mc);
BoardTimer is doing all that Boardis doing but I'm failing to get access to Board methods and variables. I've tried trace(Board(parent).boardSide);, trace(Board(this.parent).boardSide); and trace(Board(this.parent.parent).boardSide); and nothing.
What am I doing wrong?
parent doesn't refer to base class or the parent class you derived from. It refers to the parent in the displaylist on the stage. (read this)
Use super keyword for referring to the base class. Also, when you are inheriting the class, all the protected & public methods & variables would be available as it is in the derived class.

I Want Access To a Public Static Const in my Actionscript Without Instantiating an Object... Is That Possible?

I've got a static property I would like to access by importing it's class without instantiating an object of that class. Is this possible?
Essentially I'm writing a bunch of styleSheet Objects over and over. I figure If I have a class called CSS and like this:
package com
{
import flash.text.*;
public class CSS
{
public static var STYLE_SHEET:StyleSheet = new StyleSheet();
and assign all of it's properties in the constructor like:
public function CSS
{
//NAV BUTTON
var navButtonBlock:Object = new Object();
navButtonBlock.color = "#000000";
navButtonBlock.fontSize = "25";
navButtonBlock.fontFamily = "Arial";
navButtonBlock.marginLeft = "5";
navButtonBlock.kerning = "true";
navButtonBlock.fontWeight = "bold";
//TITLE
var titleBlock:Object = new Object();
titleBlock.color = "#CCCCCC";
titleBlock.fontSize = "25";
titleBlock.fontFamily = "Arial";
titleBlock.marginLeft = "5";
titleBlock.kerning = "true";
titleBlock.fontWeight = "bold";
STYLE_SHEET.setStyle("code", titleBlock);
STYLE_SHEET.setStyle("navButton", navButtonBlock);
}
If I import the class into the class I wish to make use of it like:
package{
import com.CSS;
and inside my class use the variable like:
textField.styleSheet = CSS.STYLE_SHEET;
I can save some headaches.
The thing I find weird is that I have create an instance of that class to access it's const. So in the class header I have to write:
private var css:CSS = new CSS();
even though I never end up making use of this object...
Does this make sense? Am I going about this the wrong way?
-J
p.s. Who wishes the tab key worked in this question editor window?
You can write static init() function, which you will have call only once or you can use "static initializers":
package com
{
import flash.text.*;
public class CSS
{
public static var STYLE_SHEET:StyleSheet = new StyleSheet();
// Static init block
// This block is run once when the class is first accessed
{
var navButtonBlock:Object = new Object();
/*...*/
var titleBlock:Object = new Object();
/*...*/
STYLE_SHEET.setStyle("code", titleBlock);
STYLE_SHEET.setStyle("navButton", navButtonBlock);
}
}
}
Now import class and just use static var STYLE_SHEET
import com.CSS;
...
textField.styleSheet = CSS.STYLE_SHEET;
You don't have to make an instance of the class to ACCESS its static members, but you are initiating your static variable inside the classes constructor.
This mean that at the time you access the static variable like this:
textField.styleSheet = CSS.STYLE_SHEET;
The STYLE_SHEET property is not set yet!
Usually the way to get around this kind of thing is to have an "init" static method.
CSS.init();
The init method would set STYLE_SHEET, like you have done in your constructor.
This does mean that in you application you will have to call CSS.init() once before you use STYLE_SHEET anywhere else.
ALSO:
What you refer to as a "const", is not a const at all. It is just a static. Const means the value is constant (never changes).
Thanks to both ivann and TandemAdam for leading me down the right path. Ultimately I figured out that first, the reason I had to instantiate an instance of my class is because I was defining my variables properties in the constructor function. So I built a static constructor function which eliminated the need to instantiate, but I still had to call the function (rather than just import).
Then, ivann pointed out, I don't need to call the function at all If I just build a static init() function. Awesome idea except missing one bit of information. You cannot declare variables in a static initializer. So, the ultimate solution was to call my private static function that CAN declare variables from my static initilaizer function.
example:
package com.atJascha
{
import flash.text.*;
public class CSS
{
public static var STYLE_SHEET:StyleSheet = new StyleSheet();
{
init();
}
private static function init()
{
//NAV BUTTON
var navButtonBlock:Object = new Object();
navButtonBlock.color = "#FFFFFF";
//TITLE
var titleBlock:Object = new Object();
titleBlock.color = "#00FFFF";
STYLE_SHEET.setStyle("navButton", navButtonBlock);
STYLE_SHEET.setStyle("title", titleBlock);
}
}
}