Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Качество кода. (http://www.flasher.ru/forum/showthread.php?t=207963)

ZackMercury 22.05.2014 02:05

Качество кода.
 
Вложений: 2
Недавняя тема вдохновила меня на выкладывание своего гoвнoкода в целях узнать, насколько он для вас весомый, логичный и читабельный.
Если что, можете материться, но я этого не говорил.

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

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

Чтобы было понятно, с чем имеем дело, то вот скриншот консоли.

P.S. Для фона TextField тоже хотел задать альфу, но не нашёл для этого метода. Если знаете, как, то прошу подсказать.

caseyryan 22.05.2014 07:51

Цитата:

P.S. Для фона TextField тоже хотел задать альфу, но не нашёл для этого метода. Если знаете, как, то прошу подсказать.
1) Отрубаешь фон
2) Добавляешь под TF спрайт и рисуешь фон в нем по размерам TF с заданной альфой
3) Профит

п.с. В лом качать и открывать код. Лучше сюда выкладывать в теги as3

ZackMercury 22.05.2014 11:47

Цитата:

Лучше сюда выкладывать в теги as3
Окей.
S.as
Код AS3:

package com.general 
{
        import flash.text.TextFormat;
        import flash.text.TextFormatAlign;
        import flash.text.Font;
        import flash.text.TextField;
        import flash.display.DisplayObject;
 
        public class S
        {
                public static const RED:uint = 0xd04242;
                public static const GREEN:uint = 0x4ade51;
                public static const DARK_GREEN:uint = 0x68ab51;
                public static const BLACK:uint = 0x000000;
                public static const ORANGE:uint = 0xeba326;
                public static const DARK_ORANGE:uint = 0xdc8620;
                public static const YELLOW:uint = 0xebe426;
 
                public static const LIGHT_BLUE:uint = 0xa9fff8;
                public static const BLUE:uint = 0x4ac5ff;
                public static const DARK_BLUE:uint = 0x6a93de;
                public static const SIREN_BLUE:uint = 0xba7ffe;
                public static const VIOLET:uint = 0x7d27ff;
                public static const WHITE:uint = 0xf0fae3;
 
                public static const CONSOLAS:int = 0;
                public static const FINAL_FRONTIER:int = 1;
 
                public static function getTextFormat(fontName:int):TextFormat
                {
                        var font:Font;
 
                        switch (fontName)
                        {
                                case CONSOLAS:
                                        font = new Consolas_font();
                                break;
 
                                case FINAL_FRONTIER:
                                        font = new FinalFrontier_font();
                                break;
                        }
 
 
                        var tf:TextFormat = new TextFormat();
                        tf.font = font.fontName;
                        tf.size = 20;
                        tf.align = TextFormatAlign.RIGHT;
                        return tf;
                }
 
                public static function getRedText(font:int):TextFormat
                {
                        var tf:TextFormat = getTextFormat(font);
                        tf.color = RED;
                        return tf;
                }
 
                public static function getWhiteText(font:int):TextFormat
                {
                        var tf:TextFormat = getTextFormat(font);
                        tf.color = WHITE;
                        return tf;
                }
 
                public static function getText(color:uint, font:int, align:String, size:Number):TextFormat
                {
                        var tf:TextFormat = getTextFormat(font);
                        tf.color = color;
                        tf.align = align;
                        tf.size = size;
                        return tf;
                }
 
                public static function appendPadding(tf:DisplayObject, width:int, height:int, padding:int):void
                {
                        tf.height = height - padding * 2;
                        tf.width = width - padding * 2;
                        tf.x += padding;
                        tf.y += padding;
                }
        }
 
}

LiteButton.as

Код AS3:

