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

Вернуться   Форум Flasher.ru > Блоги > ps_spectre

Рейтинг: 5.00. Голосов: 5.

Создание библиотеки ресурсов (swc) с помощью compc

Запись от ps_spectre размещена 02.02.2011 в 20:03

Итак, у нас стоит задача создать библиотеку (swc) ресурсов (картинки, звук), не используя при этом FlashIDE.

Для этого нам понадобится FlexSDK в котором есть компилятор компонентов compc, вот его мы и будем использовать.

Рассмотрим пример:
у нас есть набор файлов Image 1.png .. Image N.png, Sound1.mp3 .. SoundN.mp3, мы хотим их включить в свик файл, чтобы потом использовать в проекте.
Первый вариант — мы можем написать класс, который будет хранить в себе ссылки на связанные классы с ресурсами.

Создаем класс GraphicAssets.as (класс находится в том же каталоге где и картинки)
Код AS3:
package 
{
	public class GraphicAssets
	{
		[Embed(source="image 1.png")]
		public static var Image1:Class;
 
		[Embed(source="image 2.png")]
		public static var Image2:Class;
 
		[Embed(source="image 3.png")]
		public static var Image3:Class;
 
		....
 
		[Embed(source="image N.png")]
		public static var ImageN:Class;
 
		public function GraphicAssets() { }
	}
}
теперь скомпилируем с помощью compc(будем считать что в переменных окружения (path) операционной системы указан путь до flexSDK/bin)
(в Windows7 это можно сделать так: start -> Control Panel -> System -> Advanced System Settings -> Advanced -> Environment Variables -> system variables -- Path, дописываем туда путь, например c:\flexSDK\flex_sdk_4.5.0.18623\bin;)

(мы в каталоге где Image1.png .. ImageN.png и созданный только что класс GraphicAssets.as)
комилируем, вызывая компилятор и передавая параметры:
Код:
compc -sp . -ic GraphicAssets -output lib.swc
-sp указывает compiler.source-path (откуда начинать искать классы), указываем текущий каталог . (иначе класс GraphicAssets будет не найден, т.к. компилятор не знает где он)
-ic какие классы включать (включаем наш созданный GraphicAssets.as, указывая только его имя)
-output lib.swc имя библиотеки, которую получим после компиляции.

на выходе получаем swc файл с нашими картинками

использовать в коде (после того как залинковали библиотеку)
Код AS3:
 
var b1:Bitmap = new GraphicAssets.Image1();
addChild(b1);
var b2:Bitmap = new GraphicAssets.Image2();
b2.x = b2.y = 100;
addChild(b2);
	....
или так 
var b3:Bitmap = new GraphicAssets_Image3();
Если глянуть во внутрь библиотеки там есть классы GraphicAssets_Image1()..GraphicAssets_ImageN();

откуда взялся GaphicAssets_ImageX ?

Рассмотрим процесс компиляции более подробно.
Во время компиляции флекс автоматически разворачивает конструкции подобного вида:

Код AS3:
[Embed(source="image N.png")]
		public static var ImageN:Class;
в отдельный класс: (это можно посмотреть с помощью указания ключа компилятору -keep, тогда создастся каталог generated, в котором будет список автоматически созданных классов)

generated/Graphics_Image1.as
Код AS3:
package 
{
import mx.core.BitmapAsset;
 
[ExcludeClass]
[Embed(_resolvedSource="%PATH%/image 1.png", _column="3", source="image 1.png", exportSymbol="GraphicAssets_Image1", _line="5", _pathsep="true", _file="%PATH%/GraphicAssets.as")]
 
public class GraphicAssets_Image1 extends mx.core.BitmapAsset 
{
    public function GraphicAssets_Image1() 
    { 
	    super(); 
    }
}
}
и заменяет наш класс на
Код AS3:
    public class Graphics 
    {
 
        public static var Image1:Class = Graphics_Image1;
        public static var Image2:Class = Graphics_Image2;
        public static var Image3:Class = Graphics_Image3;
        public static var Image4:Class = Graphics_Image4;
 
        public function Graphics()
        {            
        }
    }
