Январь 2011

Руководство по actionscript. часть 1, стр. 030

Virtual zoo |- src |- zoo |- VirtualZoo. as

Теперь, когда у нас есть описание пакета, добавим в него класс VirtualZoo.

Описание класса

Для создания нового класса используется описание класса, как показано в следующем обобщенном коде:

class Идентификатор { }

Описание класса начинается с ключевого слова class, за которым указывается имя класса (в приведенном коде имя класса заменено выражением Идентифика тор). Термин «идентификатор» употребляется в значении «имя». Идентификаторы не должны содержать пробелы или тире и не могут начинаться с цифры. Каждое новое слово

в имени класса принято записывать с прописной буквы, как, например, в именах классов Date или Text Field (TextField — это предопределенный класс среды выполнения Flash, экземпляры которого представляют текст, отображаемый на экране).

Фигурные скобки ({ и }), следующие за выражением Идентификатор в предыдущем описании класса, являются оператором блока, точно так же, как и в примере описания пакета. Оператор блока описания класса называется блоком класса или иногда телом класса. Блок класса содержит директивы, описывающие характеристики и поведение класса и его экземпляров.

В следующем примере приводится описание класса VirtualZoo, являющегося основным классом для нашей игры-симулятора. Описание класса помещено в тело пакета, который описан в файле VirtualZoo. as:

package zoo { class VirtualZoo { }

}

Поскольку описание класса VirtualZoo находится в пакете zoo, полным именем класса (называемым полностью определенным именем класса) является zoo. VirtualZoo. Тем не менее в тексте мы будем использовать сокращенное, или неполное, имя класса — VirtualZoo.

Теперь, когда мы описали основной класс нашей программы, создадим еще один класс — Virtual Pet. С его помощью мы создадим объекты, представляющие зверей в зоопарке.

Как и в случае с классом VirtualZoo, мы поместим код класса VirtualPet впакет zoo, сохранив его в собственном файле VirtualPet. as внутри папки zoo. Исходный код из файла VirtualPet. as выглядит следующим образом:

package zoo { class VirtualPet { }

}

Обратите внимание, что описание пакета может размещаться в нескольких исходных файлах. И хотя классы VirtualZoo и VirtualPet физически хранятся в разных AS-файлах, они принадлежат одному пакету zoo. Любой класс, описание которого принадлежит телу пакета с именем zoo, считается частью этого пакета независимо от имени файла размещения. В отличие же от описания пакета, описание класса не может находиться в нескольких файлах и должно полностью размещаться в одном файле.

Руководство по actionscript. часть 1, стр. 031

Модификаторы управления доступом для классов. По умолчанию обращение к классу, входящему в состав определенного пакета, может осуществляться только из кода, принадлежащего тому же пакету. Чтобы класс был доступен для использования за пределами пакета, которому он принадлежит, мы должны описать этот класс с помощью атрибута public. Вообще говоря, атрибуты определяют порядок использования класса и его экземпляров в программе. Атрибуты указываются перед ключевым словом class в описании класса, как показано в приведенном ниже общем примере:

атрибут class ИдентификаторКласса { }

Например, чтобы добавить атрибут public к классу VirtualPet, нужно использовать следующий код:

package zoo { public class VirtualPet { }

}

Однако применение атрибута public в случае с классом VirtualPet необязательно, поскольку класс VirtualPet используется только классом VirtualZoo, а тот, в свою очередь, может обращаться к классу VirtualPet (классы, принадлежащие одному пакету, могут всегда обращаться друг к другу). Таким образом, мы можем вернуться к исходному описанию класса VirtualPet, которое косвенным образом позволяет использовать этот класс только внутри пакета zoo:

package zoo { class VirtualPet { }

}

Если мы хотим явно указать, что класс VirtualPet может быть использован только внутри пакета zoo, то в описание класса необходимо добавить атрибут internal, как показано ниже:

package zoo { internal class VirtualPet { }

}