package com.general 
{
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.text.TextFormatAlign;
        import flash.events.MouseEvent;
        import flash.geom.ColorTransform;
 
        public class LiteButton extends Sprite
        {
                private const BUTTON_COLOR:uint = 0x384434;
                private const BUTTON_BORDER_COLOR:uint = 0x172113;
                private const TEXT_COLOR:uint = 0x9ca987;
 
                private const ORIGINAL_CT:ColorTransform = new ColorTransform(1,1,1);
                private const OVER_CT:ColorTransform = new ColorTransform(1.1, 1.1, 1.1);
                private const HOLD_CT:ColorTransform = new ColorTransform(0.9, 0.9, 0.9);
 
                private var _tf:TextField;
                private var _onClick:Function;
 
                private var _over:Boolean;
 
                public function LiteButton(caption:String = "", width:int = 75, height:int = 25, onClick:Function = null)
                {
                        trace("... LiteButton initialized.");
                        _onClick = onClick;
 
                        drawBackground(width, height);
                        drawTextField(caption);
 
                        super.buttonMode = true;
 
                        addListeners();
                }
 
                public function setCaption(caption:String):void
                {
                        _tf.text = caption;
                }
 
                private function addListeners():void
                {
                        super.addEventListener(MouseEvent.MOUSE_DOWN, darkerColor);
                        super.addEventListener(MouseEvent.MOUSE_UP, returnColor);
                        super.addEventListener(MouseEvent.ROLL_OVER, brighterColor);
                        super.addEventListener(MouseEvent.ROLL_OUT, returnColorFromRoll);
                        super.addEventListener(MouseEvent.CLICK, handleClick);
                }
 
                private function handleClick(e:MouseEvent):void
                {
                        _onClick();
                }
 
                private function darkerColor(e:MouseEvent):void
                {
                        super.transform.colorTransform = HOLD_CT;
                }
 
                private function brighterColor(e:MouseEvent):void
                {
                        _over = true;
                        super.transform.colorTransform = OVER_CT;
                }
 
                private function returnColor(e:MouseEvent):void
                {
                        if(_over) super.transform.colorTransform = OVER_CT;
                        else super.transform.colorTransform = ORIGINAL_CT;
                }
 
                private function returnColorFromRoll(e:MouseEvent):void
                {
                        _over = false;
                        super.transform.colorTransform = ORIGINAL_CT;
                }
 
                private function drawBackground(w:int, h:int):void
                {
                        graphics.lineStyle(1, BUTTON_BORDER_COLOR, 0.7);
                        graphics.beginFill(BUTTON_COLOR, 0.6);
                        graphics.drawRect(0, 0, w, h);
                        graphics.endFill();
                }
 
                private function drawTextField(text:String):void
                {
                        _tf = new TextField();
                        _tf.defaultTextFormat = S.getText(TEXT_COLOR, S.CONSOLAS, TextFormatAlign.CENTER, 12);
                        _tf.mouseEnabled = false;
                        _tf.text = text;
                        _tf.width = super.width;
                        _tf.height = super.height;
                        addChild(_tf);
                }
 
        }
 
}

ScrollBar.as

Код AS3:

package com.general 
{
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.events.MouseEvent;
        import flash.events.Event;
        import com.engine.core.App;
 
 
        public class ScrollBar extends Sprite
        {
                private const MIN_DRAG_HEIGHT:int = 9;
 
                private var _tf:TextField;
                private var _drag:Sprite;
                private var _width:int;
                private var _height:int;
 
                public function ScrollBar(tf:TextField, width:int, height:int)
                {
                        trace("... ScrollBar initialized.");
                        super();
 
                        _tf = tf;
                        _width = width;
                        _height = height;
                        _drag = new Sprite();
 
                        drawBackground();
                        drawDrag();
 
                        updateDrag();
 
                        _drag.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
                        _tf.addEventListener(Event.SCROLL, updateDrag);
                }
 
                private function drawDrag():void
                {
                        _drag.graphics.lineStyle(1, 0x435249, 0.7);
                        _drag.graphics.beginFill(0xb9e6ca, 0.6);
                        _drag.graphics.drawRect(0, 0, _width, _height);
                        _drag.graphics.endFill();
                }
 
                private function startDragging(e:MouseEvent):void
                {
                        _drag.removeEventListener(MouseEvent.MOUSE_DOWN, startDragging);
                        _tf.removeEventListener(Event.SCROLL, updateDrag);
 
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, updateDragging);
                        stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
                }
 
                private function updateDragging(e:MouseEvent):void
                {
                        if(mouseY > _drag.height / 2 && mouseY < _height - _drag.height / 2)
                                _drag.y = mouseY - _drag.height / 2;
                        else
                        {
                                if(mouseY <= _drag.height / 2)
                                        _drag.y = 0;
                                else
                                        _drag.y = _height - _drag.height;
                        }
 
                        _tf.scrollV = Math.round(_tf.maxScrollV * ((_drag.y) / (_height - _drag.height)));
                }
 
                private function stopDragging(e:MouseEvent):void
                {
                        stage.removeEventListener(MouseEvent.MOUSE_MOVE, updateDragging);
                        stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
 
                        _drag.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
                        _tf.addEventListener(Event.SCROLL, updateDrag);
                }
 
                private function drawBackground():void
                {
                        super.graphics.lineStyle(1, 0x0d3d1f, 0.7);
                        super.graphics.beginFill(0x749380, 0.6);
                        super.graphics.drawRect(0, 0, _width, _height);
                        super.graphics.endFill();
                        super.cacheAsBitmap = true;
                }
 
                public function updateDrag(e:Event = null):void
                {
                        _drag.scaleY = 1 - _tf.maxScrollV / _tf.height;
                        if(_drag.scaleY < 0.05)
                        {
                                _drag.scaleY = 1;
                                _drag.height = MIN_DRAG_HEIGHT;
                        }
                        _drag.cacheAsBitmap = true;
                        _drag.y = _tf.scrollV / _tf.maxScrollV * (_height - _drag.height);
                        addChild(_drag);
                }
        }
 
}

