PDA

Volledige versie bekijken : Vraagje over AS3: Flex problemen - object of a null reference


gekke11
%Europe/Berlin %711 %2010, 17:04
Ik heb een probleempje met het maken van een project van me. Ik wil namelijk ervoor zorgen dat zodra een draggable object binnen het bereik van 2 punten zit, het zichtbaar blijft als je naar een ander menu gaat.
Het idee achter het project is namelijk een avatarmaker, maar in plaats van vierkante menu's met scrollbars, is het een cirkel met 4 buttons.
Dit is de code van de main:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

/**
* ...
* @author HCD Team 2
*/
public class Main extends Sprite
{
private var b1:StandardButton1;
private var b2:StandardButton2;
private var b3:StandardButton3;
private var b4:StandardButton4;
private var a1:StandardAvatar;
private var bc:BuitensteCirkel;;
private var u1:BovenkledingSubmenu;
private var u2:OnderkledingSubmenu;
private var u3:AccessoiresSubmenu;
private var u4:SchoenSubmenu

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

public function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);

bc = new BuitensteCirkel(this);
bc.alpha = 0;

//linksboven
b1 = new StandardButton1(true, this, 91, 90, 0);
//rechtsboven
b2 = new StandardButton2(true, this, 400, 90, 0);
//linksonder
b3 = new StandardButton3(false, this, 91, 398, 0);
//rechtsonder
b4 = new StandardButton4(true, this, 400, 398, 0);

//initiate avatarparts
var a1:StandardAvatar = new StandardAvatar(this);
u1 = new BovenkledingSubmenu(this);
u1.visible = false;
u2 = new OnderkledingSubmenu(this);
u2.visible = false;
u3 = new AccessoiresSubmenu(this);
u3.visible = false;
u4 = new SchoenSubmenu(this);
u4.visible = false;

addEventListener(MouseEvent.MOUSE_DOWN, deSelect);
addEventListener(MouseEvent.MOUSE_UP, select);

}

public function select(e:MouseEvent):void
{
if (b1.menutrue == true)
{
if (u1.bk1.bovenvisible == true)
{
u1.bk1.visible = true;
}

if (u1.bk1.bovenvisible == false)
{
u1.bk1.visible = true;
}

bc.alpha = 100;
u1.visible = true;
u2.visible = false;
u3.visible = false;
u4.visible = false
b1.menutrue = false;
b2.menutrue = false;
b3.menutrue = false;
b4.menutrue = false;
}
if (b2.menutrue == true)
{
bc.alpha = 100;
u1.visible = false;
u2.visible = false;
u3.visible = true;
u4.visible = false
b1.menutrue = false;
b2.menutrue = false;
b3.menutrue = false;
b4.menutrue = false;
}
if (b3.menutrue == true)
{
bc.alpha = 100;
u1.visible = false;
u2.visible = true;
u3.visible = false;
u4.visible = false;
b1.menutrue = false;
b2.menutrue = false;
b3.menutrue = false;
b4.menutrue = false;
}
if (b4.menutrue == true)
{
bc.alpha = 100;
u1.visible = false;
u2.visible = false;
u3.visible = false;
u4.visible = true;
b1.menutrue = false;
b2.menutrue = false;
b3.menutrue = false;
b4.menutrue = false;
}
}

public function deSelect(e:MouseEvent):void
{
b1.deSelect();
b2.deSelect();
b3.deSelect();
b4.deSelect();
}
}
}

Dit is de code van het submenu
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;

/**
* ...
* @author Ciriac Tromp
*/
public class BovenkledingSubmenu extends Sprite
{
public var bk1:Bovenkleding1;
public var bk2:Bovenkleding2;
public var bk3:Bovenkleding3;
public var bk4:Bovenkleding4;
public var bk5:Bovenkleding5;
public var bk6:Bovenkleding6;

public function BovenkledingSubmenu(parent:Sprite = null):void
{
var bk1:Bovenkleding1 = new Bovenkleding1(this, 370, 6);
var bk2:Bovenkleding2 = new Bovenkleding2(this, 47, 200);
var bk3:Bovenkleding3 = new Bovenkleding3(this, 687, 200);
var bk4:Bovenkleding4 = new Bovenkleding4(this, 47, 500);
var bk5:Bovenkleding5 = new Bovenkleding5(this, 687, 500);
var bk6:Bovenkleding6 = new Bovenkleding6(this, 370, 712);


if (parent != null)
{
parent.addChild(this);
}

addEventListener(Event.ENTER_FRAME, onEnter);
}

private function onEnter(e:Event):void
{
var point_1:Point = new Point(400, 400);
var point_2:Point = new Point(mouseX, mouseY);
var distanceBetween:Number = Point.distance(point_1, point_2);
if (distanceBetween <= 231)
{

}
}

}

}

