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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 06.05.2018, 13:11
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 21  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
как мне вернуть битмапку из метода getLoadedAsset, когда она становится доступной только в методе completeHandler?
Ответ содержится в вопросе. Никак.

Непонятно, зачем использовать асинхронный Loader в AIR-приложении для чтения файлов с диска. Есть же FileStream.
__________________
Reality.getBounds(this);

Старый 06.05.2018, 15:27
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 22  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Да, я так и думал Мне тут страницей выше рекомендовали Loader, т.к. FileStream, мол, больше для потокового аудио и видео. Ща попробуем, спасибо.

Добавлено через 46 минут
Вот до такого доковырялся сам.

Код AS3:
public function getLoadedAsset(fileID: String) : Bitmap // Загружает и возвращает asset
		{
			var file: File = File.applicationDirectory.resolvePath("assets" + File.separator + "backgrounds" + File.separator + fileID + PNG);
			var filestream: FileStream = new FileStream;
			var bytes: ByteArray = new ByteArray;
			var data: BitmapData = new BitmapData(800,600);
			var rect: Rectangle = new Rectangle(0, 0, 800, 600);
 
			trace(file.url);
 
			filestream.open(file, FileMode.READ);
			filestream.position = 0;
			filestream.readBytes(bytes);
 
			data.setPixels(rect, bytes);
 
			var result: Bitmap = new Bitmap(data);
			trace (result);
 
			return result;			
		}
Проблемных точек три:
Во-первых, периодически получаю ошибку [Fault] exception, information=Error: Error #2030: End of file was encountered.
Во-вторых, надо как-то заранее получать разрешение загружаемого файла. Я пока для теста написал в лоб 800*600, то это не дело.
Наконец, даже если всё получается без ошибок, то на экран какая-то каша выходит

И вообще, в правильном направлении двигаюсь?
__________________
Не сломано - не чини!


Последний раз редактировалось Appleman; 06.05.2018 в 16:15.
Старый 06.05.2018, 18:41
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 23  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
1. Стрим надо закрывать после чтения методом close();
2. B setPixels() нужно передавать пиксели, как ни странно, а не файл. Подсказка: файл изображения содержит еще кучу данных кроме собственно пикселей, а собственно "пиксели" в файле могут содержаться в сжатой архиватором форме, а то и вообще быть "вычисляемыми" в процессе декодирования изображения кодеком.
Резюме: нужен декодер, точнее декодерЫ основных форматов (либо один, если все изображения будут в одном формате). Годный декодер примет файл и выдаст битмапдату ее собственного размера синхронно. Насколько я помню, нативный набор AS3 предоставляет только асинхронный декодер в виде загрузки байтЭррей в Лоадер)) круг замкнулся.
Ищи кастомный декодер.
Ну, например https://github.com/furusystems/Aishi.../PNGDecoder.as
__________________
Reality.getBounds(this);

Старый 06.05.2018, 19:21
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 24  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Хм... А стоит ли игра свеч, если есть нативный loader, который на раз-два всё загружает и отдаёт? В чём его такое подавляющее преимущество? Уже придумался рабочий вариант - при заходе в локацию сразу загружать пачку картинок от этой локации и с данными персонажами (и первое, и второе известно, файлов не должно быть много), забивая BitmapDat-ы в Dictionary, а потом просто отдавать по идентификатору. А при смене локации - убивать старые и заполнять новые.
__________________
Не сломано - не чини!

Старый 06.05.2018, 19:38
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 25  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Это уж как вам нравится) Мое дело отвечать на поставленные вопросы)
__________________
Reality.getBounds(this);

Старый 06.05.2018, 23:26
ZergMaster вне форума Посмотреть профиль Отправить личное сообщение для ZergMaster Найти все сообщения от ZergMaster
  № 26  
Ответить с цитированием
ZergMaster
 
Аватар для ZergMaster

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
Цитата:
Сообщение от Appleman Посмотреть сообщение
Друзья!

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

Код AS3:
public function getLoadedAsset(fileID: String) : Bitmap 
		{
			var file: File = File.applicationDirectory.resolvePath("assets" + File.separator + "backgrounds" + File.separator + fileID + PNG);
			var request: URLRequest = new URLRequest(file.url);
 
			trace(file.url); // Показывает правильный путь
 
			var loader: Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
			loader.load(request);
			trace(loader.content); // null			
		}
 
		private function completeHandler(e: Event) : void
		{
			var loader: Loader = Loader(e.target.loader);
			var image: Bitmap = Bitmap(loader.content);
			trace(image); // [object Bitmap]
		}
То есть как мне вернуть битмапку из метода getLoadedAsset, когда она становится доступной только в методе completeHandler?
Не совсем православный, но самый очевидный и рабочий вариант - через функцию-callback
Код AS3:
public function getLoadedAsset(fileID: String, callback:Function) : void
		{
			var file: File = File.applicationDirectory.resolvePath("assets" + File.separator + "backgrounds" + File.separator + fileID + PNG);
			var request: URLRequest = new URLRequest(file.url);
 
			var loader: Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void 
                            {
                                 var loader: Loader = Loader(e.target.loader);
                                 var image: Bitmap = Bitmap(loader.content);
                                 callback(image);
                            });
			loader.load(request);		
		}