Класс, описанный с помощью атрибута internal, может быть использован только внутри пакета, которому он принадлежит. Другим словами, описание класса с помощью атрибута internal совершенно не отличается от описания класса без использования каких-либо модификаторов управления доступом. Атрибут internal просто служит для однозначного толкования замысла программиста.

Руководство по actionscript. часть 1, стр. 032

Атрибуты internal и public называются модификаторами управления доступом, поскольку управляют порядком доступа к областям внутри программы, в которых допускается использовать данный класс (к ним разрешен доступ данного класса).

В отличие от класса VirtualPet, класс VirtualZoo должен быть определен с помощью атрибута public, поскольку он является основным классом приложения.

Ш|_ I Компиляторы, разработанные корпорацией Adobe, требуют, чтобы основной класс при-| ложен ия был определен с помощью атрибута public.

Следующий код представляет обновленное описание класса VirtualZoo, содержащее обязательный атрибут public:

package zoo { public class VirtualZoo { }

}

Краткий обзор приложения «Зоопарк»

В настоящий момент наша игра состоит из двух классов: VirtualZoo (основной класс) и VirtualPet (класс, представляющий зверей в виртуальном зоопарке). Оба класса принадлежат пакету zoo и хранятся в виде обычных текстовых файлов с именами VirtualZoo. as и VirtualPet. as соответственно.

Согласно требованию, предъявляемому компиляторами языка ActionScript корпорации Adobe, класс VirtualZoo описан с использованием атрибута public, поскольку является основным классом приложения. В отличие от класса VirtualZoo, класс VirtualPet может быть использован только внутри пакета zoo, поскольку описан с помощью атрибута internal.

В примере листинга 1.1 представлен весь имеющийся к настоящему времени код игры, а также кое-что новое — комментарии к исходному коду.

Комментарий к исходному коду — это примечание, которое предназначено только для программистов и не воспринимается компилятором в процессе компиляции кода.

Комментарии к исходному коду ActionScript бывают двух видов: однострочные, начинающиеся с двух слэшей (//), и многострочные, начинающиеся с последовательности /* и заканчивающиеся символами */.

Так выглядит однострочный комментарий:

// Эта информация только для нас, программистов

А так записывается многострочный комментарий:

/*

Эта информация только для нас, программистов */

Текущий код для нашей игры выглядит следующим образом.

Листинг 1.1. Игра «Зоопарк»

// Содержимое файла Virtual Zoo. as package zoo {

public class VirtualZoo {

}

}

// Содержимое файла Virtual Pet. as package zoo {

internal class VirtualPet {

}

}

Теперь приступим к разработке нашей программы, начав с метода-конструктора основного класса приложения — VirtualZoo.

Методы-конструкторы

Метод-конструктор (или сокращенно конструктор) — это отдельный набор инструкций, применяемых для инициализации экземпляров класса. Для создания метода-конструктора внутри блока класса помещается описание функции, как показано в следующем обобщенном коде:

class НекийКласс { function НекийКласс ( ) {

}

}

Как видно из приведенного кода, описание метода-конструктора начинается с ключевого слова function. Затем следует имя метода-конструктора, которое должно полностью совпадать с именем класса (в том числе и регистр символов!). За именем метода-конструктора следует пара круглых скобок, в которых находится список параметров конструктора (они будут рассмотрены позднее). Фигурные скобки ({ и }), следующие за списком параметров, являются оператором блока — точно такие же операторы блока применяются в описаниях пакета и класса. Оператор блока метода-конструктора называется телом конструктора. Тело конструктора содержит директивы, используемые для инициализации экземпляров. Всякий раз, когда создается новый экземпляр класса НекийКласс, выполняются директивы, размещенные в теле конструктора (последовательно, сверху вниз). Процесс выполнения директив, размещенных в теле конструктора, называется выполнением конструктора.

Методы-конструкторы описываются с использованием ключевого слова function, поскольку с технической точки зрения они являются определенным видом функций. Подробно функции будут рассмотрены в гл. 5.

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

Руководство по actionscript. часть 1, стр. 033

Class НекийКласс { II Пустой конструктор. Для этого класса инициализация не требуется, function НекийКласс ( ) {

}

}

