PDA

Просмотр полной версии : Обращение из класса в класс


Digital
05.11.2013, 23:44
При обращении из главной функции главного класса методом
var vectorS:PlaneObj = new PlaneObj() ;

addChild(vectorS);
в класс PlaneObj ошибку не выдаёт но и не добавляет на сцену, выдаёт:
"TypeError: Error #1009: Не удается вызвать свойство или метод со ссылкой на объект "null"."
Если сделать класс PlaneObj главным, то всё выполняется и добавляется(значит ошибка не в нём). Что я делаю не так?

dimarik
05.11.2013, 23:50
А что у нас сегодня за "главную функцию главного класса"? Что-нибудь типа конструктора документ-класса?

Digital
05.11.2013, 23:52
Я имел ввиду, что главный класс - тот который в фла указывается и автоматом выполняется, а главная функция - да, конструктор класса, которая имеет его имя и выполняется автоматом.

dimarik
06.11.2013, 00:08
И у вас не получается сделать инстанс PlaneObj? А в его конструкторе вы случайно не обращаетесь к stage? Уберите addChild ради локализации проблемы. Если проблема на стадии конструирования PlaneObj, то ошибка останется.

Digital
06.11.2013, 02:19
В конструкторе PlaneObj ошибок нет, так как отдельно его вызываю, ошибка, скорее всего, в создании переменной, хотя раньше вроде так и обращался...

Добавлено через 54 секунды
В конструкторе Planeobj к стэйдж не обращаюсь

dimarik
06.11.2013, 02:39
Ну вы меня волноваться заставляете. Ошибок у него в конструкторе нет, к stage он там не обращается, но ошибка есть. И ошибка в создании, епрст, в... переменной. Это оч круто. Это такой баг, что я, боюсь, мы и не разрешим. А вы убрали как я просил, этот addChild? Ну и соизвольте, вкратце, нам ознакомиться с конструктором Planeobj.

