Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   MVC, ООП, AS3 учусь на примере 2D движка (http://www.flasher.ru/forum/showthread.php?t=208872)

ntro123123 13.09.2014 19:45

MVC, ООП, AS3 учусь на примере 2D движка
 
Вложений: 1
Цели:
понять что такое MVC и ООП
научиться кодить на AS3

Решение:
написать скрипт/проект по следующему ТЗ:
Цитата:

Написать программу с применением ООП в MVC. Шарик (X, Y, масса, коэф. упругости, радиус и цвет(hex) указаны в data/set.txt) "пинается" курсором и падает на землю по физ. законам, вместе с отскоком от стены и земли.


Не реализовано в проекте:
отскок (вместо него костыль который обнуляет скорость, когда шарик касается "пол" сцены)

Много где костылей, много где не доделано. Основная задача разобраться с AS3, MVC.
Результат (+прикрепил весь проект Вложение 31124):
mvc/Main.as
Код AS3:

package mvc
{
        import flash.display.Sprite;
        import mvc.*;
 
        public class Main extends Sprite
        {
                private var _model:Model;
                private var _view:Viewer;
                private var _controller:Controller;
 
                public function Main()
                {
                        _model = new Model(stage); // я так понимаю с точки зрения MVC я сделал крупную ошибку передав всю сцену? см. 118-119 строки модели
 
                        _view = new Viewer(_model);
                        super.addChild(_view);
 
                        _controller = new Controller(_view, _model);
                }
        }
}

mvc/Controller.as
Код AS3:

package mvc
{
        import flash.events.*;
        import flash.utils.Timer;
 
        public class Controller extends EventDispatcher
        {
                private var _model:Model;
                private var _view:Viewer;
 
                public function Controller(view:Viewer, model:Model)
                {
                        _view = view;
                        _model = model;
 
                        _view.stage.getChildByName('root1').addEventListener(MouseEvent.CLICK, _model.getDataObj)// так и не понял, почему root1 название? вроде везде mc_create
                        _model.loadData.addEventListener(Event.COMPLETE, _model.createObj); // после загрузки txt файла с параметрами, вызываем метод создания шара
                        _model.addEventListener('sharCreated', _view.addObj);
                        _view.addEventListener('sharShowed', InitEvents);
                }
 
                private function InitEvents(e:Event):void
                {
                        _model.currentShar.addEventListener(Event.ENTER_FRAME, _model.passivMove);
                        _model.currentShar.Obj.addEventListener(MouseEvent.MOUSE_OVER, _model.mouseMove);
                        var time:Timer=new Timer(50, 0); // каждые 50 мс вычисляем скорость мыши по текущим и предыдущим координатам
                        time.addEventListener(TimerEvent.TIMER, _model.OnTimeCursorV);
                        time.start();
                }
        }
}


mvc/Model.as
Код AS3:

package mvc
{
        import flash.events.*;
        import objects.Shar;
        import flash.net.URLRequest;
        import flash.net.URLLoader;
        import flash.events.EventDispatcher;
        import flash.display.Stage;
 
        public class Model extends EventDispatcher
        {
                public var currentShar:Shar;
                public var loadData:URLLoader=new URLLoader();
                private var stage:Stage;
 
                private const CURSOR_WEIGHT:Number=5; //масса шарика
                private var g:Number; // сила тяжесть
                private var stageWidth:uint;
                private var stageHeight:uint;
 
                private var cursorV:Number=0; // сохраненная скорость мыши в момент столкновения
                private var cursorCurrentV:Number=0; // текущая(мгновенная) скорость мыши
                private var cursorLastX:Number;
                private var cursorLastY:Number;
                private var lastLocalX:Number=0;
                private var lastLocalY:Number=0;
 
                public function Model(stage:Stage)
                {
                        this.stage=stage; // я так понимаю с точки зрения MVC я сделал крупную ошибку передав всю сцену? см. 118-119 строки
 
                        this.g=10/stage.frameRate; // сила тяжесть
                        this.stageWidth=stage.stageWidth;
                        this.stageHeight=stage.stageHeight;
                        this.cursorLastX=stageWidth/2;
                        this.cursorLastY=stageHeight/2;
                }
 
                public function getDataObj(e:Event):void
                {
                        e.target.stage.getChildByName('root1').removeEventListener(MouseEvent.CLICK, getDataObj);
                        //e.target.stage.removeChild(e.target.stage.getChildByName('root1')); // удаление кнопки, почемуто если удалить кнопку, то все перестает работать
                        loadData.load(new URLRequest('data/set.txt')); // считали параметры шара из файла
                }
 
                public function createObj(e:Event = null):void
                {
                        var arr:Array=new Array();
                        arr=loadData.data.split(';');
                        currentShar=new Shar({ // создали экземпляр шара по параметрам из файла (класс objects/Shar.as)
                                        X:arr[0],
                                        Y:arr[1],
                                        M:arr[2],
                                        E:arr[3],
                                        R:arr[4],
                                        C:arr[5]
                                });
                        dispatchEvent(new Event('sharCreated'));
                }
 
                public function passivMove(e:Event):void
                {
                        var shar:Object=e.target;
 
 
                        // сохраненная скорость мыши при столкновении постепенно уменьшается до 0
 
                        if(this.cursorV>0)
                                this.cursorV-=g;
                        else if(this.cursorV<0)
                                this.cursorV=0;
 
                        var Fc:Number=this.CURSOR_WEIGHT*this.cursorV; // вычислить вектор столкновения мыши с шариком (если мышь не сталкивалась тоthis.cursorV=0 и вектор=0)
                        var XFc:Number=(lastLocalX/shar.R)*Fc;
                        var YFc:Number=(-lastLocalY/shar.R)*Fc;
 
 
                        var Fs:Number=shar.M*shar.V; // вычисляем mg
                        var XFs:Number=0*Fs; // знаю что бессмысленно умножать на 0, но с точки зрения физики так понятней, сейчас разговор идет исключительно про MVC и ООП
                        var YFs:Number=1*Fs;
 
 
                        var Nx:Number=XFs+XFc; // вычисляем новый результирующий вектор
                        var Ny:Number=YFs+YFc;
 
                        shar.direc=Math.atan2(Ny, -Nx); // вычисляем новый угол движения шара
                        shar.A=Math.sqrt(Ny*Ny+Nx*Nx)*0.05; // вычисляем скалярную величину нового векутор (0.05 - коэф. ибо без него слишком быстро меняеться)
                        shar.V+=shar.A; // изменяем скорость шарика
 
                        shar.X+=shar.V*Math.cos(shar.direc); // изменяем координаты, лучше делать через _viewer.updateObj ?
                        shar.Y+=shar.V*Math.sin(shar.direc); // изменяем координаты, лучше делать через _viewer.updateObj ?
 
 
                        // далее идут вычисления границу сцены и предотвращения ухода за них шара
 
                        if(shar.Y+shar.R>=stageHeight)
                        {
                                shar.Y=stageHeight-shar.R;
                                shar.V=0; // сбрасываем скорость на 0, когда шар упал вниз сцены, правильнее будет делать отскок от сцены за счет изменения shar.direc
                        }
                        if(shar.Y-shar.R<=0)
                        {
                                shar.Y=shar.R;
                                shar.V=0; // если уперся в потолок, тоже сбрасываем скорость на 0, в идеале опять же сделать отскок
                        }
                        if(shar.X+shar.R>=stageWidth)
                        {
                                shar.X=stageWidth-shar.R;
                        }
                        if(shar.X-shar.R<=0)
                        {
                                shar.X=shar.R;
                        }
                }
 
                public function OnTimeCursorV(e:TimerEvent):void
                {
                        var dX:Number=Math.abs(stage.mouseX-cursorLastX); // через таймер же не предать stage.mouseX, он нужен для вычисления скорости мышки за счет измерения изменения координат курсора
                        var dY:Number=Math.abs(stage.mouseY-cursorLastY);
                        this.cursorCurrentV=Math.sqrt(dX*dX+dY*dY); // мгновенная скорость см. 127 строку
                        this.cursorLastX=stage.mouseX;
                        this.cursorLastY=stage.mouseY;
                }       
 
                public function mouseMove(e:MouseEvent):void
                {
                        this.cursorV=this.cursorCurrentV; // мгновенная становиться текущуй скоростью, и используеться в расчетах именно она в момент сталкнвовения с мыщью
                        this.lastLocalX=e.localX; // сохраняем координаты мыши для вычисления вектора силы мыши
                        this.lastLocalY=e.localY;
                }
        }
}

mvc/Viewer.as
Код AS3:

package mvc
{
        import flash.display.Sprite;
        import flash.events.*;
        import objects.Shar;
 
 
        public class Viewer extends Sprite
        {
                private var _model:Model;
 
                public function Viewer(model:Model)
                {
                        _model=model;
                }
 
                public function addObj(e:Event):void
                {
                        addChild(e.target.currentShar.Obj);
                        dispatchEvent(new Event('sharShowed'));
                }
 
                public function updateObj(x:Number, y:Number) // пожалуй, этим должен заниматься вьювер, но как туда предать параметры через контроллер? Или можно передать ссылку на сам вьювер?
                {
                        _model.currentShar.X=x;
                        _model.currentShar.Y=y;
                }
        }
}

objects/Shar.as
Код AS3:

package objects
{
        import flash.display.Sprite;
 
        public class Shar extends Sprite
        {
                private var _obj:Sprite=new Sprite();
                private var _X:Number;
                private var _Y:Number;
                private var _M:Number;
                private var _E:Number;
                private var _R:uint;
                private var _C:uint;
                private var _V:Number=1;
                private var _A:Number;
                private var _direc:Number=1.5*Math.PI;
 
                public function Shar(param:Object)
                {
                        this.M=param.M;
                        this.E=param.E;
                        this.C=param.C;
                        this.Obj.graphics.drawCircle(0, 0, param.R);
                        this.R=param.R;
                        this.X=param.X;
                        this.Y=param.Y;
                }
 
                public function get Obj():Object
                {
                        return this._obj;
                }
 
                public function set X(X:Number):void
                {
                        _X=X;
                        this.Obj.x=X;
                }
 
                public function get X():Number
                {
                        return _X;
                }       
 
                public function set Y(Y:Number):void
                {
                        _Y=Y;
                        this.Obj.y=Y;
                }
 
                public function get Y():Number
                {
                        return _Y;
                }       
 
                public function set R(r:uint):void
                {
                        _R=r;
                        this.Obj.width=r*2;
                        this.Obj.height=r*2;
                }
 
                public function get R():uint
                {
                        return _R;
                }
 
                public function set C(c:uint):void
                {
                        _C=c;
                        this.Obj.graphics.beginFill(c);
                }
 
                public function get C():uint
                {
                        return _C;
                }       
 
                public function set E(e:Number):void
                {
                        _E=e;
                }
 
                public function get E():Number
                {
                        return _E;
                }
 
                public function set M(m:Number):void
                {
                        _M=m;
                }
 
                public function get M():Number
                {
                        return _M;
                }
 
                public function set V(v:Number):void
                {
                        _V=v;
                }
 
                public function get V():Number
                {
                        return _V;
                }
 
                public function set A(a:Number):void
                {
                        _A=a;
                }
 
                public function get A():Number
                {
                        return _A;
                }
 
                public function set direc(d:Number):void
                {
                        _direc=d;
                }
 
                public function get direc():Number
                {
                        return _direc;
                }
        }
}

(упс, спойлер не пашет)

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

P. S. "движка" громко сказано =)