__________________
while(live()) { hope(); }

Старый 07.05.2018, 00:05
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 27  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
ZergMaster, спасибо. Даже не знал, что так можно. А почему не православный?

Wolsh, я тогда с позволения поставлю вопрос, почему ты ратуешь на использование FileStream-а для AIR как альтернативы Loader-у. Кстати, я данную ветку сначала перечитал, вспомнил твою идею не выкладывать графические файлы как есть, а закатать их в один не-пойми-какой-снаружи файл, и оттуда при загрузке уже в программе нарезать картинки. С точки зрения такого подхода, есть какие-то аргументы "за" и "против" каждого из вариантов?
__________________
Не сломано - не чини!

Старый 07.05.2018, 07:09
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 28  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
FileStream умеет читать из открытого файла фрагменты "от такого-то байта до такого-то".
Loader, конечно же, так не умеет. Если будет нужна какая-то одна иконка, лоадером придется грузить весь файл и только потом выискивать в нем нужный кусочек.
В любом случае асинхронная загрузка требует сложного менеджмента: нужно постоянно точно знать, что это сейчас пришло в лоадер, именно потому, что последовательность получения файлов не совпадает с последовательностью запросов (асинхрон). Так же и вариант ZergMaster, использующий безымянного беса — только делает вид, что возвращает картинку заказчику. На самом-то деле он возвращает ее не в место вызова и уж конечно не сразу после вызова, а в еще одну функцию, колбэк-функцию. И эта колбэк-функция понятия не имеет, что за файл в нее свалился: если у "заказчика картинок" будет один такой приемный пункт, а картинок заказано несколько, то он точно так же не будет знать, в каком порядке они поступят в приемник (колбэк), то есть буквально про каждую картинку будет неизвестно, что это такое, что за файл. Асинхронность никуда не делась (она и не может деться, если используется асинхронная загрузка), проблема осталась такой же, как и была, только перенесена с больной головы на здоровую. Если можно использовать только лоадер (например, если файлы нужно забирать с сервера), то конечно правильный подход твой — загрузить и рассортировать всю пачку для текущего уровня до его активации. Я бы по возможности и при синхронной загрузке делал так же, но это уже зависит от задачи, от особенностей проекта. Синхрон нравится мне тем, что ты получаешь файл тут же, где запросил и точно знаешь что запросил и что с ним делать, не нужно городить систему надсмотрщиков и сортировщиков.

Еще раз: выбор подхода зависит от особенностей проекта. Есть например такое понятие в UX, как ожидаемая задержка. То есть пользователь, взаимодействуя с программой, в какие-то моменты ДОПУСКАЕТ, что программа будет выполнять действие, не реагируя на него — например, при переходе между уровнями игры или при открытии дополнительного окна (инвентаря например). В другие моменты такая задержка пугала и раздражала бы, вызывая ощущение что программа "виснет" и "тормозит". Загружать иконки предметов при открытии Инвентаря — это нормально, но совершенно неприемлемо подгружать изображение пули в момент выстрела)) Надо учитывать эти моменты, решая что когда грузить — и то лишь в том случае, когда загрузить все заранее невозможно (например, просто нет такого понятия как элементы уровня: на любом уровне может понадобиться любой "предмет" игры, неизвестно заранее какой, а все ассеты весят столько, что памяти для нормальной работы не хватит).
__________________
Reality.getBounds(this);


Последний раз редактировалось Wolsh; 07.05.2018 в 07:40.
Старый 07.05.2018, 12:40
ZergMaster вне форума Посмотреть профиль Отправить личное сообщение для ZergMaster Найти все сообщения от ZergMaster
  № 29  
Ответить с цитированием
ZergMaster
 
Аватар для ZergMaster

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
Цитата:
Сообщение от Wolsh Посмотреть сообщение
И эта колбэк-функция понятия не имеет, что за файл в нее свалился: если у "заказчика картинок" будет один такой приемный пункт, а картинок заказано несколько, то он точно так же не будет знать, в каком порядке они поступят в приемник (колбэк), то есть буквально про каждую картинку будет неизвестно, что это такое, что за файл.
да, поэтому на этот случай правильней было бы, конечно, сделать так
Код AS3:
callback(fileID, image);
Цитата:
А почему не православный?
Потому что безымянная функция, над которой мы не имеем никакой власти. Если ими пользоваться бездумно, то начинает происходить всякая чертовщина. Иногда её удобно использовать, если компактно и пока никто не видит. Но если не чувствуешь в себе силы джедая, то правильней оформлять callback через private переменную, тогда и от безымянной функции можно избавиться.
__________________
while(live()) { hope(); }

Старый 08.05.2018, 00:57
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 30  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Пока забил болт и Loader-ом сделал, как и планировал: при выборе персонажа - забиваем в Dictionary графику для персонажа, при выборе локации - картинки от данной локации и т.п.

У меня ещё тут по ходу мелкий вопрос возник. Я правильно понимаю, что после того, как каждый из Loader-ов закончил работу, с него нужно руками снять слушатели событий? Почему-то в хелпе Adobe-овском об этом ни слова ни в тексте, ни в примерах.

Плюс есть ещё пара вопросов крупных, пойду с ними в тему про MVC.
__________________
Не сломано - не чини!

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

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

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


 


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


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