Digital
06.11.2013, 16:51
package ua
{
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.geom.Lines3D;
import flash.geom.Rectangle;
import flash.events.Event;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.special.CompositeMaterial;

import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.PaperPlane;
import org.papervision3d.view.BasicView;

import flash.events.KeyboardEvent;
import flash.ui.Keyboard;



public class PlaneObj extends BasicView
{
public var v0:Vertex3D;
public var v1:Vertex3D;

public var c0:Vertex3D;
public var c1:Vertex3D;

public var d0:Vertex3D;
public var d1:Vertex3D;

public var z0:Vertex3D;
public var z1:Vertex3D;
public var z2:Vertex3D;
public var z3:Vertex3D;
public var lm:LineMaterial = new LineMaterial(0x000000);
public var paperPlane:PaperPlane;

private var keyRight:Boolean;
private var keyLeft:Boolean;
private var keyForward:Boolean;
private var keyBackward:Boolean;
public var speed:Number=30
private var KeyFall:Boolean;
private var KeyFly:Boolean;
private var nitro:Boolean;

public function PlaneObj ()
{
super(stage.stageWidth,stage.stageHeight,true,false,CameraType.SPRING);

initCameraControll();

var camera:SpringCamera3D = SpringCamera3D(camera);
camera.mass = 20;
camera.damping = 4;
camera.stiffness = 1;
camera.positionOffset = new Number3D(0,150,-500);
camera.lookOffset = new Number3D(0,0,100);

init ();
startRendering ();

}
private function initCameraControll():void
{
stage.addEventListener (KeyboardEvent.KEY_DOWN,keyDownHandler);
stage.addEventListener (KeyboardEvent.KEY_UP,keyUpHandler);
}
private function keyDownHandler (e:KeyboardEvent):void
{
switch ( e.keyCode )
{
case "W".charCodeAt() :
case Keyboard.UP :
keyForward = true;
break;
case "S".charCodeAt() :
case Keyboard.DOWN :
keyBackward = true;
break;
case "A".charCodeAt() :
case Keyboard.LEFT :
keyLeft = true;
break;
case "D".charCodeAt() :

case Keyboard.RIGHT :
keyRight = true;
break;

case "T".charCodeAt() :
KeyFly = true
break;

case "G".charCodeAt() :
KeyFall = true
break;
case "Z".charCodeAt() :
nitro = true
break;
}
}
private function keyUpHandler (e:KeyboardEvent):void
{
switch (e.keyCode)
{
case "W".charCodeAt() :
case Keyboard.UP :
keyForward = false;
break;
case "S".charCodeAt() :
case Keyboard.DOWN :
keyBackward = false;
break;
case "A".charCodeAt() :
case Keyboard.LEFT :
keyLeft = false;
break;
case "D".charCodeAt() :
case Keyboard.RIGHT :
keyRight = false;
break;

case "T".charCodeAt() :
KeyFly = false
break;

case "G".charCodeAt() :
KeyFall = false
break;
case "Z".charCodeAt() :
nitro = false
break;
}
}
private function init ():void
{
viewport.interactive = true;
v0 = new Vertex3D(0,550,0);
v1 = new Vertex3D(0,-550,0);
c0 = new Vertex3D(550,0,0);
c1 = new Vertex3D(-550,0,0);
d0 = new Vertex3D(0,0,550);
d1 = new Vertex3D(0,0,-550);
var lineN:Lines3D = new Lines3D(lm);

lineN.addNewLine(2,v0.x,v0.y,v0.z,v1.x,v1.y,v1.z);
lineN.addNewLine(2,c0.x,c0.y,c0.z,c1.x,c1.y,c1.z);
lineN.addNewLine(2,d0.x,d0.y,d0.z,d1.x,d1.y,d1.z);
scene.addChild(lineN);
startRendering();

var planeMaterial:CompositeMaterial = new CompositeMaterial();
planeMaterial.addMaterial (new ColorMaterial(0x00CC00));
planeMaterial.addMaterial (new WireframeMaterial(0x484848));
planeMaterial.doubleSided = true;

paperPlane = new PaperPlane(planeMaterial);
scene.addChild (paperPlane);
paperPlane.y = 250;
paperPlane.z = -1000;

camera.z = -1500;
camera.target = paperPlane;
}
private function moveObject ():void
{
if (keyForward)
{
paperPlane.moveForward (speed);
//camera.moveForward (30);
}
else if (keyBackward)
{
paperPlane.moveBackward (speed);
//camera.moveBackward (30);
}
if (keyRight)
{
paperPlane.localRotationY -= 2;
//camera.localRotationY -= 2;
}
else if (keyLeft)
{
paperPlane.localRotationY += 2;
//camera.localRotationY += 2;
}
if(KeyFly){
paperPlane.y += 10;
}
else if(KeyFall){
paperPlane.y -=10
}
if(nitro){
speed = 100
}
else{
speed = 30
}
}
private function doInteractions (e:InteractiveScene3DEvent):void
{
camera.target=e.displayObject3D;
}

override protected function onRenderTick (event:Event = null):void
{
moveObject();
super.onRenderTick ();
}
}
}

Добавлено через 7 минут
Если убрать addChild из главного класса -ничего не меняется

PsixokoT
06.11.2013, 17:13
В конструкторе Planeobj к стэйдж не обращаюсь точно?

uglan
06.11.2013, 17:15
Его импортнуть поди надо?
import ua.PlaneObj;
var vectorS:PlaneObj = new PlaneObj();

Babylon
06.11.2013, 17:20
и конечно трейс в конструкторе прописать ну совсем тяжело:)