Gerbert 13.09.2014 21:57

1) Могу пока только сказать, что свойства принято начинать со строчных.
2) Класс Шар у Вас унаследован от sprite и его название говорит, что ЭТО ШАР,
а на деле получается, что ЭТО КОНТЕЙНЕР ДЛЯ ШАРА, ведь шар, который является больше
_view, у Вас назван _obj.
3) Сами себя инициализируете через сеттеры, хотя в этом нет необходимости.
4) Graphics размазан по всему классу, это тоже не айс.
5) Жуткие названия, пишите лучше полными именами.

Добавлено через 1 час 8 минут
И модель у Вас выполняет сразу много обязанностей - загружает, рассчитывает, что-то ещё.
Это нарушает Принцип единственной обязанности.

in4core 13.09.2014 23:45

Цитата:

_model.currentShar.X=x;
_model.currentShar.Y=y;
Не имеет права вид менять значение модели напрямую. Все оч плохо.

ntro123123 14.09.2014 00:02

1) опять затупил, давно не ООПешил, спасибо
2) ну да, он наследует спрайт чтобы рисовать шар и менять его свойсвтва непосредственно + если будет много таких шаров/экземпляров класса. я так понимаю тут достаточно переменовать в SharBox ?
3) действительно, спасибо.
4) а как подругому? ну скажем на сцене текстовое поле и человек ввел туда цвет. он должен значит изменить и у шара, в мое случае через оболочку класс Shar.
5) вот че тока не ожидал но не этого, вроде и так очень полно пишу, ну в любом случае спасибо.
6) ну да, модель это и должна делать, вот только перересовку я хотел во вьювер отдать в метод UpdateObj, но это геморно.

