Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 26.09.2009, 21:53
Furinax вне форума Посмотреть профиль Отправить личное сообщение для Furinax Найти все сообщения от Furinax
  № 1  
Ответить с цитированием
Furinax
[+1 02.09.15]

Регистрация: Mar 2009
Адрес: Moscow
Сообщений: 469
По умолчанию Как правильно вызвать метод?

У меня есть три символа во флэш, все слинкованы с классами.Первые два расширяют класс MovieClip. Третий расширяет класс SimpleButton. Третий символ вложен во второй. На этапе выполнения первый символ создает экземпляр второго и вносит его в список отображения на сцену (ну и соответственно вместе с ним и вложенный в него символ). Таким образом, первый и второй символ находятся на одном уровне.

Вопрос:
как из третьего символа-потомка SimpleButton, обратиться к методам второго символа-потомка MovieClip?

Код класса первого символа:
Код AS3:
package {
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.events.Event;
 
	public class AlterBtn extends MovieClip {
 
		private var pressed:Boolean
		public var win:Win;
 
		public function AlterBtn () {
			buttonMode = true
			useHandCursor = true
			pressed = false
			stop ();
			addEventListener (MouseEvent.MOUSE_DOWN, downHandler);
			addEventListener (Event.ENTER_FRAME, checkPressed)
		}
 
		private function downHandler (e:MouseEvent):void {
			pressed = true
			win = new Win
			win.x = 90
			win.y = 162.6
			parent.addChild (win)
			gotoAndStop ("PRESS")
		}
 
		private function checkPressed (e:Event):void {
			if (pressed == true) {
			buttonMode = false
			useHandCursor = false
			removeEventListener (MouseEvent.MOUSE_DOWN, downHandler)
			}
		}
 	}
}
Код второго класса:
Код AS3:
package {
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class Win extends MovieClip {
 
		public function Win () {
		}
 
		public function makeRew ():void {
			addEventListener (Event.ENTER_FRAME, goBack);
		}
 
		private function goBack (e:Event):void {
			prevFrame ();
			if (currentFrame == 1) {
				removeEventListener (Event.ENTER_FRAME, goBack)
			}
		}
	}
}
Код третьего класса:
Код AS3:
package {
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	import flash.events.Event;
 
	public class CloseBtn extends SimpleButton {
 
		public function CloseBtn () {
			addEventListener (MouseEvent.MOUSE_DOWN, closeWin)
		}
 
		private function closeWin (e:MouseEvent):void {
 
//	parent.makeRew () не работает
 
		}
	}
}
При таком коде вылазит ошибка: Обращение к возможно неопределенному методу.
Как правильно вызвать метод makeRew () из экземпляра класса Win?

Старый 26.09.2009, 22:58
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 2  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
1. не проверяйте переменные типа Boolean на равенство true | false они все равно ничему другому не могут быть равны. При дефолтных настройках флексового компилятора такой код не скомпилируется с предупреждением.
2. Вы можете каcтовать родителя к нужному типу, например: (parent as Win).makeRew(). Но это нехорошая практика - правильно в таком случае либо послать событие (на которое родитель, как и кто-либо другой могут подписаться), либо просто передать экземпляру класса CloseBtn ссылку на функцию, которую нужно вызвать. Второй вариант немного более экономичен по затратам, но первый более "ожидаемый" подход. Т.е. если кто-то будет использовать ваш класс, то в первую очередь будет искать возможность подписаться на событие, которое происходит когда в нем случается closeWin.
__________________
Hell is the possibility of sanity

Старый 27.09.2009, 16:06
Furinax вне форума Посмотреть профиль Отправить личное сообщение для Furinax Найти все сообщения от Furinax
  № 3  
Ответить с цитированием
Furinax
[+1 02.09.15]

Регистрация: Mar 2009
Адрес: Moscow
Сообщений: 469
Цитата:
Сообщение от wvxvw Посмотреть сообщение
не проверяйте переменные типа Boolean на равенство true | false они все равно ничему другому не могут быть равны. При дефолтных настройках флексового компилятора такой код не скомпилируется с предупреждением.
ну я пока что малоопытен, поэтому пишу в коде все напрямую, чтобы потом самому разобраться. А во флексе пока что даже ни одной строчки кода не написал.

Большое спасибо за ваш совет, теперь мой скрипт работает. Решил воспользоваться первым подходом, так как кроме меня кодом никто пользоваться не будет. Но когда все доделаю и буду модернизировать, обязательно перепишу все по второму подходу.

Добавлено через 16 часов 45 минут
Цитата:
Сообщение от wvxvw Посмотреть сообщение
Вы можете каcтовать родителя к нужному типу, например: (parent as Win).makeRew(). Но это нехорошая практика - правильно в таком случае либо послать событие (на которое родитель, как и кто-либо другой могут подписаться), либо просто передать экземпляру класса CloseBtn ссылку на функцию, которую нужно вызвать. Второй вариант немного более экономичен по затратам, но первый более "ожидаемый" подход. Т.е. если кто-то будет использовать ваш класс, то в первую очередь будет искать возможность подписаться на событие, которое происходит когда в нем случается closeWin.
но ведь чтобы зарегистрировать пользовательское событие нужно, чтобы класс расширял EventDispatcher, а он уже расширяет SimpleButton для того, чтобы слинковаться с символом мувиклипа. Каким образом реализовать возможность посылать собития?

