Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Access of undefined property (http://www.flasher.ru/forum/showthread.php?t=127420)

SONICTOM 13.07.2009 19:44

Access of undefined property
 
Пишу первую примитивную игру леталку-стрелялку. Вот такой код:

Код AS3:

field.addEventListener(MouseEvent.CLICK, fieldClick);
function fieldClick(a:MouseEvent):void {
 var shoot:sh=new sh;
 addChild(shoot);
 shoot.x=sam.x;
 shoot.y=sam.y;
 shoot.addEventListener(Event.ENTER_FRAME, shootTrace);
}
 
function shootTrace(a:Event):void {
 if (shoot.y>0) {
  shoot.y-=5;
  field.removeEventListener(MouseEvent.CLICK, fieldClick);
 }
 if (shoot.y<0) {
  removeChild(shoot);
 
 }
}

При тесте вылазит ряд ошибок:
Цитата:

1120: Access of undefined property shoot.
Я предпологал сделать так, чтобы при клике по мувиклипу "field" создается объект "shoot", который библиотеке лежит в Библиотеке в виде мувиклипа. В свойствах объекта в Библиотеки указано имя класса "sh".
После этого "shoot" получает координаты мувиклипа "sam" и движется вверх. Если его координата по у станет меньше нуля, то он удаляется).

Подскажите, пожалуйста, где я допустил ошибку. Пожалуйста. объясните, как тупому, так как знаний у меня буквально после 20 видеоуроков по AS3. И еси можно, поправьте, пожалуйста, код.

Заранее большое спасибо за помощь и терпение!

switcher! 13.07.2009 20:51

По идее, shoot объявляется как локальная переменная, которая исчезает сразу по завершению функции fieldClick. А она это делает (завершается) за доли секунды ))

Так что когда вызывается функция shootTrace - ей просто нечего обрабатывать. Отсюда и выскакивает ошибка 1120.

для ваших целей - переменная должна быть объявлена извне функции fieldClick. Другое дело - преобразовать код для ваших задач. Это я подумаю - если местные спецы не помогут раньше.

Партизан 13.07.2009 20:56

Код AS3:

field.addEventListener(MouseEvent.CLICK, fieldClick);
//Создавать экземпляр sh нужно здесь, когда используете ссылку на него из
//разных функций (Знакомство с областью действия переменной)
// Когда создаете экземпляр класса ( var shoot:sh=new sh; ) пишется new sh()
//у вас скобки пропущены (Объекты и Классы) кстати имя класса (sh)
//принято писать с заглавной (Sh)
 
var shoot:sh=new sh();
 
function fieldClick(a:MouseEvent):void {
 
// Здесь sh не создается, пропущены ()  -  должно быть var shoot:sh=new sh();
// var shoot:sh=new sh;
 
 
 addChild(shoot);
 shoot.x=sam.x;
 shoot.y=sam.y;
 shoot.addEventListener(Event.ENTER_FRAME, shootTrace);
}
 
function shootTrace(a:Event):void {
 if (shoot.y>0) {
  shoot.y-=5;
  field.removeEventListener(MouseEvent.CLICK, fieldClick);
 }
 if (shoot.y<0) {
// Здесь неплохо бы удалить сначала листенер
  shoot.removeEventListener(Event.ENTER_FRAME, shootTrace);
  removeChild(shoot);
 
 }
}

Знакомство с областью действия переменной
Объекты и классы

cleptoman 13.07.2009 22:42

Код AS3:

function shootTrace(a:Event):void {
var shoot:sh = e.target as sh;
 
 if (shoot.y>0) {
  shoot.y-=5;
  field.removeEventListener(MouseEvent.CLICK, fieldClick);
 }
 if (shoot.y<0) {
shoot.removeEventListener(Event.ENTER_FRAME, shootTrace);
 
  removeChild(shoot);
 
 }
}

var shoot:sh = e.target as sh;

и еще:
Код AS3:

field.removeEventListener(MouseEvent.CLICK, fieldClick);

тут поменяйте что-нибудь..а то у вас каждый фрэйм филд отписывается от клика.)

Мечтатель 14.07.2009 00:01

Партизан абсолютно необязательно использовать круглые скобки при создании экземпляра класса. Это является делом вкуса. Разумеется, когда метод-конструктор класса запрашивает обязательные параметры, Вы будете должны их передать, а так разницы никакой не будет
Код AS3:

var spOne:Sprite = new Sprite;

и
Код AS3:

var spOne:Sprite = new Sprite();

абсолютно тождественны! И в первом и во втором случае, программа разместит в памяти AVM2 экземпляр класса Sprite, на который будет ссылаться переменная spOne

Партизан 14.07.2009 00:18