Как следствие, у нас появляется легкая избыточность в нашей библиотеке.
Раз флекс создает классы GraphicAssets_Image1 .. GraphicAssets_ImageN , то зачем нам в коде свой класс, который хранит ссылки на эти классы?
К тому же, при автоматической генерации классов флекс наследует их от своего класса mx.core.BitmapAsset, а не напрямую от flash.display.Bitmap
отсюда следует тот факт, что при компиляции библиотеки попадают с десяток лишних классов из флекс_фреймворка (mx.core.*, mx.utils.*) (8 классов, если быть точным)
тоже самое звук он наследует от mx.core.SoundAsset

Отсюда мы переходим к другому варианту

На каждый файл ресурса (.png, .jpg, .mp3) будем создавать по отдельному классу:

Image_1Png.as
Код AS3:
package  
{ 
	import flash.display.Bitmap
	[Embed(source="image 1.png")]
	public class Image_1Png extends Bitmap
	{
		public function Image_1Png()
		{
		}
	}
}
или так:

Image_1Png.as
Код AS3:
package  
{ 
	import flash.display.BitmapData
	[Embed(source="image 2.png")]
	public class Image_2Png extends BitmapData
	{
		public function Image_2Png(width:Number=0,height:Number=0)
		{
			super(width,height);
		}
	}
}
картинки можно наследовать от BitmapData

на звуковые файлы точно так же создаем свой класс:

Sound1Mp3.as
Код AS3:
package  
{ 
	import flash.media.Sound;
	[Embed(source="sound1.mp3")]
	public class Sound1Mp3 extends Sound
	{
		public function Sound1Mp3()
		{
		}
	}
}
и т.д.

Плюс следует в том, что флекс не будет пихать свои классы, т.к. мы явно наследуемся от родных классов (Bitmap, Sound, BitmapData)
И у нас не будет общего класса со всеми ссылками. (может это и не плюс)
Так же если у нас есть подкаталоги, то мы можем явно писать package

Теперь нам осталось это все добро с компилировать. (сейчас у нас кол-во ресурсов == кол-во классов)

Есть несколько вариантов
в командной строке с ключем -ic перечисляем все наши классы, или создать конфиг файл в котором перечислим их.

Например создаем файл config.xml
Код:
<?xml version="1.0"?>
<flex-config>	
<compiler>
<source-path>
	<path-element>.</path-element>       	
</source-path>
</compiler>
	<include-classes>
		<class>Image_1Png</class>
		..
		<class>Image_NPng</class>
		..
		<class>Sound1Mp3</class>
		..
		<class>SoundNMp3</class>		
	</include-classes>
</flex-config>

<compiler>
	<source-path>
		<path-element>.</path-element>       	
	</source-path>
</compiler>
alias: -sp . для комадной строки (compiler.source-path)

в секции <include-classes> явно перечисляем классы, которые хотим включить (у нас на один ресурс -- один класс)
алиас: -ic

(package явно надо указывать
если у нас есть папка assets в ней папка icons, в ней класс Icon1.as у которого package assets.icons { }, тогда
<class>assets.icons.Icon1</class>
)


другой вариант, мы можем указать компилятору путь к исходникам, которые надо обазятельно включить (<include-sources>) (полностью включить)

config.xml
Код:
<?xml version="1.0"?>
<flex-config>	
	<compiler>
		<source-path>
			<path-element>.</path-element>       	
		</source-path>
	</compiler>

	<include-sources>      
      <path-element>.</path-element>
   </include-sources>
</flex-config>
При таком варианте нам явно не надо перечислять классы, которые будем включать.
Работает это следущим образом, флекс видить путь откуда начинать искать (в<include-sources>, мы там указали текущий путь , где мы находимся) и начинает включать все классы которые найдет. (если есть лишнии классы, которые не мы создавали для наших ресурсов, то он и их подхватит, все классы которые найдет включит)