Добавлено через 2 минуты
Цитата:

Сообщение от in4core (Сообщение 1171920)
Не имеет права вид менять значение модели напрямую. Все оч плохо.


см. 6) пункт ответа. это еще одна причина почему я перересовку не вынес во вьювер.

"оч плохо" - очень прошу как можно подробней. спасибо!

nubideus 14.09.2014 00:13

Цитата:

хотел бы, чтобы меня тыкнули носом в мои ошибки (все, кроме физики объекта), и услышать как бы вы реализовали с точки зрения MVC данный проект, какие есть направления MVC и т.п.
все бред.

> отскок (вместо него костыль который обнуляет скорость, когда шарик касается "пол" сцены)
сначала программировать научись, потом уже разбирайся в паттернах проектирования.
иначе заработаешь себе ооп головного мозга.
https://ru.wikipedia.org/wiki/KISS_(...6%D0%B8%D0%BF)

и архивируй в zip.

Gerbert 14.09.2014 00:16

2) Сейчас ещё посмотрел на класс Шар и могу сказать, что посоветовать мне особо нечего из-за того,
что я не понимаю, что означают свойства, могу лишь догадываться.
2) Вы не понимаете, что такое дисплей лист.
2) Вы не понимаете, что значит наследовать и ещё нужно знать, что такое композиция.
6) Нет, она должна объединять работу классов-модулей, но не быть всем сразу и при том одновременно.

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

