Просмотр полной версии : Многокомпонентная анимация персонажа - как реализовать?
mickfallout
23.04.2010, 23:40
Есть персонаж в изометрической РПГ, графика сохранена в виде кучи png файлов:
Man_Move_Right_001.png, Man_Move_Right_002.png, <...> - кадры анимации движения голого перса
AK_Move_Right_001.png, AK_Move_Right_002.png, <...> - кадры анимации автомата при движении перса
и так далее.
Как всё это собирать в один мувик? В голову приходит три варианта:
1. Сделать отдельные мувики движений разных частей, сделать класс-контейнер, который будет следить за синхронностью движений, управлять переключением кадров, добавлять-удалять компоненты анимации. В этом варианте пугает, что для каждого кадра в оперативной памяти будет несколько изображений, что для одного персонажа будет несколько мувиков.
2. При появлении персонажа создавать мувик, в каждый кадр которого ставить Bitmap, полученный сложением кадров одетых вещей. Такой вариант видимо будет быстрее воспроизводиться и меньше памяти требовать.
3. Сделать отдельные мувики движений разных частей, а при появлении персонажа собирать из кадров этих отдельных мувиков один общий (просто добавляя shape'ы в кадры, без использования Bitmap). Такой вариант анимации наверное будет воспроизводиться быстрее первого, но медленнее второго, а инициализироваться быстрее второго, но медленнее первого.
Посоветуйте, какой вариант выбрать? Или может быть есть ещё варианты?
при появлении персонажа собирать из кадров этих отдельных мувиков один общий (просто добавляя shape'ы в кадры, без использования Bitmap)
Откуда уверенность, что переключение кадров быстрее подстановки bitmapData у Bitmap? Там еще не понятно что с памятью при переключении кадров происходит.
Соберите в каждый swf как ресурс. Съэкономите на времени ожидания загрузки для конечного пользователя.
mikhailk
24.04.2010, 11:00
Проблема, как я понимаю, в том числе и в том, что заранее все варианты в мувик не собрать. С тем, чтобы собрать голого лысого перса в один клип, вопросов нет. Но пользователь в процессе игры докупает для него одежду, аксессуары, прическу меняет.
Все равно получается контейнер, к котором стопкой лежат мувиклипы, синхронизированные по таймлайну, как я понимаю.
Хотя, конечно, с точки программирования идеальный вариант, когда все внутри уже реализовано, а ты просто выставляешь/убираешь альфу. Но это для простых случаев.
mickfallout
24.04.2010, 22:29
сделал так(первый вариант):
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
/**
* ...
* @author mick
*/
public class UnitAnimation extends Sprite
{
static public const UNIT_BODY_MAN:String = "Man";
static public const UNIT_EQUIPMENT_AK:String = "AK_Equipment";
public function UnitAnimation(bodyType:String, equipment:Array=null)
{
var i:int = 0;
super();
if (equipment == null)
equipment = [];
addChild(Main.newMovieClip(bodyType));//функция Main.newMovieClip(imageName:String):MovieClip - выдает мувик из файла ресурсов
while (i < equipment.length)
addChild(Main.newMovieClip(equipment[i++]));
gotoAndStop(0);
}
public function gotoAndStop(frame:Object, scene:String = null):void
{
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).gotoAndStop(frame, scene);
}
public function get currentFrame():int
{
if (numChildren > 0)
return MovieClip(getChildAt(0)).currentFrame;
return 1;
}
public function get totalFrames():int
{
if (numChildren > 0)
return MovieClip(getChildAt(0)).totalFrames;
return 1;
}
public function gotoAndPlay(frame:Object, scene:String = null):void
{
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).gotoAndPlay(frame, scene);
}
public function stop():void
{
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).stop();
}
public function play():void
{
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).play();
}
public function nextFrame():void
{
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).nextFrame();
}
public function prevFrame():void
{
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).prevFrame();
}
public override function set mouseEnabled(value:Boolean):void
{
super.mouseEnabled = value;
var i:int = numChildren;
while (i-- > 0)
MovieClip(getChildAt(i)).mouseEnabled=value;
}
public override function get mouseEnabled():Boolean
{
return super.mouseEnabled;
}
public function setEquipment(equipment:Array, playAnimation:Boolean = true):void
{
var i:int = numChildren;
while (i-- > 1)
removeChildAt(i);
i = numChildren;
while (i < equipment.length)
addChild(Main.newMovieClip(equipment[i++]));
if (playAnimation)
gotoAndPlay(currentFrame);
else
gotoAndStop(currentFrame);
}
}
}
Не нравится мне такой вариант =(
Думаю второй был бы быстрее... Но с ним не знаю как лучше сделать смену изображений в зависимости от кадра (собственно анимацию). Просто подписать обработчик события EnterFrame с сменой битмапДаты? Не будет ли это слишком долго?
http://blog.hexagonstar.com/animatedbitmapclass/
вот что-то похожее делал:
http://k0t0vich.megaforce.ru/test/flashfight/Animtest.swf
вот что-то похожее делал:
http://k0t0vich.megaforce.ru/test/flashfight/Animtest.swf
оо, очень шустро работает. А как сортируется такая толпа? childIndex'ом?
BlooDHounD
26.04.2010, 13:45
очень шустро и очень криво =)
очень шустро и очень криво =)
Это даже не прототип - тестик: потянет/не потянет 50 - одновременно движущихся с большой битмапой..
Там xml - персонажа кривая (координаты, положения, некоторых кадров элементарно нет), рендеры тестовые, нет никакой практически оптимизации, но свою цель тест выполнил на все 100%.
Если будет возможность/разрешение вышестоящих органов - выложу что в итоге получилось))
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.