En dit is de code van het object zelf:
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.geom.Point;
import flash.net.Socket;
/**
* ...
* @author Ciriac Tromp
*/
public class Bovenkleding1 extends Sprite
{

[Embed(source = '../lib/trui.png')]
private const embeddedImage:Class;
private var imgInstance:Bitmap;
public var bovenvisible:Boolean = false;

public function Bovenkleding1(parent:Sprite = null, x:Number = 0, y:Number = 0)
{
//This piece of code adds this object to the stage
if (parent != null)
{
parent.addChild(this);
}

//initialising position
this.x = x;
this.y = y;

imgInstance = new embeddedImage();

this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
this.addEventListener(Event.ENTER_FRAME, onEnter);

this.draw();
}

private function onEnter(e:Event):void
{
var point_1:Point = new Point(400, 400);
var point_2:Point = new Point(this.x, this.y);
var distanceBetween:Number = Point.distance(point_1, point_2);
if (distanceBetween <= 251)
{
bovenvisible = true;
}
else
{
bovenvisible = false;
}

}

private function onMouseUp(e:MouseEvent):void
{
this.stopDrag();
}

private function onMouseDown(e:MouseEvent):void
{
this.startDrag();
}

public function draw():void
{
graphics.clear();
addChild(imgInstance);
graphics.endFill();
}

}

}

De error die ik krijg, komt voor in de main: op regel 66, waar: if(u1.bk1.bovenvisible == true) staat

Dit is de error die ik krijg:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Main/select()[C:\Users\Rik\Documents\Vakken\2009-2010\Blok 2\Project OUT2\FLASH\HCD Project\src\Main.as:66]

Kan iemand aub helpen? :)

eriknoorland
%Europe/Berlin %765 %2010, 18:22
in je class "BovenkledingSubmenu" maak je public vars aan, en vervolgens maar je met dezelfde naam vars aan in de constructor, volgens mij ga je daar ergens de mist in.

Overigens kan je heel snel testen welke property er niet goed is door ze 1 voor 1 te tracen net boven de regel waar het mis gaat. Zoiets als:

trace(u1);
trace(u1.bk1);
trace(u1.bk1.bovenvisible);

Dan weet je aan welke property het ligt.

gekke11
%Europe/Berlin %770 %2010, 18:29
Zoals ik al dacht, licht het aan de variabele in Bovenkleding1. Zou het misschien kunnen dat ik het op het verkeerde moment de variabele heb aangemaakt?
Btw, bedankt voor je snelle reactie ;)

eriknoorland
%Europe/Berlin %773 %2010, 18:34
Wat ik niet begrijp is dat je wegkomt met:

var bk1:Bovenkleding1 = new Bovenkleding1(this, 370, 6);

terwijl je al een public var hebt gemaakt met dezelfde naam en data type.

public var bk1:Bovenkleding1;

in je "BovenkledingSubmenu" class

gekke11
%Europe/Berlin %778 %2010, 18:40
Misschien komt dat, omdat ik er nog geen waarden aan heb meegegeven, en ze pas inlaad in de constructor. Mijn excuses als dit overigens vaag klinkt, maar mijn begrip van AS3 rijkt niet ver.

eriknoorland
%Europe/Berlin %785 %2010, 18:50
Vervang je constructor van je class "BovenkledingSubmenu" door:

public function BovenkledingSubmenu(parent:Sprite = null):void
{
bk1 = new Bovenkleding1(this, 370, 6);
bk2 = new Bovenkleding2(this, 47, 200);
bk3 = new Bovenkleding3(this, 687, 200);
bk4 = new Bovenkleding4(this, 47, 500);
bk5 = new Bovenkleding5(this, 687, 500);
bk6 = new Bovenkleding6(this, 370, 712);


if (parent != null)
{
parent.addChild(this);
}

addEventListener(Event.ENTER_FRAME, onEnter);
}

en dan zou het moeten werken.

jaspermuts
%Europe/Berlin %796 %2010, 19:06
Wat ik niet begrijp is dat je wegkomt met:

var bk1:Bovenkleding1 = new Bovenkleding1(this, 370, 6);

terwijl je al een public var hebt gemaakt met dezelfde naam en data type.

public var bk1:Bovenkleding1;

in je "BovenkledingSubmenu" class
Dit kan prima: je kunt best een lokale variabele met dezelfde naam als je members hebben, je moet dan wel duidelijk het onderscheid daartussen maken.

package
{
public class A
{
private var a:Object = {}; // member

public function A()
{
var a:Object = {}; // lokale var
trace(a); // lokale var
trace(this.a); // member
trace(this.a == a); // false
}
}
}

Maar de member wordt gebruikt als de lokale variabele niet bestaat

package
{
public class B
{
private var b:Object = {}; // member

public function B()
{

trace(b); // member
trace(this.b); // member
trace(this.b == b); // true
}
}
}

eriknoorland
%Europe/Berlin %798 %2010, 19:10
Weer een les geleerd, wat er dus gebeurde was dat in de class "BovenkledingSubmenu" de lokale variabele werd gebruikt omdat de public property niet "gevuld" werd. En die lokale variabele kan je niet aanspreken van buitenaf.

Dus op zich is mijn oplossing goed, alleen de uitleg daarvan klopt van geen kanten :)

jaspermuts
%Europe/Berlin %972 %2010, 23:20
Ehh volgens mij was er niets dat je zei dat niet klopte hoor... Dat je het niet begreep is toch waar? ;)
En ja, volgens mij was je oplossing ook prima :)

Ik heb mijn voorbeelden nog even aangepast: de laatste regel van het eerste voorbeeld geeft namelijk wel true als zowel vars a en this.a niet geen waarde hebben (null zijn), dat kan wat verwarring veroorzaken: ze zijn niet dezelfde, maar hebben wel dezelfde waarde.