В отличие от прав доступа классов, права доступа методов-конструкторов не могут регулироваться при помощи модификаторов управления доступом. В языке ActionScript 3.0 все методы-конструкторы косвенно считаются открытыми (тем не менее, возможно, в будущих версиях языка будет включена поддержка и «за-

крытых» методов-конструкторов). В целях обеспечения однородности стиля в этой книге при описании методов-конструкторов используется модификатор управления доступом public, чем подчеркивается тот факт, что все методы-конструкторы должны быть открытыми. Пример использования этого правила приведен в следующем коде:

class НекийКласс { public function НекийКласс ( ) {

}

}

Причина, по которой в языке ActionScript 3.0 методы-конструкторы должны быть открытыми, обусловлена лимитом времени, выделенным на разработку спецификации языка ECMAScript 4, и непостоянством этой спецификации. Подробную информацию по этому вопросу можно найти в статье Шо Кувамото (Sho Kuwamoto) по адресу http://kuwamoto. org/2006/04/05/as3-on-the-lack-of-private-and-protected-constructors (Шо является руководителем команды разработчиков приложения Adobe Flex Builder).

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

Следующий код содержит изменения, связанные с добавлением метода-конструк-торав класс VirtualZoo:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { }

}

}

Теперь у нашего приложения появилась служебная точка входа. В процессе запуска приложения среда выполнения Flash автоматически создаст экземпляр класса VirtualZoo и выполнит его метод-конструктор. Поскольку наше приложение создает виртуальный зоопарк, первое, что необходимо сделать в конструкторе класса VirtualZoo, — создать объект класса VirtualPet (то есть добавить животное в зоопарк). В следующем разделе мы рассмотрим процедуру создания объектов.

Руководство по actionscript. часть 1, стр. 034

Создание объектов

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

new ИмяКласса

Например, чтобы создать объект из класса VirtualPet, используется следующий код:

new VirtualPet

Из одного класса можно создать несколько независимых объектов. В следующем примере описан код создания двух объектов VirtualPet:

new VirtualPet new VirtualPet

Синтаксис констант

Выше было сказано, что для создания нового объекта используется обобщенный синтаксис:

new ИмяКласса

Этот синтаксис применяется как к предопределенным, так и к пользовательским классам языка ActionScript. Например, следующий код демонстрирует создание нового экземпляра предопределенного класса Date, представляющего определенный момент времени:

new Date

Тем не менее для некоторых собственных классов язык ActionScript также предлагает альтернативный, более удобный способ создания экземпляров, называемый синтаксисом констант. К примеру, чтобы создать новый экземпляр класса Number, представляющий число с плавающей запятой 2 5, 4, можно использовать удобную запись в виде константы:

25.4

Подобным же образом для создания нового экземпляра класса String, представляющего текст «hello», можно использовать запись в виде константы:

«hello»

Наконец, чтобы создать новый экземпляр класса Boolean, представляющий логическое состояние true, можно также использовать запись в виде константы:

true

Для создания нового экземпляра класса Boolean, представляющего логическое состояние false, снова применяется запись в виде константы:

false

Синтаксис констант также доступен для классов Ob j ect, Function, RegExp и XML. Синтаксис констант для класса Ob j ect приведен в гл. 15, для класса Function — в гл. 5, а для класса XML — в гл. 18. Информацию по синтаксису констант для класса RegExp можно найти в соответствующей документации корпорации Adobe.

Пример создания объекта: добавление животного в зоопарк

Теперь, когда нам известно, как создавать объекты, мы можем добавить объект класса VirtualPet в нашу программу по созданию виртуального зоопарка. Следующий код делает именно это:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) {

new VirtualPet

}

}

}

Обратите внимание, что в этом коде обращение к классу VirtualPet происходит не по его уточненному имени zoo. VirtualPet, а по имени VirtualPet, являющемуся неуточненным, поскольку код из определенного пакета может обращаться к классам этого пакета по их неуточненным именам.

Однако код не может обращаться к классам в других пакетах. Чтобы получить доступ к открытому классу в другом пакете, необходимо использовать директиву import, которая записывается в следующем общем виде:

