Thursday, December 16, 2010
Can of Worms
Okay so the next post is almost entirely code. If your not interested browse on and come back tomorrow.
Opened up a can of worms and going to go into it a bit. First off this entire code program is at:
Object Test You will need Flash to compile.
Or you can just follow along on the image below.
So This is how it SHOULD work but doesn't:
First off lets make the array and object:
//A simple global array because I'm lazy
var simpleArray:Array = new Array();
//A simple global object class because I'm Lazy
var TempObject:Object = {
hello:0,
world:100
}
function standard() {
var result;
//a variable since i don't care what its
//called when placed in the array
//Now it should work as
//result = new TempObject();
//this dosen't compile in action script though for
//any other object it would work
//fine... So instead this is the best version we
//can do and all the pointers now
//point to the same spot.
//Your loop to make 3 copies
for (var i:Number = 0; i < 3; i++) {
result = TempObject;
simpleArray.push(result);
}
traceArray(simpleArray);
//show it before changing one variable in the object
simpleArray[0].hello = 1;
traceArray(simpleArray);
//after changing the one object OMG it changed all
//the same variables GOD NO!
//pointers issue
}
//See pic
//My work around is the ghosts.
//an array exactly the same as the last with a different name
var ghostArray:Array = new Array();
//make 3 ghost objects Note I changed the number of world so you can see which one //is which
var GhostObject1:Object = {
hello:0,
world:200
}
var GhostObject2:Object = {
hello:0,
world:201
}
var GhostObject3:Object = {
hello:0,
world:202
}
function ghost() {
//Just push the 3 into our global array
ghostArray.push(GhostObject1);
ghostArray.push(GhostObject2);
ghostArray.push(GhostObject3);
//trace it
traceArray(ghostArray);
ghostArray[0].hello = 1;
//change 1 spot and trace again
traceArray(ghostArray);
}
//see pic
And what do you know it changed. Your going to want to check out references other then my say so.
http://www.actionscript.org/forums/archive/index.php3/t-143689.html
http://www.actionscript.org/forums/showthread.php3?t=68660
If you guys have a better solution I am more then willing to hear it, as I admit I am a cheap programmer using the KISS system.
Daisy
Subscribe to:
Post Comments (Atom)
AS uses only pointers, so when you create an object, then set another variable equal to that object it is a pointer setting. No new object is being made. To be fair, very few major languages have full copying constructors. Even C++ just does a shallow copy. You generally will have to write your own copy method. In the end your code will look like:
ReplyDeletevar X = new Foo();
var Y = X.copy;
or var Y = new Foo(X);
to be more of a constructor-style. This isn't an AS thing, it's any language that uses pointers. It's a standard coding practice to always include a destructor, copy constructor, and copy method in all objects (the old Rule of Three). Minor pain in the ass for good software, but as long as you start early enough in the project, it won't break any balls.
-Hedonismbot
to create an array of similar objects u can buy creating a temp object in some local function or loop and then by adding it to the array that u want
ReplyDelete1.1 example:
var temparray:Array = new Array();
for (var i:Number = 0; i < 3; i++)
{
var tempobject:Object = {
number:5
};
temparray.push(tempobject);
}
1.2 checkig:
trace(temparray[0].number);
trace(temparray[1].number);
temparray[0].number = 6;
trace(temparray[0].number);
trace(temparray[1].number);
u should get
5
5
6
5
the conclusion
[1]==[1]
however [0]!=[0]
2. example:
ReplyDeletevar temparray:Array = new Array();
function add_object(event:MouseEvent):void
{
var tempobject:Object = {
number:5
};
temparray.push(tempobject);
}
function getInfo(event:MouseEvent):void
{
trace(temparray[0].number);
trace(temparray[1].number);
temparray[0].number = 6;
trace(temparray[0].number);
trace(temparray[1].number);
}
hopes this helps.. sry for my really bad englsih :)
Hmm... Helping Guest going to try out that code tonight it looks very promising.
ReplyDeleteDaisy
Of course, you're not limited into using an arrayList as your only data structure if you get stuck.
ReplyDeleteI'm no expert with Flash, but most languages which use passing by reference have clone functions to effectively duplicate objects.
ReplyDeleteSomething to look at, the code would obviously have to be updated from AS 1 and might not work at all.
http://codeidol.com/flash/flash-hack/ActionScript/Clone-an-Object/
The real problem is here:
ReplyDelete//A simple global object class because I'm Lazy
var TempObject:Object = {
hello:0,
world:100
}
Well, that code WORKS, I mean it doesn't crash...it just doesn't do what you THINK it does. You're not actually creating a class here. You're creating one object, "TempObject". It's basically an array. It has two values, hello and world.
Then, your "result" variable is just a pointer to objects. When you do this:
result = TempObject;
simpleArray.push(result);
The same pointer gets put into simpleArray each time. So of course it always points to the same object.
I believe the "Helping Guest"'s code creates a new object each time with this code:
var tempobject:Object = { number:5 };
So that's why it should work. I think.
The "real" way to do this is to actually define a class. This can be a little tricky to set up, but once you get it working it's easy.
ReplyDeleteThe way I have to do it (I'm using Flash CS4 Pro) is:
1) Decide on a "package name" for the class(es).
2) Create a directory with the same package name. (If the main .fla is in "\MyFlash", and the package is MyPackage, I have to create "\MyFlash\MyPackage".)
3) Decide on a name for the class and create an .as file in the directory with that name. (A class named MyClass would be in the file "\MyFlash\MyPackage\MyClass.as".)
4) The main .fla code has to "import" the class.
Here's an example class:
package tempPackage
{
public class tempClass
{
public var hello:int;
public var world:int;
public function trace_me():void
{
trace("tempClass trace_me called! hello is " + hello + " and world is " + world);
}
public function tempClass(phello:int = 0, pworld:int = 100):void
{
hello = phello;
world = pworld;
}
}
}
Note:
1) The class has two variables, hello and world. Every instance of the class has them.
2) The class has a trace function that prints out the current values for that class.
3) The class has a constructor--this is a function that is called when an instance is created. You can tell it's a constructor because it has the same name as the class.
4) The constructor has default values of 0 and 100. If you call it without arguments, it will fill in those values. Or you can give it your own arguments.
Here's some code using the class:
import tempPackage.tempClass;
trace("creating t_d");
var t_c:tempClass;
t_c = new tempClass();
trace("tracing t_c before t_d created");
t_c.trace_me();
trace("creating t_d");
var t_d:tempClass = new tempClass(3, 56);
trace("tracing t_c after t_d created");
t_c.trace_me();
trace("tracing t_d");
t_d.trace_me();
trace("changing t_c");
t_c.hello = 7837;
t_c.world = 333;
trace("tracing t_c after changed");
t_c.trace_me();
trace("tracing t_d after t_c changed");
t_d.trace_me();
I'd give you a .fla file but I'm not sure we have the same versions of Flash, so...I hope this helps!
If you hadn't seen it already, here's the official Flash documentation:
http://help.adobe.com/en_US/as3/learn/index.html
I believe programing its not about how u do it... its not about having the right way or the wrong way doing it... more about why u do it and how do u feel after doing it... U'll get that feeling of acomplishment even by doing it the wrong way...
ReplyDelete@helping guest: Maybe it's not, but there are advantages of using classes. You can attach methods to classes to manipulate the objects data without having to repeat the code everywhere, making the code a lot cleaner and easier to modify when necesary.
ReplyDeleteFor examle you made a class, lets name it Person, with three atributtes: name, age, tel.
the code to see these atributes on an object isntance named P would be:
trace(P.name);
trace(P.age);
trace(P.tel);
repeat this everywere you want to see the values.
Now if you decided to add a fourth atribute, lets say direction, to the class, you would have to add: trace(P.direction); everywere.
But with methods you can have that code inside the class like this:
fublic function trace_person(){trace(name); trace(age); trace(tel);}
And when you need to see the values you put:
P.trace_person();
If you need to add a fourth atribute you only need to add another trace to the metod, cutting a lot of coding time.
THX for hard work...
ReplyDeleteAnd another THX for Mugi-chan...