Добавлено через 4 минуты
Цитата:

все бред.
У всех был такой бред... У Вас прошел? Вы можете подсказать или можете только говорит бред-бред.
Цитата:

сначала программировать научись
А это что означает? Лично я по коду вижу, что ТС умеет писать код и даже, наверняка осмысленно.
Ему не хватает знаний.

Добавлено через 16 минут
nubideus, а что Вы думаете по поводу модели ТС?

in4core 14.09.2014 00:54

Gerbert - а в чем собственно резон защищать ТС, если ты даже сам понимаешь, что ему не хватает знаний даже на дисплейЛист, самое основное и первое в АС! Нужно нагло отправлять читать книжки и все тут. Я лично замечаю небольшую болезнь полубога.

nubideus 14.09.2014 00:59

Цитата:

ТС умеет писать код
А Я БАЛЕРИНА

> а что Вы думаете
Код AS3:

                public function set E(e:Number):void
                {
                        _E=e;
                }
 
                public function get E():Number
                {
                        return _E;
                }
 
                public function set M(m:Number):void
                {
                        _M=m;
                }
 
                public function get M():Number
                {
                        return _M;
                }
 
                public function set V(v:Number):void
                {
                        _V=v;
                }
 
                public function get V():Number
                {
                        return _V;
                }
 
                public function set A(a:Number):void
                {
                        _A=a;
                }
 
                public function get A():Number
                {
                        return _A;
                }
 
                public function set direc(d:Number):void
                {
                        _direc=d;
                }
 
                public function get direc():Number
                {
                        return _direc;
                }