i mpo rt имяПакета. ИмяКласса:

В приведенном коде имяПакета — это имя пакета, которому принадлежит класс, а Имя — Класса — это имя открытого класса, который должен быть использован. Если указанный класс не является открытым, то его невозможно будет импортировать, поскольку классы, не являющиеся открытыми, не могут быть использованы за пределами пакета, которому принадлежат. Как только класс будет импортирован в программу, к нему можно обращаться по его неуточненному имени. Например, чтобы создать экземпляр предопределенного класса flash. media. Sound (который используется для загрузки и воспроизведения звуковых файлов), используется следующий код:

Руководство по actionscript. часть 1, стр. 035

Import flash. media. Sound new Sound

Если импортировать класс на уровне пакета, то он будет доступен из любого места кода, принадлежащего телу пакета. Например, в следующем коде класс flash. media. Sound импортируется на уровне пакета, а затем создается экземпляр класса Sound в методе-конструкторе VirtualZoo:

package zoo { import flash. media. Sound

public class VirtualZoo { public function VirtualZoo ( ) { new Sound

}

}

}

В случае возникновения конфликта между неуточненными именами классов для них необходимо использовать уточненные имена. Например, если собственный класс Sound описан в пакете zoo, обязательным является использование следующего кода, создающего экземпляр предопределенного класса flash. media. Sound (обратите внимание на использование уточненного имени):

new flash. media. Sound

Для создания же экземпляра класса Sound из пакета zoo нам бы пришлось использовать следующий код:

new zoo. Sound

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

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

import имяПакета.*

Например, чтобы получить доступ ко всем открытым классам в пакете flash. media, используется такой код:

import flash. media.*

Обратите внимание, что классы, принадлежащие пакету без имени, помещаются в автоматически создаваемый пакет, который называется безымянным. Классы из безымянного пакета можно непосредственно использовать в любом месте кода программы, не применяя директиву import. Другими словами:

package {

// Классы, описанные здесь, принадлежат безымянному пакету // и могут быть непосредственно использованы // в любом месте кода программы

}

Тем не менее следует избегать размещения описаний классов в безымянном пакете, поскольку их имена могут конфликтовать с именами других классов (и других типов описаний), описанных в языке ActionScript, других программах или даже в других частях одной программы.

Говоря техническим языком, директива import открывает общедоступное пространство имен указанного пакета для текущей и всех вложенных областей видимости. Если вы новичок в программировании на языке ActionScript, то вам не стоит беспокоиться о техническом аспекте директивы import. Вся необходимая информация будет рассмотрена в следующих главах.

Теперь вернемся к нашей первоначальной задаче — созданию объектов в программе «Зоопарк». Вспомним следующий код, в котором создается новый объект класса

VirtualPet:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { new VirtualPet

}

}

}

В приведенном коде успешно создается новый объект класса VirtualPet, но при этом возникает проблема: после создания объекта программа не имеет никакой возможности обращаться к нему. В результате она не может использовать новое животное или управлять им. Чтобы предоставить ей такую возможность — обращаться к объекту класса VirtualPet, — используются специальные переменные.

Руководство по actionscript. часть 1, стр. 036

Переменные и значения

В языке ActionScript любой объект рассматривается как отдельный, независимый фрагмент данных (или информации), называемый значением. Не считая объектов, единственными допустимыми значениями в языке ActionScript являются специальные значения null и undefined, представляющие понятие «пустое значение». Переменная — это идентификатор (то есть имя), ассоциированный со значением. Например, переменной может являться идентификатор submitBtn, который ассоциирован с объектом, представляющим кнопку на интерактивной странице в Интернете. Или переменной может быть идентификатор productDescr iption, ассоциированный с объектом String, описывающим некий продукт.

Переменные используются для отслеживания информации в программе. Они позволяют обращаться к объекту после его создания.

Существует четыре типа переменных: локальные переменные, переменные экземпляра, динамические переменные экземпляра и статические переменные. Первые два типа будут рассмотрены прямо сейчас, а остальные — далее в этой книге.

