Public Function Allegedly Doesn't Exist? - actionscript-3

Okay, I am at the end of my rope.
I have a Flash Professional CS5.5, Adobe AIR, Actionscript 3 project. So far, I've never had this problem before...
I have a custom class called Prefs, that I wrote myself. This class has a number of functions. The ones I wrote a couple weeks ago, I can call in my code with no problem. But the ones in the SAME CLASS that I wrote today are throwing an error.
This one works:
public function UserFetch(ID:String):*
{
This one doesn't:
public function Set(setting:String, val:*):void
{
I call both the same way. In the document class "base":
package {
import flash.display.MovieClip;
import trailcrest.prefs.prefs;
public class base extends MovieClip {
public static var Prefs:prefs = new prefs();
}
}
In my timeline code.
base.Prefs.UserFetch("musictoggle");
base.Prefs.Set("musictoggle", true);
The first fires fine. The second gives this error:
Scene 1, Layer 'Layer 1', Frame 1, Line 4 1061: Call to a possibly
undefined method Set through a reference with static type
prefs.
What is going on? I can find absolutely no legitimate reason why this should be happening. Like I said, it has never happened before, and it not happening on any other class or function.

After a bit of discussion in the chat, we found that flash was not picking up on the changes made in the prefs.as-file. Changing the name of the class fixed the issue (It may have been a weird compiler cache problem).

Related

Embedding png throws Error #1065: Variable FlexVersion is not defined

I've found several articles relating to variable FlexVersion and error 1065, but nothing seems to help.
EDIT:I've attempted to implement SEVERAL guides on embedding images into flashDevelop with the same result. Everything works correctly until I try to add the embedded image, then I get the above error.
Has no one here seen this error?
My Class (which I've stripped down to nothing in order to pinpoint the issue):
package {
import flash.display.Sprite;
import flash.display.Bitmap;
public class JMouse extends Sprite {
[Embed(source = "../lib/jacobsLadder.png")]
private var Picture:Class;
//private var pic:Bitmap = new Picture(); // THIS LINE
public function JMouse() {
init();
}
private function init():void {
}
}
throws the error when the line "THIS LINE" is not commented out. I've tried adding "as Bitmap" to the end of this line without luck.
I am calling this class from my document class:
jMouse = new JMouse();
the file, jacobsLadder.png, is in my lib folder, and I used FlashDevelop to "Generate Embed Code."
I am using FlashDevelop 5.0.1.3 for .NET 3.5
Any Ideas?
EDIT: I also tried this (and similar variations), as per the suggestion:
"The type of code you can run at variable declaration scope is limited. Creating an instance of Picture requires decoding and so will fail at that point. Instead create your instance of Picture within an instance methods or the constructor."
[Embed(source = "../lib/jacobsLadder.png")]
public static var Picture:Class;
public function JMouse() {
var pic:Bitmap = new Picture();
init();
}
But I get the same error.
The type of code you can run at variable declaration scope is limited. Creating an instance of Picture requires decoding and so will fail at that point. Instead create your instance of Picture within an instance methods or the constructor.
ANSWER: Load the bitmapdata with a loader.
Although the OP (me) was asking how to embed the file, the mysterious problem of "Error #1065: Variable FlexVersion is not defined" issue is apparently an insurmountable one, and I hope that anyone else who may come across this problem may find solace in the following (courtesy of John Mark Isaac Madison et al):
How do you load a bitmap file into a BitmapData object?
While not the an answer, per se, it at least allows the OP to continue on in his work as an alternative to lighting his house on fire.

Type Coercion failed in 'loader' and 'loaded' applications

My main application swf file is being loaded by a simple loader swf application that is useful to break cache. In both applications I would like to have access to a singleton. I will provide you with an example to reproduce the bug. So here's our singleton:
package {
public class SingletonTest {
public static const instance:SingletonTest = new SingletonTest();
public function SingletonTest() { /* Nothing here. */ }
public function test():void {
trace("SingletonTest!");
}
}
}
In constructors of both loader and main classes I call:
SingletonTest.instance.test();
That is made in order to be sure that my singleton class code will be included in both applications. I won't provide you with loader code but it's very simple. It creates Loader instance, it creates LoaderContext supplying it with both current ApplicationDomain and SecurityDomain, etc...
But when I launch my loader application I get following error:
Main Thread (Suspended: TypeError: Error #1034: Type Coercion failed:
cannot convert SingletonTest#47a3091 to SingletonTest.)
SingletonTest$cinit
I get this error right after main application was loaded with loader. Event.COMPLETE is not dispatched yet so no handlers involved. I spent a lot of time trying to find something about application or security domains but it seems like it's not the issue because what I found next is really strange. If instead:
public static const instance:SingletonTest = new SingletonTest();
I will write:
private static var _instance:SingletonTest;
public static function get instance():SingletonTest {
if (_instance == null) _instance = new SingletonTest();
return _instance;
}
Then there will be no such error and everything will be fine. Obviously flash player is performing some unexpected behavior here. There's very few information on this issue out there. Most of people get this error because of missing loader context but as I said before here it's not the case. Some discussions on this are even left without any answers which is strange to me because I find this to be quite a common problem to be encountered when using small applcation loader.
Spent almost 12 hours trying to solve the problem. At last found the solution. In order to avoid runtime error which I provided above you need to compile your singleton class into swc-library. That's it.
In my case that singleton was providing global access to logging and only option was to switch from singleton pattern to static class. But I didn't want it very much because I really like this one-line singleton instantiation: "public static cosnt instance:MyClass = new MyClass();".

Collecting Information From a Variable with An EventListener

This may be quite a complicated question, but I am making a hack for a game which I have hacked many times before and I have had a request, but I do not know how to work around it.
I am not that advanced at AS3 so please be kind if I fail xD
The request is to make a chat catcher for the game, where all chat is saved. I have been told that I can use an EventListener to do this. I also discovered that
Game.chatM
Is the linkage (I think that's the correct word for this) for where all of the chat can be found.
I know that it's a far stretched question, but is there a function which would do something such as this? Like gathering information from this variable?
Any advice would be much appreciated!
What I tried before:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
public Class ChatCatcher extends Sprite
{
private var Game.chatM:Model;
public function ChatCatcher():void
{
Game.chatM = new Model();
Game.chatM.addEventListener(Model.VALUE_CHANGED, onModelChanged);
}
private function onModelChanged(e:Event):void
{
trace('New Chat Message');
//This is where hopefully chat will be saved
}
}
}
Your code looks a little suspicious.
You incorrectly declare a variable on this line:
private var Game.chatM:Model;
You shouldn't be declaring variables that have a dot in their name. That should generate an error when you try to compile your code.
I imagine that Game is a class, and that in that class you have defined a static property named chatM (which is of type Model). If this is the case, then you should do something like this to declare a local instance of the chat model in your class:
private var chatModel:Model = Game.chatM;
Next, you add an event listener for the event "onModelChanged". If the chat model class dispatches such an event when a new chat message is added, then your event listener will get executed.
But all of my guessing here seems to lead me to the conclusion that this is all unnecessary. I'm sure I've misunderstood something... but your intent was to get a list of all the chat messages. And it seems you already have that list (the chat model itself).
If this doesn't help, you should also add the relevant code for your Model class and if it exists, the Game class... and of course, tell me where my guesses were wrong!

passing custom events between modules through parent application

I have created a custom event that I want to use to pass a string between two modules. The event looks like this:
package com.mypackage.events
{
import flash.events.Event;
public class ThumbDeleteEvent extends Event
{
public static const THUMBS_DELETED:String = "thumbsDeleted";
public var files:String;
public function ThumbDeleteEvent(type:String, files:String)
{
super(type);
this.files = files;
}
// Override the inherited clone() method.
override public function clone():Event {
return new ThumbDeleteEvent(type, files);
}
}
}
In one module I dispatch the event like so:
parentApplication.dispatchEvent(new ThumbDeleteEvent("parentApplication.thumbsDeleted", files));
and in another module I listen for the event like so:
public function init():void {
parentApplication.addEventListener("parentApplication.thumbsDeleted", onThumbsDelete);
}
if I use ThumbsDeleteEvent as the type passed in to the listener function like this:
public function onThumbsDelete(evt:ThumbDeleteEvent):void{
trace("thumb delete event for thumbs: "+evt.files);
}
I get the following error:
TypeError: Error #1034: Type Coercion failed: cannot convert com.mypackage.events::ThumbDeleteEvent#26748a31 to com.mypackage.events.ThumbDeleteEvent.
if I just use Event as the type passed in to the listener function like this:
public function onThumbsDelete(evt:ThumbDeleteEvent):void{
if(evt is ThumbDeleteEvent){
trace("thumb delete event for thumbs: "+(evt as ThumbDeleteEvent).files);
}else{
var type:XML = describeType(evt);
trace(type.toXMLString());
}
}
It works but does not think it is a ThumbDeleteEvent type class (it hits the else statement) the xml output of describe type says its type is:
type name="com.mypackage.events::ThumbDeleteEvent"
What is going on here? If I put a breakpoint in the debugger it says the event is a ThumbDeleteEvent and I can see the files parameter and its right???
The issue here is that one swf has their definition of that class, and then the other swf has its own version of that exact same class. When trying to cast between them flash does a bytecode-check to see if the definitions are the same, and if you ever changed something in that as file without updating both with the exact same info you will run into this issue. That is, compile both swf-files, then change a space in the as-file, and compile only one swf file.
Urgh it's coming back to me, all those issues with shared code between different modules. I always just slug my way through these errors until I get it to work and can never really remember what it is since it can be so many issues.
Make sure both compiled swf-files have up-to-date-versions of the file.
Make sure both swf-files have same linkage-nesting to the code-file.
If that doesn't work [can't really remember since this issue is kind of like solve-once and copy to every other project].
See in which order things are added to ApplicationDomain and make sure nothing else has their own out-of-date-version of it through something imported in flash library
Move shared code into seperate code library linked in with "dynamic binding"
Try with sharing the Interface instead
Change how assets are loaded into the ApplicationDomain
Hopefully someone has more knowledge of this issue and can tell exactly what steps to use, but this is at least a starting point... I might have more time to research this and write a post about it sometime in the future later today.
Edit:
from another SO-thread Custom AS3 Class not Updating
This is the age old problem of what ultimately boils down to is the Verify Error. It happens when you embed "Class A" in one or more applications, modules, swfs, etc. Ultimately every output swf that uses "Class A" must be recompiled when "Class A" is changed. Otherwise you end up with a situation where 1 module has the newer implementation but others don't. This problem is compounded by the fact that the application domain is defined as a "first in wins" when it encounters a Class of the same name / package - meaning if the old one is referenced first, the newer one loaded later gets ignored.
The more permanent solution is to use class promotion to an RSL that ultimately allows the RSL to control the actual "Class A" reference in which it also implements an "IClassAImpl" interface that all modules use. This allows the compiler to cross link the reference with a signature it knows about without actually embedding the actual class itself.

AS3 OOP common practices examples?

I am trying to better understand the AS3 OOP structure and organization, but I am having some problems wrapping my head around it. I want to create multiple class files and it seems that best practice is not to and to put all classes in one file? I have searched for hours on the web and came up with little for good examples. Maybe seperate files is not the way to go while using AS3, but to me it only makes sense for modularzation. The files I have been playing with are:
Main.fla
Main.as (document class)
TestOne.as
TestTwo.as
TestThree.as
TestFour.as
TestFive.as
I have created a folder called classes to house all class files except the Main.as which resides with the FLA.
All five Test classes are the same code except the file name and class name.
Here is how I am importing the files:
Main.as
package classes
{
import flash.display.MovieClip;
import classes.TestOne;
import classes.TestTwo;
import classes.TestThree;
import classes.TestFour;
import classes.TestFive;
public class Init extends MovieClip
{
trace("This is Main Class");
var testOne : TestOne = new TestOne;
}
}
TestOne.as
package classes
{
import flash.display.MovieClip;
public class TestOne extends MovieClip
{
trace("This is TestOne");
public function testing():String
{
return "This is the testing method";
}
}
}
Are the above examples I created good AS3 OOP practices? I understand these are real basic classes, but I think it should get the point arossed.
I am using CS3
Might be good to look at the Flex SDK coding conventions and best practices. It is a point by point rundown of how you should be using ActionScript 3. There is quite a bit of OOP stuff scattered throughout, so take a good skim through it. I think it is worth any new or experienced AS3 devs to have a read, because there is a lot of useful information there.
OOP is a big subject but here is a good primer.
ActionScript 3 design patterns will be also useful for you.
As Nathan said, big subject.
The thing about having all classes in one file is related to the topic "visibility of a class" and "access modifiers".
The modifier is that what is written before the class keyword. It can be public or internal. Internal means, that only code that is placed in the same directory (package) of the internal class can create an object of it. Public means, any code can create an instance of the class. Random link via google: http://flexmaster.blog.co.in/2010/05/20/action-script-use-access-modifiers-with-classes-and-class-members/
You are allowed to have multiple classes in one file. But then only one can have the modifier public. All others need to be internal. If you leave out the modifier, a class is by default internally visible. An internal class in a multiple classes file can be accessed only from within this file.
There are two more modifiers: protected and private. Both are applicable only to properties or methods. As an advanced developer you can even define you own modifier by using namespaces.
The rules of OOP still apply to AS3
1) Encapsulation.
2) Inheritance.
3) Abstraction.
4) Polymorphism.
Apply them or not is your choice but it is good practice.
And don't forget the most important rule "KISS" (keep it simple stupid)
I also want to point out your code has an error
package classes
{
import flash.display.MovieClip;
public class TestOne extends MovieClip
{
trace("This is TestOne");// this line is not inside a function and will most undoubtly error out your app.
public function testing():String
{
return "This is the testing method";
}
}
}
I think you either did something wrong when you copied the code into SO or you're not placing the trace statements correctly. You need to place the trace("This is TestOne"); inside a constructor in TestOne.as, like this:
public function TestOne() {
trace("This is TestOne");
}
The same goes for the code inside the Init class, which now reads:
trace("This is Main Class");
var testOne : TestOne = new TestOne;
but should be(note the bracers after new TestOne):
public function Init() {
trace("This is Main Class");
var testOne : TestOne = new TestOne();
}
What happens when you run your SWF, is that the constructor of the class Init will:
1) Trace "This is Main Class" to your console.
2) It will construct a new object(thus the name constructor) by calling the constructor of the class TestOne.
If you were to add this line to the end of the constructor in the class Init:
testOne.testing();
you should see this in the console: "This is the testing method".
If you would now comment out the line: var testOne : TestOne = new TestOne(); and run the SWF again, you'll get an error telling you something is null. This is because you attempt to call the method testing on an object that does not exist.
I do realize this is primarily fixing some coding errors of yours, and not so much helping you understand OOP. But hopefully you can pick up some help regarding object construction. I see some answers already mention key OOP principle that you really should look into.
Edit:
Remember that duplicating code is never a good thing, so if you find that all of the classes TestOne - TestFive contain the same code, except for some minor detail. You should probably change them into one class.
In your case you could for example change TestOne so that the constructor accepts a String, and then in your testing function you could just trace that String. By changing your TestOne class into the following you effectively get rid of 4 other classes. You also encapsulate a String inside of the class TestOne.
package classes {
import flash.display.MovieClip;
public class TestOne extends MovieClip {
private var message : String;
public function TestOne(myMessage:String) {
message = myMessage;
trace("This is TestOne");
}
public function testing() : String {
return message;
}
}
}