dimarik
06.11.2013, 17:34
public function PlaneObj ()
{
super(stage.stageWidth,stage.stageHeight,true,false,CameraType.SPRING);
^^^ - вот же обращение к несуществующему stage

Akopalipsis
06.11.2013, 17:34
А это Вы к чему обращаетесь?
stage.stageWidth,stage.stageHeight
В конструкторе нужно слушать событие на добавление на стейдж.

caseyryan
06.11.2013, 17:49
В конструкторе Planeobj к стэйдж не обращаюсь
Это у меня обман зрения? :D
super(stage.stageWidth,stage.stageHeight,true,false,CameraType.SPRING);

initCameraControll();
В методе initCameraControll() дальше так же идет обращение к stage

Digital
06.11.2013, 18:50
Это у меня обман зрения? :D

В методе initCameraControll() дальше так же идет обращение к stage

Я иммел ввиду, что ничего туда не добавляю... А как мне тогда оттуда обратится к стейдж?

Akopalipsis
06.11.2013, 18:52
А как мне тогда оттуда обратится к стейдж?
В конструкторе нужно слушать событие на добавление на стейдж.
addEventListener(Event.ADDED_TO_STAGE,init);

caseyryan
06.11.2013, 19:05
Я иммел ввиду, что ничего туда не добавляю... А как мне тогда оттуда обратится к стейдж?

Исходя из ваших слов, у вас нет даже базового понимания того как все работает. Поэтому встречный вопрос, зачем сразу лезть в 3д движки?

Digital
06.11.2013, 19:06
Я как бы понимаю и не понимаю одновременно. Вроде в работе с 2д вопросов не было, решил попробовать что-то посложнее с русскими мануалами, но, видимо, я не всё усвоил из 2д

caseyryan
06.11.2013, 19:10
пока объект не добавлен в дисплей лист, его свойство stage == null
А при вызове конструктора объект только создается, поэтому добавлен в дисплей лист он быть в принципе не может на данном этапе. Значи в конструкторе добавляем слушатель события Event.ADDED_TO_STAGE, как написали выше, и в его обработчике уже смело обращаемся к свойствам stage

Digital
06.11.2013, 19:13
но строка
super(stage.stageWidth,stage.stageHeight,true,false,CameraType.SPRING);
может использоваться только в конструкторе класса! А слушатель уведёт из конструктора в обычную функцию

caseyryan
06.11.2013, 19:20
может использоваться только в конструкторе класса! А слушатель уведёт из конструктора в обычную функцию
Кривая реализация. Значит передайте эти параметры как аргументы в конструктор своего класса оттуда, где stage уже есть

А вообще, не зная что там за суперкласс, нельзя сказать как лучше переделать

Digital
06.11.2013, 19:24
Хм, заменил на числовые значения, но не строит теперь!) Хотя и ошибок не выдаёт)