До этого я писал код только в кадрах временной шкалы и обращался к экземплярам символов через instance name. Но щас решил все делать во внешних файлах и не совсем представляю, как один символ, линкованный с классом, может обращаться к другому симолу, линкованному с внешним файлом. Единственное че получается это первый написанный вами подход, но применить его получается не во всех случаях. Например AlterBtn находится на сцене, а CloseBtn вложен в Win. Через CloseBtn я могу обратиться к Win через parent, а вот как обратиться к AlterBtn?

Старый 27.09.2009, 16:24
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 4  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
SimpleButton уже расширяет EventDispatcher.
Объекты помещенные на сцену в ИДЕ - вобщем-то практически такие же, как и те, которые вы создаете используя возможности языка. Единственное, добираться до них действительно неудобно. Я так представляю, что после получения ссылки на root можно используя getChildAt() найти нужный объект, но вообще лучше все создавать либо в коде, либо уже все вытаскивать на таймлайн.
__________________
Hell is the possibility of sanity

Старый 27.09.2009, 17:35
Furinax вне форума Посмотреть профиль Отправить личное сообщение для Furinax Найти все сообщения от Furinax
  № 5  
Ответить с цитированием
Furinax
[+1 02.09.15]

Регистрация: Mar 2009
Адрес: Moscow
Сообщений: 469
И мой, надеюсь последний, вопрос.
Я зарегил событие в CloseBtn следующим образом, вот код:
Код AS3:
package {
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	import flash.events.Event;
 
	public class CloseBtn extends SimpleButton {
		public static const WIN_CLOSED:String = "windowClosed";
 
		public function CloseBtn () {
			addEventListener (MouseEvent.MOUSE_DOWN, closeWin)
		}
 
		private function closeWin (e:MouseEvent):void {
			(parent as Win).makeRew()
			dispatchEvent (new Event (CloseBtn.WIN_CLOSED));
		}
	}
}
Затем зарегистрировал в AlterBtn приёмник, вот код:
Код AS3:
public class AlterBtn extends MovieClip {
 
		private var goBackStarted:Boolean;
		public var win:Win;
 
		public function AlterBtn () {
			buttonMode = true;
			useHandCursor = true;
			stop ();
			addEventListener (MouseEvent.MOUSE_DOWN, downHandler);
			addEventListener (CloseBtn.WIN_CLOSED, closeHandler);
		}
 
 
		private function downHandler (e:MouseEvent):void {
			gotoAndStop ("PRESS");
			mouseEnabled = false;
			win = new Win;
			win.x = 90;
			win.y = 162.6;
			parent.addChild (win);
		}
 
 
		private function closeHandler (e:Event) {
			mouseEnabled = true;
		}
 
	 }
}
Но AlterBtn никак не реагирует на событие. И самое обидное что все компилируется без ошибки. Что я делаю не правильно?

Старый 27.09.2009, 18:43
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 6  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
в твоем раскладе AlterBtn никак не сможет сам выловить событие
во-первых, потому что оно должно быть для этого всплывающим
и во вторых потому что CloseBtn лежит в соседней ветке дерева дисплейОбжектов и событие от него в AlterBtn никак не попадет..
можно подписаться у общего предка и вещать всплывающие событие
Код AS3:
public class AlterBtn extends MovieClip {
 
	public function AlterBtn () 
	{
		root.addEventListener (CloseBtn.WIN_CLOSED, closeHandler);
	}
 
	private function closeHandler(e:Event) 
	{
		trace( "AlterBtn.closeHandler > e : " + e );
 
	}
}
Код AS3:
public class CloseBtn extends SimpleButton {
	public static const WIN_CLOSED:String = "windowClosed";
 
	public function CloseBtn () 
	{
		addEventListener (MouseEvent.MOUSE_DOWN, closeWin)
	}
 
	private function closeWin (e:MouseEvent):void 
	{
		dispatchEvent (new Event (CloseBtn.WIN_CLOSED, true));
	}
}

можно подписываться в AlterBtn непосредственно у CloseBtn, но для этого тот должен иметь ссылку на него

можно вещать в кнопке не от ее имени, а от имени какого-то статического диспатчера, который 'виден' отовсюду, ну и слушать соответственно его а не кнопку

в общем, вариантов есть.., сказать что какой-то однозначно предпочтительнее, имхо, нельзя, в каждом конкретном случае все по разному

Старый 27.09.2009, 19:13
Furinax вне форума Посмотреть профиль Отправить личное сообщение для Furinax Найти все сообщения от Furinax
  № 7  
Ответить с цитированием
Furinax
[+1 02.09.15]

Регистрация: Mar 2009
Адрес: Moscow
Сообщений: 469
ух ты, работает!

Создать новую тему Ответ Часовой пояс GMT +4, время: 18:58.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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