Цитата:

Партизан абсолютно необязательно использовать круглые скобки при создании экземпляра класса.
не знал :) спасибо.

BlooDHounD 14.07.2009 01:02

Мечтатель, просто в первом случаи видно, что у "повара" проблемы со вкусом, и кушать его стрепню опасно для здоровья

MonkDead 14.07.2009 08:01

BlooDHounD, красиво сказал. Такую стряпню действительно есть не хочется.

SunShadow 14.07.2009 09:30

Допускается оба варианта записи. Уж кому как нравиться выделяться. Я пользуюсь вторым вариантом по привычке, и это новичков не пугает)

SONICTOM 14.07.2009 11:46

Братцы, большое спасибо за помощь!

Подскажите, пожалуйста, как можно рационально вызвать функцию fieldClick?
Пока я создал прозрачный мувиклип field на заднем плане и вызываю fieldClick кликом по нему.
Есть ли вариант MousEventa кликом не по field, а за его пределами. Тогда я мог бы сделать маленький мувиклип field, поместил бы его де-то за пределами рабочей области игры и вызывал бы fieldClick кликом мимо мувиклипа field.

Спасибо!

SunShadow 14.07.2009 12:42

Цитата:

Сообщение от SONICTOM (Сообщение 835270)
Подскажите, пожалуйста, как можно рационально вызвать функцию fieldClick?

А что такое fieldClick? От того о каком объекте идет речь, зависит какие события ему доступны. И главное чего вы пытаетесь добиться?

SONICTOM 14.07.2009 15:52

Цитата:

Сообщение от SunShadow (Сообщение 835288)
А что такое fieldClick? От того о каком объекте идет речь, зависит какие события ему доступны. И главное чего вы пытаетесь добиться?

Посмтрите, пожалуйста, первый пост темы. Я там процитировал свой код.

Мне нужно, чтобы при клике мышкой вылетал патрон "shoot". Для этого я сделал мувиклип, поторый лежит на заднем плане, растянул его на всю рабочую область, и при клике по нему вызывается функция fieldClick, которая добавляет чайлд патрона и стартует его вылет.

Вот меня и интересуюе, есть ли какие-то более рациональные способы кликом мыши вызвать функцию fieldClick.

Если позволите, я потом задам еще несколько важных для меня вопросов.
Спасибо!

SunShadow 14.07.2009 15:59

Тогда подписывайте на событие stage на тот же самый клик что и для мувика. Прозрачный мувик тогда не нужен

Добавлено через 1 минуту
На сколько я понимаю у вас все в кадрах прописано. Это не рекомендуется для AS3. Код желательно выносить в классы. Выложи бы вы класс было видно от чего наследуется каждый объект, было бы понятно что с ними делать.

SONICTOM 14.07.2009 16:18

Цитата:

Сообщение от SunShadow (Сообщение 835356)
Тогда подписывайте на событие stage на тот же самый клик что и для мувика. Прозрачный мувик тогда не нужен

Ага, так горадо проще.

Цитата:

Добавлено через 1 минуту
На сколько я понимаю у вас все в кадрах прописано. Это не рекомендуется для AS3. Код желательно выносить в классы. Выложи бы вы класс было видно от чего наследуется каждый объект, было бы понятно что с ними делать.
Я пока еще путаюсь в том, что делать, чтобы добиться конечной цели :) Немного привыкну буду в классы выносить. В классы лучше выность все или только то, что часто выплняется или может быть выполнено несколькими объектами?

Еще вот такие вопросы:

1. Допустим у меня вначале идет игровое меню. Как мне сделать так, чтобы весь мой игровой код начал выпоняться только после клика по кнопке старт? Зпихнуть весь код в класс и вызвать его кнопкой старт? И так же его удалить его призавершении игры?

2. Можно ли вызывать какую-то функцию не привязывая ее к объекту (Как например: mc1.addEventLiatener(Event.ENTER_FRAME, NameFunction)., а так, чтобы она вызывалась сама, при запуске флешки?

Мечтатель 14.07.2009 16:31

SONICTOM, не совсем понятно, что ВЫ хотите реализовать...Вам нужно, чтобы приемник для события MouseEvent.CLICK выполнялся не по щелчку на прозрачное поле field, а на что тогда? Поподробнее, plz

SunShadow 14.07.2009 16:33

Подход не правильный) Весь ваш мувик должен быть связан с неким классом, в котором запускаются процессы по загрузке, переходу на новые кадры по событиям и т.п. В случае с игровым меню для кнопок меню пишется общий класс "КНОПКА". А каждой отдельной кнопке присваивается класс наследник от "КНОПКА" с перекрытым методом по клик. Таким образом ваша кнопка старт должна при клике в классе генерировать событие "запуститьИгру". А класс главного мувика должен ловить это событие и переводить мувик к нужному кадру.
Таким образом ООП означает выделить объекты, определить их свойства и поведение и тогда уже писать для них классы. Чем более основательно вы спроектируете систему существования и взаимодействия объектов, тем легче будет делать и модифицировать. Универсальность когда в один класс все пихают не рациональна.
А на счет привычки, учитесь сразу правильно делать, это очень поможет в будущем. Весь код в классы. На кадрах только методы типа stop(), gotoAndStop() и т.д. Хотя в общем можно и без них обойтись)