Добавлено через 14 минут
ArgumentError: Error #1063: Несоответствие количества аргументов в ua::PlaneObj/initCameraControll(). Ожидалось 0, получено 1.
Теперь это =(

Добавлено через 25 часов 43 минуты
Ладно, всем спасибо, постараюсь дальше сам разобраться

Digital
14.11.2013, 15:19
Я в отчаянии =( Никакие костыли не работают! Как ещё можно обратиться к stage не из класса?

Akopalipsis
14.11.2013, 15:37
Сделайте в классе в котором нужно обратится к сцене статический метод со сценой в параметрах.
В главном классе, до создания экземпляра нужного Вам класса, передайте сцену в статический метод.
И получится так, что при создании экземпляра, в конструкторе уже будет сцена.

Добавлено через 2 минуты
package
{
import flash.display.Sprite;
import flash.events.Event;

public class Main extends Sprite
{

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

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point

NeedStage.setStage(stage);
var _neddStage:NeedStage = new NeedStage();
}

}

}
package
{
import flash.display.Sprite;
import flash.display.Stage;

public class NeedStage extends Sprite
{
private static var _stage:Stage;

public function NeedStage()
{
trace(_stage);
}
public static function setStage(stage:Stage):void
{
_stage = stage;
}

}

}

Digital
14.11.2013, 15:53
Класс, в котором мне нужно обратиться к сцене расширяет не спрайт, а бейсик вью + главній класс не может расширять спрайт - выдаёт ошибку... У меня главный клас расширяет Мувиклип

Akopalipsis
14.11.2013, 16:00
Не имеет значения, в какой класс передавать сцену.

Digital
14.11.2013, 16:08
Тоесть после этих функций, я смогу из класса NeedStage обращаться к сцене? Или из функции setStage?

Akopalipsis
14.11.2013, 16:13
package ua
{
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.geom.Lines3D;
import flash.geom.Rectangle;
import flash.events.Event;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.special.CompositeMaterial;

import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.PaperPlane;
import org.papervision3d.view.BasicView;

import flash.events.KeyboardEvent;
import flash.ui.Keyboard;



public class PlaneObj extends BasicView
{
private static var _stage:Stage;//!!!!!!!!!!!!!!!

public var v0:Vertex3D;
public var v1:Vertex3D;

public var c0:Vertex3D;
public var c1:Vertex3D;

public var d0:Vertex3D;
public var d1:Vertex3D;

public var z0:Vertex3D;
public var z1:Vertex3D;
public var z2:Vertex3D;
public var z3:Vertex3D;
public var lm:LineMaterial = new LineMaterial(0x000000);
public var paperPlane:PaperPlane;

private var keyRight:Boolean;
private var keyLeft:Boolean;
private var keyForward:Boolean;
private var keyBackward:Boolean;
public var speed:Number=30
private var KeyFall:Boolean;
private var KeyFly:Boolean;
private var nitro:Boolean;

public function PlaneObj ()
{
super(_stage.stageWidth,_stage.stageHeight/*//!!!!!!!!!!!!!!!*/,true,false,CameraType.SPRING);

initCameraControll();

var camera:SpringCamera3D = SpringCamera3D(camera);
camera.mass = 20;
camera.damping = 4;
camera.stiffness = 1;
camera.positionOffset = new Number3D(0,150,-500);
camera.lookOffset = new Number3D(0,0,100);

init ();
startRendering ();

}
public static function setStage(stage:Stage):void
{
_stage = stage;
}
private function initCameraControll():void
{
stage.addEventListener (KeyboardEvent.KEY_DOWN,keyDownHandler);
stage.addEventListener (KeyboardEvent.KEY_UP,keyUpHandler);
}
private function keyDownHandler (e:KeyboardEvent):void
{
switch ( e.keyCode )
{
case "W".charCodeAt() :
case Keyboard.UP :
keyForward = true;
break;
case "S".charCodeAt() :
case Keyboard.DOWN :
keyBackward = true;
break;
case "A".charCodeAt() :
case Keyboard.LEFT :
keyLeft = true;
break;
case "D".charCodeAt() :

case Keyboard.RIGHT :
keyRight = true;
break;

case "T".charCodeAt() :
KeyFly = true
break;

case "G".charCodeAt() :
KeyFall = true
break;
case "Z".charCodeAt() :
nitro = true
break;
}
}
private function keyUpHandler (e:KeyboardEvent):void
{
switch (e.keyCode)
{
case "W".charCodeAt() :
case Keyboard.UP :
keyForward = false;
break;
case "S".charCodeAt() :
case Keyboard.DOWN :
keyBackward = false;
break;
case "A".charCodeAt() :
case Keyboard.LEFT :
keyLeft = false;
break;
case "D".charCodeAt() :
case Keyboard.RIGHT :
keyRight = false;
break;

case "T".charCodeAt() :
KeyFly = false
break;

case "G".charCodeAt() :
KeyFall = false
break;
case "Z".charCodeAt() :
nitro = false
break;
}
}
private function init ():void
{
viewport.interactive = true;
v0 = new Vertex3D(0,550,0);
v1 = new Vertex3D(0,-550,0);
c0 = new Vertex3D(550,0,0);
c1 = new Vertex3D(-550,0,0);
d0 = new Vertex3D(0,0,550);
d1 = new Vertex3D(0,0,-550);
var lineN:Lines3D = new Lines3D(lm);

lineN.addNewLine(2,v0.x,v0.y,v0.z,v1.x,v1.y,v1.z);
lineN.addNewLine(2,c0.x,c0.y,c0.z,c1.x,c1.y,c1.z);
lineN.addNewLine(2,d0.x,d0.y,d0.z,d1.x,d1.y,d1.z);
scene.addChild(lineN);
startRendering();

var planeMaterial:CompositeMaterial = new CompositeMaterial();
planeMaterial.addMaterial (new ColorMaterial(0x00CC00));
planeMaterial.addMaterial (new WireframeMaterial(0x484848));
planeMaterial.doubleSided = true;

paperPlane = new PaperPlane(planeMaterial);
scene.addChild (paperPlane);
paperPlane.y = 250;
paperPlane.z = -1000;

camera.z = -1500;
camera.target = paperPlane;
}
private function moveObject ():void
{
if (keyForward)
{
paperPlane.moveForward (speed);
//camera.moveForward (30);
}
else if (keyBackward)
{
paperPlane.moveBackward (speed);
//camera.moveBackward (30);
}
if (keyRight)
{
paperPlane.localRotationY -= 2;
//camera.localRotationY -= 2;
}
else if (keyLeft)
{
paperPlane.localRotationY += 2;
//camera.localRotationY += 2;
}
if(KeyFly){
paperPlane.y += 10;
}
else if(KeyFall){
paperPlane.y -=10
}
if(nitro){
speed = 100
}
else{
speed = 30
}
}
private function doInteractions (e:InteractiveScene3DEvent):void
{
camera.target=e.displayObject3D;
}

override protected function onRenderTick (event:Event = null):void
{
moveObject();
super.onRenderTick ();
}
}
}

Digital
14.11.2013, 16:14
А слушатели событий в private function initCameraControll():void тоже менять?)