Локальные переменные

Локальные переменные применяются для временного отслеживания информации внутри метода-конструктора, метода экземпляра и статического метода или функции. Методы экземпляров и статические методы пока не рассматривались, поэтому сейчас сосредоточимся на использовании локальных переменных в методах-конструкторах.

Для создания локальной переменной внутри метода-конструктора используется описание переменной, как показано в следующем обобщенном коде. Обратите внимание, что описание начинается с ключевого слова va г и, как и все директивы, не содержащие операторов блока, завершается точкой с запятой. Точка с запятой обозначает конец директивы так же, как точка обозначает конец предложения в обычном языке:

Руководство по actionscript. часть 1, стр. 037

Class НекийКласс { public function НекийКласс ( ) { var идентификатор = значение:

}

}

В этом коде идентификатор представляет имя локальной переменной, а значение — значение, ассоциированное с этой переменной. Знак равенства и элемент значение называют инициализатором переменной, поскольку они определяют исходное значение переменной.

_а_

Я Процесс ассоциирования переменной со значением называется присваиванием, установкой или записью значения переменной.

Если инициализатор переменной не указан, то компилятор языка ActionScript автоматически присваивает переменной значение по умолчанию, соответствующее ее типу. Эти значения будут рассмотрены в гл. 8.

Локальная переменная может быть использована только внутри того метода или функции, в которой она описана. После завершения выполнения метода или функции срок действия локальной переменной заканчивается и она больше не может быть использована в программе.

Для обращения к объекту класса VirtualPet, который был создан ранее в конструкторе класса VirtualZoo, создадим локальную переменную. Локальной переменной присвоим имя pet, а для связывания объекта VirtualPet с этой переменной воспользуемся инициализатором. Привожу код:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet;

}

}

}

Теперь, когда локальная переменная pet связана с объектом VirtualPet, она может быть использована для обращения к объекту и, следовательно, для управления им. Однако в настоящий момент объект Vi г tua 1 Ре t не может выполнять никакие действия, поскольку его функциональность еще не запрограммирована. Способы устранения этого недостатка будут рассмотрены в разд. «Параметры и аргументы конструктора», в котором я также расскажу, как предоставить животным возможность иметь имена.

Переменные экземпляра

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

Переменная экземпляра — это переменная, принадлежащая определенному объекту. Обычно каждая переменная экземпляра описывает некую характеристику объекта, к которому принадлежит. Например, переменной экземпляра может являться идентификатор width, связанный со значением 150, которое определяет ширину кнопки интерфейса, или идентификатор shippingAddress, связанный со значением ул. Некая, 34, которое определяет адрес доставки объекта заказанного товара.

Руководство по actionscript. часть 1, стр. 038

Как видно из следующего обобщенного кода, переменные экземпляра создаются с помощью размещаемых непосредственно в описании класса описаний переменных:

class НекийКласс { var идентификатор = значение:

}

Добавление описания переменной экземпляра в описание класса приводит к автоматическому присоединению этой переменной к каждому экземпляру данно-

го класса. Как и в случае с локальными переменными, инициализатор описания переменной экземпляра задает исходное значение для создаваемой переменной. Однако, поскольку в переменных отдельно взятого экземпляра класса хранятся его собственные значения, исходное значение переменной экземпляра зачастую не указывается и присваивается позднее уже при выполнении программы.

В качестве примера добавим переменную экземпляра в класс VirtualPet. Она позволит отслеживать имя каждого объекта VirtualPet. Переменную экземпляра назовем именем pet Name:

package zoo { internal class VirtualPet { var petName = «Unnamed Pet»;

}

}

В результате использования приведенного кода переменная экземпляра petName будет автоматически присоединена к каждому новому экземпляру класса Vi г tua 1 Реt. Исходным значением переменной petName для всех экземпляров класса VirtualPet будет являться фраза Unnamed Pet. Тем не менее после создания экземпляра класса VirtualPet переменной petName может быть присвоено новое, индивидуальное значение.

Для присвоения переменной экземпляра нового значения используется следующий обобщенный код:

объект. переменнаяЭкземпляра = значение