SONICTOM 14.07.2009 18:26

Цитата:

Сообщение от Мечтатель (Сообщение 835368)
SONICTOM, не совсем понятно, что ВЫ хотите реализовать...Вам нужно, чтобы приемник для события MouseEvent.CLICK выполнялся не по щелчку на прозрачное поле field, а на что тогда? Поподробнее, plz

SunShadow мне уже объяснил, что функцию по клику без использования прозрачного поля можно реализовать таким образом: stage.addEventListener(MouseEvent.CLICK, FunctionName)


Цитата:

Сообщение от SunShadow (Сообщение 835370)
Подход не правильный) Весь ваш мувик должен быть связан с неким классом, в котором запускаются процессы по загрузке, переходу на новые кадры по событиям и т.п. В случае с игровым меню для кнопок меню пишется общий класс "КНОПКА". А каждой отдельной кнопке присваивается класс наследник от "КНОПКА" с перекрытым методом по клик. Таким образом ваша кнопка старт должна при клике в классе генерировать событие "запуститьИгру". А класс главного мувика должен ловить это событие и переводить мувик к нужному кадру.
Таким образом ООП означает выделить объекты, определить их свойства и поведение и тогда уже писать для них классы. Чем более основательно вы спроектируете систему существования и взаимодействия объектов, тем легче будет делать и модифицировать. Универсальность когда в один класс все пихают не рациональна.
А на счет привычки, учитесь сразу правильно делать, это очень поможет в будущем. Весь код в классы. На кадрах только методы типа stop(), gotoAndStop() и т.д. Хотя в общем можно и без них обойтись)