а тут думать не надо, удалять весь этот "код", который написан "наверняка осмысленно"

Цитата:

Напишите, что означают все свойства в классе Шар, я покажу, как будет лучше.
очевидно же,
private var _X:Number;
private var _Y:Number;
private var _M:Number; // масса
private var _E:Number; // эластичность
private var _R:uint; // радиус
private var _C:uint; // цвет
private var _V:Number=1; // наверное скорость
private var _A:Number; // хз, прозрачность поди, если цвет есть
private var _direc:Number=1.5*Math.PI; // направление

Gerbert 14.09.2014 01:11

Цитата:

Gerbert - а в чем собственно резон защищать ТС
Да, для меня есть. Мне очень хочется привлечь к этой теме форумчан и узнать их мнение о МОДЕЛИ.
Цитата:

Я лично замечаю небольшую болезнь полубога.
Всего полу?))) Голову с плеч чтоль?)))

ntro123123 14.09.2014 14:18

Цитата:

сначала программировать научись, потом уже разбирайся в паттернах проектирования.
Цитата:

понять что такое MVC и ООП
научиться кодить на !!!AS3!!!
В паттернах я хочу разобраться не только для AS3, для других ООП языков было бы тоже не плохо)


Цитата:

Сейчас ещё посмотрел на класс Шар и могу сказать, что посоветовать мне особо нечего из-за того,
что я не понимаю, что означают свойства, могу лишь догадываться.
все как и сказал nubideus кроме:
private var _A:Number; // в школе буквой a обозначали ускорение.


Цитата:

Вы не понимаете, что такое дисплей лист.
Список отображения, куда нужно добавлять объекты чтобы они отобразились на сцену. Я так понимаю можно обойтись без спрайта (т.е. не наследовать спрайт), но тогда придеться сам шар рисовать через свою функцию (по формуле x*x+y*y=R*R), а не через graphics.drawCircle(). Или я вообще не то щас написал сказал?

Цитата:

Вы не понимаете, что значит наследовать и ещё нужно знать, что такое композиция.
почему? шар наследует спрайт, чтобы использовать его свойства и методы, в моем случае graphics юзаю. Поконкретней что именно не так.


Цитата:

Нет, она должна объединять работу классов-модулей, но не быть всем сразу и при том одновременно.

события она не слушает, отображение не занимается (за исключением непосредственного изменения координат), вы имеете ввиду загружать данные (из set.txt) можно в самом контроллере?


Цитата:

а тут думать не надо, удалять весь этот "код", который написан "наверняка осмысленно"
наверное вы специально упустили те сетеры где работа идет с graphics? так вот, мне стало обидно за мой класс шар, что где-то есть сетеры для какихто свойств, а где-то нету, и я решил поставитьсетеры и гетеры на все =) бред? ок, спасибо, исправлюсь.



P.S. мне от вас нужно просто получить знания ГДЕ у меня бред (вот как nubideus вырезал кусок кода и сказал что ***** полное, я понял и исправлюсь), и как сделать правильно, и через 2-3 проекта я буду писать код более приемлемый. Не которые вещи я знаю что бред, но не достаточно знаний языка AS для того чтобы сделать правильно как я считаю, вот немного "костылю" в надежде что вы скажите: "у вас там костыль ***, надо делать так ***".

P.S.S. покажите мне человека у которого есть знания и он пишет на форуме вопросы? Иначе по вашей логике всех нужно посылать читать книжку, только после прочтения ваш форум не нужен будет в 99.99% случаев.

Всем спасибо, жду ваших ответов, советов и дальнейших обоснованных обсираний моего кода.


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

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