Здесь объект — это объект, переменной экземпляра которого присваивается значение; переменнаяЭкземпляра — это одна из переменных экземпляра объект (описанных в классе объекта); значение — это присваиваемое значение.

Воспользуемся описанной методикой, чтобы присвоить какое-либо имя объекту VirtualPet, созданному ранее в конструкторе класса VirtualZoo. Привожу код описания класса VirtualZoo, который содержит все предыдущие изменения:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet;

}

}

}

В соответствии с обобщенным кодом, используемым для присваивания нового значения переменной экземпляра, сначала необходимо обратиться к объекту. В данном случае для обращения к желаемому экземпляру класса VirtualPet применим локальную переменную pet:

pet

Затем ставится точка:

pet.

После этого записывается имя переменной экземпляра, значение которой нужно изменить — в данном случае petName:

pet. petName

В конце ставится знак = и указывается значение, которое необходимо присвоить переменной экземпляра. В нашем примере применим значение Stan:

pet. petName = «Stan»

Разве это не мило? Теперь у нашего животного появилась кличка. Мы делаем успехи.

Ниже приведен измененный код описания класса VirtualZoo:

package zoo { public class VirtualZoo { public function VirtualZoo ( ) { var pet = new VirtualPet: pet. petName = «Stan»;

}

}

}

Обратите внимание, что в предыдущем коде значение переменной экземпляра petName, описанной в классе VirtualPet, присваивается через экземпляр класса VirtualPet, принадлежащего классу VirtualZoo. Следовательно, коду в классе VirtualZoo доступна переменная экземпляра petName. Когда класс разрешает доступ из других классов к своим переменным экземпляра, он позволяет этим классам вносить изменения в характеристики своих экземпляров.

Руководство по actionscript. часть 1, стр. 039

Имя животного — это характеристика, которая естественным образом пригодна для внешнего изменения. Тем не менее некоторые переменные экземпляра могут представлять характеристики, которые не должны изменяться за пределами класса, содержащего описание данных переменных. Например, далее будет создана переменная экземпляра caloriesPerSecond, определяющая скорость, с которой у того или иного животного переваривается пища. Если переменной caloriesPerSecond присвоить слишком маленькое или слишком большое значение, то животное может постоянно хотеть есть или, наоборот, никогда не проголодаться. Поэтому, чтобы внешний код не смог присвоить неприемлемое значение переменной caloriesPerSecond, необходимо ограничить доступ к этой переменной. Для этого применяются модификаторы управления доступом.

Модификаторы управления доступом для переменных экземпляра. Модификатор управления доступом переменной экземпляра определяет уровень доступа к этой переменной в программе. Для описаний переменных экземпляра существуют следующие модификаторы управления доступом: public, internal, protected и private.

Модификаторы pub lie и internal для переменных экземпляра обладают таким же эффектом, что и для классов. Переменная экземпляра, объявленная с использованием модификатора public, может быть доступна как внутри, так и снаружи пакета, в котором была описана; переменная экземпляра, объявленная с исполь-



Полезные ссылки
Случайные записи
  • 03.03.2011">Руководство по actionscript. часть 5, стр. 079
  • 02.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.111
  • 22.01.2011">Руководство по actionscript. часть 1, стр. 133
  • 11.03.2011">Руководство по actionscript. часть 4, стр. 013
  • 18.07.2010">Лучшие модули для сайта
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 096
  • 17.05.2012">«Лаборатория Касперского»: спамеры нацелились на геймеров и пользователей Facebook
  • 28.02.2011">Руководство по actionscript. часть 6, стр. 011
  • 28.03.2010">Коллекция кистей для Photoshop
  • 19.03.2011">Руководство по actionscript. часть 2, стр. 084
  • 15.03.2011">Руководство по actionscript. часть 3, стр. 057
  • 21.03.2011">Руководство по actionscript. часть 2, стр. 032
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.56
  • 08.03.2011">Руководство по actionscript. часть 4, стр. 096
  • 12.04.2011">Photoshop для начинающих: как вставить фото в готовую рамку?
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...