Добавлено через 2 минуты
Даже если их поиенять(и добавить импорт сцены) - всё равно не рисует с TypeError: Error #1009, что-то не так...

Akopalipsis
14.11.2013, 16:18
Конечно, раз Вы уже притащили в класс ссылку, то почему бы ей во всех случаях и не пользоваться.

Digital
14.11.2013, 19:52
И Тем не менее ошибка... Вот основной класс
package
{
import ua.PlaneObj;
import fl.controls.TextArea;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.display.*;
import flash.display.Sprite;
import flash.events.Event;
public class AddButton extends Sprite
{


public var k:Number = 1
public var vx1:Number;
public var vy1:Number;
public var vz1:Number;
public var vx2:Number;
public var vy2:Number;
public var vz2:Number;
public var vx3:Number;
public var vy3:Number;
public var vz3:Number;
public var vx4:Number;
public var vy4:Number;
public var vz4:Number;


private var _timer:Timer;
public function AddButton()
{
var vectorS:PlaneObj = new PlaneObj() ;
trace(stage.stageHeight)
trace(stage.stageWidth)
addChild(vectorS);


var bt_start:MovieClip = new btn
var bt_sutr:MovieClip = new btn_st
var bt_supa:MovieClip = new btn_sp
var bt_ratr:MovieClip = new btn_rt
var fon:MovieClip = new RAMKA
addChild(bt_start)
addChild(bt_sutr)
addChild(bt_ratr)
addChild(bt_supa)
//addChild(fon)
bt_start.x = 50
bt_start.y= 300
bt_sutr.x = 150
bt_sutr.y= 300
bt_supa.x = 300
bt_supa.y = 300
bt_ratr.x = 500
bt_ratr.y = 300
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);


}

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


PlaneObj.setStage(stage);
var _neddStage:PlaneObj = new PlaneObj();
}
}
}

Akopalipsis
14.11.2013, 19:58
Перечитайте эту тему ещё и ещё. Вам не один раз на ошибки указали, а Вы их снова повторяете.
У меня тоже так бывает и по этому я советую перечитать. Если и потом не поймете, то скажите об этом.