Console.as
Код AS3:

package com.general 
{
        import flash.display.Sprite;
        import com.engine.core.App;
        import flash.text.TextField;
        import flash.text.TextFormatAlign;
        import flash.text.TextFieldType;
        import flash.events.KeyboardEvent;
        import flash.ui.Keyboard;
        import flash.events.Event;
 
        public class Console extends Sprite
        {
                private const CONSOLE_VERSION:String = "Developed by SuriTheAngel. Version: 0.3";
 
                private const CONSOLE_HEIGHT:int = 200;
                private const PADDING:int = 5;
                private const SCROLLBAR_WIDTH:int = 10;
                private const FONT_SIZE:int = 10;
                private const MAX_MESSAGES:int = 250;
 
                private const PROMPT_LINE_HEIGHT:int = 20;
                private const CLEAR_BTN_OFFSET:int = 5;
 
                private var _messages:Vector.<String>;
                private var _background:Sprite;
                private var _scrollBar:ScrollBar;
                private var _logField:TextField;
 
                private var _paused:Boolean;
                private var _pauseBtn:LiteButton;
                private var _clearBtn:LiteButton;
                private var _promptField:TextField;
 
                public function Console()
                {
                        _messages = new Vector.<String>();
                        _messages.push(CONSOLE_VERSION);
 
                        //Рисуем задний фон.
                        _background = new Sprite();
                        _background.graphics.lineStyle(1, 0x0d3d1f, 0.7);
                        _background.graphics.beginFill(0x415046, 0.6);
                        _background.graphics.drawRect(0, 0, App.SCR_W - 1, CONSOLE_HEIGHT - 1);
                        _background.graphics.endFill();
 
                        //Само окошко консоли, куда будут выводиться сообщения лога.
                        _logField = new TextField();
                        _logField.defaultTextFormat = S.getText(0xFFFFFF, S.CONSOLAS, TextFormatAlign.LEFT, FONT_SIZE);
                        S.appendPadding(_logField, App.SCR_W - SCROLLBAR_WIDTH, CONSOLE_HEIGHT - PROMPT_LINE_HEIGHT, PADDING);
 
                        //Скроллбар
                        _scrollBar = new ScrollBar(_logField, SCROLLBAR_WIDTH, _logField.height - PADDING * 2);
                        _scrollBar.x = App.SCR_W - 1 - SCROLLBAR_WIDTH;
                        _scrollBar.y += PADDING;
 
                        //Нижняя панель консоли (user_prompt)
                        _clearBtn = new LiteButton("Clear", 90, PROMPT_LINE_HEIGHT, clear);
                        _clearBtn.x = App.SCR_W - _clearBtn.width - CLEAR_BTN_OFFSET;
                        _clearBtn.y = CONSOLE_HEIGHT - _clearBtn.height - PADDING;
 
                        _pauseBtn = new LiteButton("Pause", 90, PROMPT_LINE_HEIGHT, playPause);
                        _pauseBtn.x = _clearBtn.x - _pauseBtn.width - PADDING;
                        _pauseBtn.y = _clearBtn.y;
 
                        _promptField = new TextField();
                        _promptField.defaultTextFormat = S.getText(S.WHITE, S.CONSOLAS, TextFormatAlign.LEFT, 12);
                        _promptField.background = true;
                        _promptField.backgroundColor = 0x364a2f;
                        _promptField.borderColor = 0x23331d;
                        _promptField.border = true;
                        _promptField.width = _pauseBtn.x - PADDING * 2;
                        _promptField.height = PROMPT_LINE_HEIGHT;
                        _promptField.x = PADDING;
                        _promptField.y = _pauseBtn.y;
                        _promptField.type = TextFieldType.INPUT;
                        _promptField.addEventListener(KeyboardEvent.KEY_DOWN, type);
 
                        //Добавляем элементы на сцену
                        //Верхняя часть консоли
                        super.addChild(_background);
                        super.addChild(_logField);
                        super.addChild(_scrollBar);
 
                        //Нижняя часть консоли
                        super.addChild(_clearBtn);
                        super.addChild(_pauseBtn);
                        super.addChild(_promptField);
 
                        super.addEventListener(Event.ADDED_TO_STAGE, focus);
                        super.addEventListener(Event.REMOVED_FROM_STAGE, unfocus);
                }
 
                private function focus(e:Event):void
                {
                        stage.focus = _promptField;
                }
 
                private function unfocus(e:Event):void
                {
                        App.pStage.focus = App.pStage;
                        _promptField.text = "";
                }
 
                private function type(e:KeyboardEvent):void
                {
                        if(e.keyCode == Keyboard.ENTER)
                        {
                                prompt(_promptField.text);
                                _promptField.text = "";
                        }
                }
 
                public function log(message:String, color:uint = 0xFFFFFF):void
                {
                        _messages.push("<font color=\"#"+color.toString(16).replace("0x", "") + "\">" + "<b>system: </b>" + message + "</font>");
                        if(!_paused) update();
                }
 
                public function prompt(message:String):void
                {
                        _messages.push("<font color=\"#" + S.LIGHT_BLUE.toString(16).replace("0x", "") + "\">" + "<b>user_prompt: </b>" + message + "</font>");
                        CommandPrompt.applyCommand(message);
                        update();
                }
 
                public function clear():void
                {
                        _messages = null;
                        _messages = new Vector.<String>();
                        update();
                }
 
                private function playPause():void
                {
                        if(!_paused)
                        {
                                _paused = true;
                                _pauseBtn.setCaption("Resume");
                        }
                        else
                        {
                                _paused = false;
                                _pauseBtn.setCaption("Pause");
                                update();
                        }
                }
 
                private function update():void
                {
                        if(_messages.length >= MAX_MESSAGES)
                        {
                                _messages.splice(0, 50);
                        }
 
                        var str:String = "";
                        for(var i:int = 0; i < _messages.length; i ++)
                        {
                                str += _messages[i];
                                if(i < _messages.length - 1) str += "\n";
                        }
                        _logField.htmlText = str;
                        _logField.scrollV = _logField.maxScrollV;
                        _scrollBar.updateDrag();
                }
 
        }
 
}

