Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   BitmapData#draw(...) проблеммы с применением трансформаций (http://www.flasher.ru/forum/showthread.php?t=181688)

elder_Nosferatu 29.06.2012 19:02

BitmapData#draw(...) проблеммы с применением трансформаций
 
Салют!
Задался задачей рендерить происходящее в игровом мире в Битмапу. Думал контейнер игрового мира не кидать на сцену вообще, а только делать его отпечатки в БитмапДату и Битмапой, которая будет в ДисплейЛисте, выводить. Идея проста и понятна, но вот никак не смог увидеть больше чем первую координатную плоскость иргового мира, а интересного много и на отрицательных координатах... Так же не смог применить масштабирование снимка игрового мира.
Трейсил матрицу трансформации - там все ОК! Думал, что у меня не правильная расстановка объектов внутри мира и решил добавить его на сцену для проверки. Все оказалось на своих местах, но плюс ко всему снимок я получил такой как надо...:o

А теперь вопрос: Как применить трансформации для ДисплейОбджекта, который отрисовывается в БитмапДату, не имея родителя?

maxkar 29.06.2012 19:49

Пример маленький соберите, на котором трансформация не работает. Так сложно что-то сказать. Вы там clipRect неправильный указываете, что ли? И у вас объекты самодеятельностью на ADDED_TO_STAGE не занимаются? :)

elder_Nosferatu 30.06.2012 00:53

Вложений: 1
Вложение 28152(1,23 КБ (1`264 байт)) - скомпилированый пример. По клику добавляет или убирает "игровой мир" со сцены. В битмапе видно результат.

Код:
Код AS3:

package {
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.geom.Matrix;
 
        public class Main extends Sprite {
                private var world:Sprite = new Sprite();
                private var obj:Shape = new Shape();
                private var data:BitmapData = new BitmapData(200, 150);
                private var tv:Bitmap = new Bitmap(data);
                private var trans:Matrix = new Matrix();
 
                public function Main():void {
                        // Мир с осями координат
                        world.graphics.lineStyle(2);
                        world.graphics.moveTo( -300);
                        world.graphics.lineTo(  300);
                        world.graphics.moveTo(  0, -20);
                        world.graphics.lineTo(  020);
                        // Обьект мира с центром координат внутри изображения
                        obj.graphics.beginFill(0xFF0000, 0.2);
                        obj.graphics.drawCircle(0, 0, 35);
                        obj.graphics.endFill();
                        obj.graphics.beginFill(0x00FF00, 0.2);
                        obj.graphics.drawRect(-30, -20, 60, 40);
                        obj.graphics.endFill();
                        world.addChild(obj);
                        // Битмапа для съемки мира
                        graphics.lineStyle(2);
                        graphics.drawRect(97, 57, 206, 156);
                        addChild(tv);
                        tv.x = 100;
                        tv.y = 60;
                        // Трансформация снимка
                        trans.scale(2, 2);
                        trans.translate(0.5 * tv.width, 0.5 * tv.height);
                        // Поехали...
                        addEventListener(Event.ENTER_FRAME, handleEnterFrame);
                        stage.addEventListener(MouseEvent.CLICK, handleClick);
                        addChild(world);
                }
                private function handleClick(event:MouseEvent):void {
                        if (contains(world)) removeChild(world);
                        else addChild(world);
                }
                private function handleEnterFrame(event:Event):void {
                        obj.rotationY += 5; // Изменение объекта
                        data.fillRect(data.rect, 0);
                        data.draw(world, trans);
                }
        }
}

К стати, в примере начертил оси и увидел, что с самим миром все ОК, вот только его "кишки" ведут себя по разному, в зависимости от наличия родительского контейнера для объекта мира...

expl 30.06.2012 01:42

Не пробовал, но, вроде как, люди обкатали на реальных проектах:
http://flashgameblogs.ru/blog/actionscript/1015.html
Здесь было:
http://www.flasher.ru/forum/blog.php?bt=7632

vizgl 30.06.2012 01:59

Проблема в вращении по оси Y. Если его убрать, то все нормально отрисовывается.

elder_Nosferatu 30.06.2012 02:01

Нашел проблему, но не знаю как сделать все красиво...
В примере я не зря поставил строчку
Код AS3:

obj.rotationY += 5;

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

Короче говоря, пока у объекта null-евая Matrix3d, все работает нормально, но как только вступает в силу ось Z, сразу же вылазит на ружу тот результат, который я показал в примере.

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

Если у кого есть решение получше, буду очень благодарен!

Добавлено через 1 минуту
Опоздал с постом... Но как я и писал - без Z-трансформации дело не пойдет

maxkar 30.06.2012 02:18

Цитата:

world.transform.perspectiveProjection = new PerspectiveProjection();
В любом месте. Достаточно одного раза.

При желании проекцию можете взять у Stage, она будет точно такая же.

Как нашел - не спрашивайте. Интуиция и немного экспериментов. Собственно, там больше не с чем экспериментировать было (в 3D), а что проекция потенциально настраивается, я знал раньше.

elder_Nosferatu 30.06.2012 02:33

2maxkar:
Огромное спасибо! То что надо!

2(expl, vizgl):
И Вам спасибо, что не прошли мимо!

+,+,+

ChuwY 30.06.2012 02:56

Эксперименты примерно по той же теме.
Может быть, тоже поможет.


Кстати, даже если и не пользоваться этими извращениями с отрисовкой в битмапу без родительского контейнера, ручной скейл на основе PerspectiveProjection получается чуть ли не в разы быстрее, чем использование Matrix3D


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

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