Выбираем подходящий вариант и компилируем следущим образом
Код:
compc -load-config+=config.xml -output lib.swc

-load-config
указывает на то, какой конфиг подгружать , += надо для того, чтобы стандартный конфиг файл флекс загрузил (находится в %flexsdk_path%/frameworks/flex-config.xml)

на выходе получаем swc файл в котором зашиты наши ресурсы.

Использовать в коде стандартно, для любого swc:

var bd:Bitmap = new Image_1Png();


Компиляция из командной строки без конфиг файла
Код:
compc -sp . -is . -output lib.swc
-is . это алиас
Код:
<include-sources>      
    <path-element>.</path-element>
</include-sources>


Точно так же мы можем скомпилировать не только наши ресурсы, а, например, Flixel: (2д блитинг движок)
качаем исходники, распаковуем в папку flixel, заходим в нее (в ней будет каталог org -flixel - *.as)
(или git clone git://github.com/AdamAtomic/flixel.git)

c:\flixel>compc -sp . -is . -output flixel.swc

если распаковали исходники, но в папку не зашли, тогда указываем не текущий путь откуда начинать, а название каталога

(если мы в текущей папке, в которой есть другие, например flashPunk, flixel, ... )
c:\>compc -sp flixel -is flixel -output flixel.swc
так же путь можно абсолютный задавать.

Более детально compc -help
------------------

Мы рассмотрели два основных подхода создания библиотеки с картинками/звуками с помощью compc.

Но такие задачи всегда лучше автоматизировать.
Например использовать java ant + flex ant.
Или написать свой скрипт, который будет генерить все это добро.

Я написал небольшой скрипт на питоне (gswc.py), который работает следущим образом:

начиная с текущего каталога ищет файлы .png, .jpg., .mp3 , создает рядом такой же файл .as с классом куда внедряет ресурс (второй подход выше рассмотренный)
подкаталоги учитываются (в подкаталогах создается класс , в котором указан package subfolder1.subsubfolder1... )
потом создается config.xml куда перечисляются все созданные классы, вызывается compc которым компилит все это добро, а дальше подчищаем за собой.

для правильной работы скрипта необходимо чтобы путь в системных переменных был указан до флекс_сдк/bin, где лежит compc. (если из cmd написать compc в любом месте и это работает, то путь уже прописан)
или в исходниках указать абсолютный путь где лежит compc.
я у себя положил скрипт в тот же каталог где compc (флекс/бин) , и вызываю с любого места набирая имя gswc.py.

дополнительные параметры:
-a : не добавлять расширения в имя класса (Image1PNG.as vs Image1.as)
-b : вставлять картинки как битмапДату
-o <swc_name.swc> : имя библиотеки, по-дефолту assetLibrary.swc
-t : не подчищать за собой временные файлы

обычный вызов: gswc.py
вызов с параметрами: gswc.py -a -b -o lib.swc -t

проверялось на питоне 2.6 и flex_sdk 4.5.

p.s. не забываем, что swc это архив, в котором .swf + catalog.xml.

p.p.s. во вложение картинка, которая показывает результат.
Изображения
Тип файла: jpg visual.jpg (51.8 Кб, 1164 просмотров)
Вложения
Тип файла: zip gswc.zip (1.7 Кб, 222 просмотров)
Размещено в Mxmlc and compc
Комментарии 8 Отправить другу ссылку на эту запись
Всего комментариев 8

Комментарии

Старый 02.02.2011 23:50 dimarik вне форума
dimarik
 
Аватар для dimarik
Хорошая, основательная статья. Можно понять куда шагать дальше. Спасибо.

У нас применяется другой подход. Ресурсы подгружаются по мере необходимости. Согласитесь, иметь флешку в 2 гига с лишним - это моветон.
Старый 03.02.2011 00:01 gr_crd вне форума
gr_crd
 
Аватар для gr_crd
Отличный материал! печатать и вникать)
Давно было желание попрактиковаться в создании swc-библиотек, но думал, что без Flash IDE не обойтись.
Старый 03.02.2011 00:49 LOS2008 вне форума
LOS2008
Цитата:
но думал, что без Flash IDE не обойтись
Для FlashDevelop есть плагин. SWC делается одним движением пальца.
Старый 03.02.2011 02:25 avilov вне форума
avilov
http://sourceforge.net/projects/exportswc/