CommandPrompt.as

Код AS3:

package com.general 
{
        import com.adobe.utils.StringUtil;
        import flash.display.StageDisplayState;
        import com.engine.core.App;
        import flash.display.StageScaleMode;
 
        public class CommandPrompt
        {
                public static function applyCommand(command:String):void
                {
                        command = command.toLowerCase();
                        command = StringUtil.trim(command);
                        if(command.indexOf("/") < 0)
                        {
                                App.console.log("Console doesn''t understand you.", S.RED);
                                return;
                        }
 
                        var operator;
                        if(command.indexOf(" ") > -1)
                                operator = command.substring(0, command.indexOf(" ")).replace("/", "");
                        else
                                operator = command.replace("/", "");
 
                        var property:String = StringUtil.trim(command.substr(command.indexOf(operator) + operator.length));
                        switch(operator)
                        {
                                case "set":
                                        set(property);
                                break;
 
                                default:
                                        App.console.log("Unknown command " + operator + ".", S.RED);
                                break;
                        }
                }
 
                private static function set(whatToSet:String):void
                {
                        switch(whatToSet)
                        {
                                case "fullscreen":
                                        App.pStage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
                                break;
 
                                case "screen-scale-true":
                                        App.pStage.scaleMode = StageScaleMode.EXACT_FIT;
                                break;
 
                                case "screen-scale-false":
                                        App.pStage.scaleMode = StageScaleMode.SHOW_ALL;
                                break;
 
                                default:
                                        App.console.log("Unknown property " + whatToSet + ".", S.RED);
                                break;
                        }
                }
 
        }
 
}


in4core 22.05.2014 12:52

