Как и обещал выкладываю первую тройку ответов. Напомню, что в качестве эксперимента я решил собирать короткие вопросы по флеш и отвечать на них в своем журнале.
Надо признаться давненько я не рассказывал о программировании. Все дело в том, что эта часть разработки игр становится для меня рутиной, и преподносит мне все меньше сюрпризов. А сам я углубляюсь в геймдизайн, ливелдизайн, дитрибуцию и прочие сопутствующие моменты.Но сегодня я решил отвлечься, написать немного текста и порадовать журнал новым сообщением. Великих тайн я раскрыть не смогу, ведь сам не обладаю знанием, поэтому рассказ пойдет о простых вещах, об основах так сказать. Итак, сегодня поговорим про flash. Ожидайте в выпуске:
| ![]() |
Как полностью удалить объект?
Дело в том, что в Delphi, на котором я программировал бОльшую часть жизни, удаление объекта происходило просто MyObject.Free()... После вызова этой строчки я мог быть уверен, что оперативная память очистилась от ненужного более объекта.
В as3 такого нет. Поэтому при первом знакомстве моя дотошная натура беспокоилась: "мы же заххх-ламииии-м всю память, моя прелессссть". Погуглив, стало ясно, что as3 оснащен сборщиком мусора, который иногда зачищает память от объектов, на которые никто не ссылается. Например, мы создали мувик и положили на сцену:
var MyClip: MovieClip = new MovieClip; stage.addChild(MyClip);
Как теперь избавиться от нашего экземпляра MovieClip?
Сначала убираем его со сцены, и теперь stage перестанет ссылаться на наш клип:
stage.removeChild(MyClip);
Но кто-то еще держит ссылку на этот объект. Кто? Конечно, это наша переменная MyClip, являясь по сути ссылкой на сам клип. Зануляем его и дело с концом:
MyClip = null;
Вот и все. Сначала создали, затем убили. Вскоре сборщик мусора распознает наше желание вычистить память от клипа и сделает свое дело, зачистив память.
Загрузка звукового файла
Чтобы подбор звуков для игры не стал мучительным круговоротом "подправил звук -> скомпилировался -> подправил звук -> скомпилировался ->..." я загружаю звуки во время игры. То есть ударили нашего персонажа по голове, и в этот момент я загружаю звук с диска и отправляю на проигрывание. Ударили второй раз - снова гружу с диска. Поэтому, если между ударами заменить файл со звуком, то во второй раз проиграется уже новый звук. Таким образом подгон кромкости, тональности и остального проходит довольно быстро. Когда игра готова, я убираю код с подгрузкой из файла, а вместо этого вшиваю финальные звуки в итоговый файл игры.
Загрузить звук очень просто:
var request: URLRequest = new URLRequest("sounds/" + aName + ".mp3"); var sound: Sound = new Sound; sound.load(request); sound.play(); // запускаем загруженный звук
Замечательно, теперь наш звук будет грузиться с диска и сразу проигрываться!
Хочу удалить объект из MovieClip'а со всех кадров!
Итак, самый сложный вопрос на сегодня я оставил напоследок. Чтобы было понятно о чем речь, расскажу такую историю.
К примеру, есть у меня мувик (MovieClip) с анимацией движения человечка с мечом. Так как в игре планируются разные мечи, то в этом мувике вместо меча лежит синий квадратик, и я надеюсь его подменить нужным мечом, которым экипирован человечек. Таким образом я хочу сэкономить на анимациях - делаю одну, а потом просто меняю синий квадратик на меч. При проигрывании анимации я сначала удалю квадратик, и в его позицию помещу меч, с углом поворота все того же убер-квадратика.
И вот теперь встает первая задача - я хочу удалить синий квадратик из мувика! Ведь мне нужно его заменить на меч, а сам квадратик мне и даром не нужен...
Итак, допустим у нас есть объект A в первых двух кадрах мувика B. Делаем так:
B.gotoAndStop(1); B.removeChild(A); B.gotoAndStop(2);
И наблюдаем замечательную картину - объект A пропал и из второго кадра тоже! Отлично! То, что нужно? Почти... Давайте после всего этого сделаем так:
B.gotoAndStop(1);
И, о чудо, объект A возродился из пепла, словно неугомонный феникс... Как же так? Не могу точно ответить на этот вопрос, но видимо мувик хранит полные слепки некоторых кадров, а в промежуточных пытается оперировать исходными объектами. Поэтому, когда мы переходим на такой вот "слепок" - все наши манипуляции с внутренними объектами пропадают.
Так же, если у нас в первом кадре есть наш объект A, во втором кадре его нет, а в третьем он появляется вновь - то, чтобы мы ни делали с ним в первом кадре - все напрасно, при проигрывании анимации, в третьем кадре он появится вновь. Это и понятно, ведь флеш не телепат, чтобы понять, что именно мы от него хотим, удаляя внутренний объект.
Как тогда поступить в нашей ситуации? Как гарантированно удалить объект из мувика? Ну, лично я бы удалял ненужный объект каждый кадр. Решение жесткое, но пока другого (стопроцентно-работающего) я не нашел.
Итак, что-то вроде этого:
B.addEventListener(Event.ENTER_FRAME, onFrameUpdate); function onFrameUpdate(e: Event): void { if(B.contains(A)) B.removeChild(A); }
На этом можно было бы и остановиться, но я приведу еще несколько примеров, где данная проблема остро встает:
- растеризация объектов. это прием, при котором все объекты сначала "фотографируются" в картинку, затем эти векторные объекты из мувика удаляются совсем, а на их место кладется созданная картинка. слова "удаляются" и "кладется" уже наверно навели на мысль, что, если мы этот мувик запустим на анимацию, то уже скоро все наши манипуляции с ним забудутся, и вновь появятся векторные объекты, а картинка просто исчезнет (ведь в кадре-"слепке" ее не было!)
- "выдергивание" объектов из мувика. сейчас поясню... чтобы не путаться, я помечу слова цветами, надеюсь, так будет яснее что где =) дело в том, что я иногда ищу в мувике нужный объект и переношу его в другой мувик. при этом искомый объект исчезает из исходного мувика и появляется в новом. Пока все ясно... Теперь я перехожу в исходном мувике на следующий кадр и снова ищу нужный объект. А его там нет... почему? Потому что при переходе на следующий кадр исходный мувик "правильно" сработал и удалил объект и из следующего кадра. Ведь "слепка" пока не было. Наверно, это уже менее ясно, но все же... главное - что я не знаю точно, где мувиклип делает свои "слепки" и не могу предсказать, будет ли перенесенный объект в исходном клипе. Как бороться? Я сделал так - в конце исходного мувика добавил пустой кадр и при любых переходах между кадрами я сначала перехожу на последний кадр, и только потом иду на нужный. Так мувиклип гарантированно восстановит все исходные объекты из "слепка".
Прошу прощения за последний текстовый фарш... Дело в том, что я и сам не до конца разобрался в этом вопросе, поэтому не могу четко написать "так, мол, и так". Отсюда и неясности все эти. Но надеюсь я буду расти, а вместе с моим ростом будет улучшаться качество моих записей. Во флеш я новичок, поэтому буду и вопросы раскрывать "новичковые", с которыми сам и сталкиваюсь.
Если интересно - не стесняйтесь, задавайте свои вопросы в общей теме, возможно я смогу ответить!