Скачать и закинуть его C:\Program Files\FlashDevelop\Plugins , и там запустить , рестартануть FD и в панели появится кнопка , сразу генерит swc и asdoc.
Старый 03.02.2011 02:34 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Это прекрасно, что есть такие плагины. Но иногда докопаться до сути вещей куда приятнее, чем делать всё одной кнопкой.
Статью ещё не читал, но заранее спасибо. Тема интересная.
Старый 03.02.2011 02:36 Котяра вне форума
Котяра
 
Аватар для Котяра
Другое дело что flashIDE имеет намного больше возможностей по сжатию конечного материала.
Я для этих целей использую jsfl ибо обходиться полностью без IDE нет особого смысла - он всё равно нужен.
Но за статью спасибо.
Старый 03.02.2011 02:41 iNils вне форума
iNils
 
Аватар для iNils
Плагин это конечно хорошо, но статья про создание swc вне Flash IDE, а не про создание в FD. Хотя пусть даже и в FD, но все равно познавательно, тем более так подробно. Спасибо!
PS. Хотелось бы, чтобы еще был пример с внедрением шрифтов.
Старый 03.02.2011 13:17 ps_spectre вне форума
ps_spectre
 
Аватар для ps_spectre
Спасибо всем за столь хорошие отзывы!
Это моя первая статья.

FlashIDE очень сильно рулит, никто не спорит (раньше я этого не понимал), но не всегда целесообразно ее использовать с учетом того, что она стоит денег.

iNils, шрифты я как правило внедряю в сам проект, а не через библиотеку. Но можно и через библиотеку.
например так

MyFontContainer.as
Код AS3:
package
{
	import flash.text.Font
	public class MyFontContainer extends Font
	{
 
			[Embed(source = "Retroville NC.ttf", 
				fontName = "MyMainFont",				
				unicodeRange = "U+0041-U+005A,U+0061-U+007A,U+0030-U+0039,U+002E-U+002E",
				embedAsCFF = false)
			]                    	
			public static var MyMainFontClass:Class;
 
			public function MyFontContainer() 
			{
			}
		}
}
компилируем (находясь в текущем каталоге где наш файл .as и шрифт .ttf)

Код:
compc -sp . -ic MyFontContainer -output fontLib.swc
в библиотеке получаем кучу flex-мусора

в проекте использовать так:
Код AS3:
var fc:MyFontContainer = new MyFontContainer(); //надо сделать, иначе флекс не подтянет
txt = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.embedFonts = true; //не забываем самую главную фишку
txt.defaultTextFormat = new TextFormat("MyMainFont", 18); //имя фонта которое указываем при Embed
в результате подтянется в проект сам шрифт и всего 2 mx.core.* класса. (IFlexAsset, ICoreAsset)

dimarik, да, когда много ресурсов, я тоже за то, чтобы подтягивать динамически. )
Но ситуации разные бывают, предположим мы делаем игру небольшую с растровой графикой, одно из самых главных условий распространения -- это распространять одним swf файлом. Тут нам все равно понадобится включить все ресурсы в один файл.

2All, плагины это хорошо, это правильно, но они тот же самый compc и используют, я в конце статьи замечание сделал, что такие процессы надо автоматизировать (flex ant, plugins, custom scripts, etc... ).
 

 


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


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