SuriTheAngel
по первому
1) class S
2) getTextFormat(fontName:int) // сам понимаешь , что тут написано? Вернуть текстФормат, основываясь не на ТЕКСТОВОМ ПОЛЕ, а на каком то имени шрифта, вопервых, во вторых имя шрифта почему то int. Не надо так
3)getRedText и т.п. , ничего не значащие методы, которые не нужны. Вместо них делается 1 метод getColoredText(color:int)
4) appendPadding(tf:DisplayObject - паддинг есть только у TF , ты же принимаешь DisplayObject. Правда в данном случае это не паддинг нифига, тогда неверное обозначение tf, вместо диплейОбж

2 Класс более менее, только коллбек onClick нафиг не нужен. Подписаться можно извне. А если он еще что то делает в этом классе, то 2 подписки. Одна внутри, другая снаружи.

Console - тут лучше всего ( понятнее ) не focus, unfocus - а setFocus , removeFocus. Метод update я бы сделал открытым, бывают часто такие ситуации, когда нужно обновить извне.

Последний читать не стал, отформотируй.

Так по сути, конечно это съедобно, по сравнению с предидущим оратором, но - тут простейших view классы, посему особо обсуждать нечего, только лишь читаемость, о которой я пишу.

ZackMercury 22.05.2014 13:05

in4core, спасибо.
1) Это класс для инструментов работы со строками и текстом, и + цвета.
Класс используется не только консолью, для удобства. Всё равно косяк?
2) Это сделано для удобного получения текстформата. Пример использования прост
Код AS3:

tf.defaultTextFormat = S.getText(S.FINAL_FRONTIER, S.SIREN_BLUE, TextFormatAlign.CENTER, 10);

Разве не удобно? IDE сама подсказывает наличие констант шрифтов(которые int для более быстрой работы, аналог enum в сишках)
3) +
4) +
Цитата:

Подписаться можно извне
Но ведь колбек удобнее и проще, тем более что можно не передавать параметров в вызываемую функцию, которые мне нафиг не нужны. События, тем более, вроде работают медленнее вызова метода. Конечно, я понимаю, однородность, и т.п. :)


Цитата:

Console - тут лучше всего ( понятнее ) не focus, unfocus - а setFocus , removeFocus.
Спасибо.

Цитата:

Последний читать не стал, отформотируй.
Есть.
Да ёпта, хреновый парсер синтаксиса...

alexcon314 22.05.2014 14:18

Плох тот флешер, кто не написал собственный логгер :).
Убери из трейсов одинарные кавычки, форматирование на форуме на них спотыкается.
Код как код, убористый, все линейно. Но лоска явно не хватает.
Не понравилось именование.
darkerColor () и иже с ними (ожидаем что-то типа clickHandler), appendPadding(), class S, set() и playPause(), _drag, type() - очень неудачные названия.
Пихание наружного коллбека в буттон...эмм..не то, чтобы плохо, но вызывает диссонанс. Более ожидаемо (читай стандартно) для кнопки все-таки оповещеть родителя о клике событием. Потом, коллбэки вообще - это довольно радикальная альтернатива ивентам, не следуте торопиться на них подсаживаться.
Ну, комментов подсыпать не мешало бы. Выделение секций приват/публик методов так же приветствуется.

Логгер еще подразумевает и такую штуку, как лог-левел, можно подумать и над этим.
Собственно, логгер - это благодатная тема для прокачки скила :).

оффтоп.
Много раз тут советоваали "Совершенный код" Макконнела.
От себя порекомендую "Практика программирования" (Керниган, Пайк). Эта книга в три раза меньше по объему, более сконцентрирована, практична и технична. Читается очень легко, структуирована так, что вполне может использоваться как спаравка.

ZackMercury 22.05.2014 14:32

Цитата:

оффтоп.
Редко, когда я действительно открываю какие-то книжки, но я постараюсь не лениться :)
А что такое log-level?

in4core 22.05.2014 15:45

Цитата:

Ну, комментов подсыпать не мешало бы
Совершенно не надо, и вообще код комментировать нафиг надо :) Если ты написал код, который требует комментариев internal - это плохой код. Код должен требовать только external - как натив, для чего функция, че делает, что возвращает. Хотя может быть ты об этом же... Комментарии типа приват-паблик по сути только для быстрого доступа, но честно говоря - если это твой код, конечно не написанный 100 лет назад, то ты визуально знаешь, где какой метод находится и без комментов на это. Между прочим эта тема действительно интересная и спорная. Открыв свой код 5 летней давности - мне страшно, как я такое писал - ок, открыв код 2х летней ( заказчик попросил добавить фич ) - я без труда и потери времени разобрался и сделал быстро, - это из расчета , что я не пишу комментариев вообще, кроме как TODO или Crutch

log-level - название в принципе говорит само за себя. getStackTrace - посмотри логгер который я писал, если еще не удалили, там это все было.

ZackMercury 22.05.2014 17:13

Оффтоп - посоветуйте уроки по С# и Unity, можно книжку, можно видео, хоть что-то, что поможет научиться творить шедевры и сохранять порядок в C# :)

alexcon314 22.05.2014 17:17

in4core, хорош уже ко мне цепляться :D.


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

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