Digital
14.11.2013, 20:00
Ок, спасибо, начинаю чтение)

Добавлено через 13 минут
Возможно переходит к классу до того как выполняется объявление stage? Но я не могу решить эту проблему кнопкой, так как конструктор функции не может быть воид, а super используется только в конструкторе

Akopalipsis
14.11.2013, 20:21
Видите, как сделано у меня, в ДокументКлассе, в момент инициализации конструктора сцены может и не быть. По этому, всё что мы делаем, это подписываемся на добавление ДокументКласса на сцену.
Как только поймали события мы передаём ссылку на сцену в класс, который нуждается в ней в конструкторе.
И только потом создаём этот класс. И в момент инициализации его конструктора ссылка на сцену уже есть.

Digital
14.11.2013, 22:47
Я вообще ничего не понимаю) Когда создаётся класс - переменная _neddStage уже есть, но та же typeError... Stage в planeObj тоже не осталось

Akopalipsis
14.11.2013, 22:51
Покажите класс, который должен запуститься со сценой в конструкторе и я покажу.

Digital
14.11.2013, 22:52
И Тем не менее ошибка... Вот основной класс
package
{
import ua.PlaneObj;
import fl.controls.TextArea;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.display.*;
import flash.display.Sprite;
import flash.events.Event;
public class AddButton extends Sprite
{


public var k:Number = 1
public var vx1:Number;
public var vy1:Number;
public var vz1:Number;
public var vx2:Number;
public var vy2:Number;
public var vz2:Number;
public var vx3:Number;
public var vy3:Number;
public var vz3:Number;
public var vx4:Number;
public var vy4:Number;
public var vz4:Number;


private var _timer:Timer;
public function AddButton()
{
var vectorS:PlaneObj = new PlaneObj() ;
trace(stage.stageHeight)
trace(stage.stageWidth)
addChild(vectorS);


var bt_start:MovieClip = new btn
var bt_sutr:MovieClip = new btn_st
var bt_supa:MovieClip = new btn_sp
var bt_ratr:MovieClip = new btn_rt
var fon:MovieClip = new RAMKA
addChild(bt_start)
addChild(bt_sutr)
addChild(bt_ratr)
addChild(bt_supa)
//addChild(fon)
bt_start.x = 50
bt_start.y= 300
bt_sutr.x = 150
bt_sutr.y= 300
bt_supa.x = 300
bt_supa.y = 300
bt_ratr.x = 500
bt_ratr.y = 300
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);


}

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


PlaneObj.setStage(stage);
var _neddStage:PlaneObj = new PlaneObj();
}
}
}
Вот же он

Akopalipsis
14.11.2013, 22:52
И ещё покажите класс, в котором Вы его создаете.

Digital
14.11.2013, 22:54
может просто весь проэкт скинуть?

dimarik
14.11.2013, 22:55
Видите, как сделано у меня, в ДокументКлассе, в момент инициализации конструктора сцены может и не быть.

Правда что ли? Проверьте, пожалуйста.

Добавлено через 1 минуту
public function Main():void {
super.addEventListener(Event.ADDED_TO_STAGE, this.init);
}
Это необходимо и достаточно.

Digital
14.11.2013, 22:57
Вот всё

Akopalipsis
14.11.2013, 22:58
Так Вы класс PlaneObj создаете до того как stage передали.

Digital
14.11.2013, 23:00
Заработало! Я кривой, компилировал и не нажимал "сохранить"... Всем огромное спасибо! теперь я понимаю как это работает)

Akopalipsis
14.11.2013, 23:11
Правда что ли? Проверьте, пожалуйста.
Да, ошибся! В ДокументКлассе stage ЕСТЬ СРАЗУ! А в другом классе, ошибка по тому, что в момент инициализации конструктора, он ещё не добавлен в DOC и по этому его свойство stage===null.
Спасибо за исправление! Заодно и мысли поправили :) Сам не знаю почему такую ерунду написал.