Ничего не понял, но все равно спасибо за объяснения :)
Просто видео в моих видеоуроках это еще не описывалось.
Учили создавать классы в виде as файлов, где описывалось поведение спрайта, потом привязывали поведение объекта из бблиотеки к этому классу.
Думаю с этим разберуть потом. А пока у меня по прежнему проблемы с реализацией игры :( После попадания патрона во врага, оба удаляются и по их координатам появляется мувик с анимацией взрыва.
После снова вылазит ошибка:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display:: DisplayObjectContainer/removeChild()
at g6_fla::MainTimeline/shootTrace()

Не пойму в чем дело :(
Вот текущий код:

Код AS3:

sam.addEventListener(Event.ENTER_FRAME, samTrace);
 
function samTrace(a:Event):void {
        sam.x=mouseX;
}
 
// Патрон
 
var shoot:sh=new sh;
var n:Number=1;
 
stage.addEventListener(MouseEvent.CLICK, fieldClick);
 
function fieldClick(a:MouseEvent):void {
        addChild(shoot);
        shoot.x=sam.x;
        shoot.y=sam.y-20;
        shoot.addEventListener(Event.ENTER_FRAME, shootTrace);
}
function shootTrace(a:Event):void {
        if (shoot.y>0) {
                shoot.y-=5;
                stage.removeEventListener(MouseEvent.CLICK, fieldClick);
                if (shoot.y<0) {
                        shoot.removeEventListener(Event.ENTER_FRAME, shootTrace);
                        removeChild(shoot);
                        stage.addEventListener(MouseEvent.CLICK, fieldClick);
                }
        }
}
 
// Противник
var en:Enemy=new Enemy
var b:Number=1
en.addEventListener(Event.ENTER_FRAME, enStart)
 
function enStart(a:Event):void{
        if(b==1){
                addChild(en)
                en.y=-30
                en.x=Math.random()*550
                b=2
        }
        if(en.y<430){
                en.y+=5
        }
        else{
                b=1}
}
 
// Отслеживание попадания
 
stage.addEventListener(Event.ENTER_FRAME, hitTrace)
 
 
 
function hitTrace(a:Event):void{
        if(shoot.hitTestObject(en)){
                stage.removeEventListener(Event.ENTER_FRAME, hitTrace)
                boom.x=en.x
                boom.y=en.y
                boom.play()
                removeChild(shoot)
                removeChild(en)
 
        }
}


SONICTOM 26.07.2009 14:09

Братцы, не оставьте, пожалуйста, без помощи!

Azrael 10.05.2016 23:58

Скажите почему возникает эта ошибка в моем случае?
Решил вынести код игрового меню из main в отдельный класс. Появилась эта ошибка касательно переменных AboutText и myFormat. В main этот код работал, а в новом (своем) классе уже нет.
Код AS1/AS2:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.display.*;
        import flash.events.MouseEvent;
        import flash.system.fscommand;
        import flash.text.*;
 
        public class MenuScreen extends Sprite
        {
                var myFormat:TextFormat = new TextFormat();       
                var AboutText:TextField = new TextField();
 
                var btn_play:MyButtonClass = new MyButtonClass();
                var btn_opt:MyButtonClass = new MyButtonClass();
                var btn_inst:MyButtonClass = new MyButtonClass();
                var btn_abt:MyButtonClass = new MyButtonClass();
                var btn_ext:MyButtonClass = new MyButtonClass();
 
 
                myFormat.font = "Times New Roman";
                myFormat.size = 20;
                myFormat.color = 0x000000;                               
 
                AboutText.width = 550;
                AboutText.height = 250;
                AboutText.x = 225;
                AboutText.y = 80;
                AboutText.selectable = false;
                AboutText.setTextFormat(myFormat);
                addChild(AboutText);
 
                public function MenuScreen()
                                {
                                super();
 
 
                                        btn_play.name = "btn_PLAY";
                                        btn_play.label = "Play";
                                        btn_play.addEventListener(MouseEvent.CLICK, btnMouseHandle);
                                        addChild(btn_play).y = 50;
                                        btn_play.x = 80
 
 
                                        btn_opt.name = "btn_OPTIONS";
                                        btn_opt.label = "Options"
                                        btn_opt.addEventListener(MouseEvent.CLICK, btnMouseHandle);
                                        addChild(btn_opt).y = 100;
                                        btn_opt.x = 80
 
 
                                        btn_inst.name = "btn_INSTRUCTIONS";
                                        btn_inst.label = "Instructions"
                                        btn_inst.addEventListener(MouseEvent.CLICK, btnMouseHandle);
                                        addChild(btn_inst).y = 150;
                                        btn_inst.x = 80
 
 
                                        btn_abt.name = "btn_ABOUT";
                                        btn_abt.label = "About"
                                        btn_abt.addEventListener(MouseEvent.CLICK, btnMouseHandle);
                                        addChild(btn_abt).y = 200;
                                        btn_abt.x = 80
 
 
                                        btn_ext.name = "btn_EXIT";
                                        btn_ext.label = "Exit"
                                        btn_ext.addEventListener(MouseEvent.CLICK, btnMouseHandle);
                                        addChild(btn_ext).y = 250;
                                        btn_ext.x = 80
                                }
 
                function btnMouseHandle(e:MouseEvent):void
                                {                                       
                                        switch(e.target.name){
                                                case "btn_PLAY":
                                                        var TestSWC:MovieClip = new WSymbol_mc;
                                                        trace("btn_01 click");
                                                        TestSWC.x = 50;
                                                        TestSWC.y = 50;
                                                        addChild(TestSWC);
                                                        break;
                                                case "btn_OPTIONS":
                                                        trace("btn_02 click");
                                                        break;
                                                case "btn_INSTRUCTIONS":
                                                        trace("btn_03 click");
                                                        ShowTextBlock (e.target.name);
                                                        break;
                                                case "btn_ABOUT":
                                                        trace("btn_04 click");
                                                        ShowTextBlock (e.target.name);
                                                        break;
                                                case "btn_EXIT":
                                                        trace("btn_05 click");
                                                        fscommand('quit');
                                                        break;
                                        }
                                }
 
                function ShowTextBlock (strID:String):void
                                {               
                                        if (strID == "btn_INSTRUCTIONS")
                                                {
                                                        trace("INS");
                                                        AboutText.text = "Some text here";
                                                }
                                        else
                                                {
                                                        trace("AB");
                                                        myFormat.align = TextFormatAlign.CENTER;
                                                        myFormat.leading = 10;
                                                        AboutText.defaultTextFormat = myFormat;
                                                        AboutText.text = "Some text here";
                                                }
                                }
 
        }
 
}

Main

Код AS1/AS2:

package
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.display.*;
        import flash.events.MouseEvent;
        import flash.system.fscommand;
        import flash.text.*;
 
        public class Main extends Sprite
        {
 
                var MScreen:MenuScreen = new MenuScreen;
 
 
 
                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);
                        addChild(MScreen);
 
 
                }
 
        }
 
}



Часовой пояс GMT +4, время: 07:40.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.