AntonVK
User-
Posts
156 -
Joined
-
Last visited
-
Days Won
13
Everything posted by AntonVK
-
Добрый день. Прошу прощения, что так поздно увидел ваше сообщение, давно не заходил на форум. По поводу вашего вопроса, вертикальное выравнивание совсем простое, то, что указано в конфиге, то и применяется. Но обратите внимание, сам текст расположен внутри текстового поля и к нему уже интерпретатор применяет вертикальное выравнивание и горизонтальное в рамках этого поля. Ориентироваться визуально на границы шрифта нельзя. Обратите внимание на скриншот, вот как раз выравнивание применяется к границам текстовых полей. Горизонтальное выравнивание сложнее, там суммируются значения в зависимости от разных факторов, но суть та же. По шрифту ориентироваться нельзя. Невидимые границы текстовых полей - другие. В коде это считается просто совсем для вертикального выравнивания clockHrs.y = offsetY + Number(configData.ConfigClock.position.@y); Но еще раз повторю, это применяется к невидимым границам. Сам текст внутри этого поля и там как он уже машинно отрендерится ####### ####### ####### ####### ####### ####### ####### ####### Совершенно не ясно, зачем форум объединяет посты в один, в результате я не могу написать два отдельных поста подряд Обновлено до актуальной версии игры 1.13.0.0. Обновления в шапке.
-
Двоеточие есть. Я все такие вещи проверяю. Это особенности шрифта Micra, так как он не пропорциональный, о чем я писал. Почему и были сделаны отступы в предыдущих версиях. Для шрифта Micra нужно примерно как-то так (это есть в примерах конфигураций) и манипулировать этими параметрами sepWidth="12" offsetHrs="4" offsetMin="4" offsetSec="4" <ConfigClock visible="true" AMPM="false" blink="false" sepWidth="12"> <position x="-10" y="60"/> <text bold="false" color="0xFFFFCC" font="Micra" size="16"/> <filters enable="true" filter="shadow"> <glow blurX="4" blurY="4" color="0x000000" strength="1"/> <shadow angle="45" blurX="2" blurY="2" color="0x000000" distance="2" strength="1"/> </filters> <formatHrs offsetHrs="4">{HH}</formatHrs> <formatMin offsetMin="4">{mm}</formatMin> <formatSec offsetSec="4" visible="true">{ss}</formatSec> <formatAMPM offsetAMPM="4"></formatAMPM> </ConfigClock>
-
Обновлено до актуальной версии игры 1.10.1.x Обновления в шапке. Теперь используются при компиляции оригинальные swc библиотеки WG из gui.pkg ПРОШУ ОБРАТИТЬ ВНИМАНИЕ! Внесены изменения в вывод значений часов, минут, секунд, так как просили убрать отступы у разделителя между часами, минутами, секундами. Теперь ширина разделителя и смещение ширины в текстовых полях значений часов, минут, секунд - настраиваемый параметр. изменения в конфигурационном файле коснулись этой секции. Параметры: sepWidth="0" <formatHrs offsetHrs="0">{HH}</formatHrs> <formatMin offsetMin="0">{mm}</formatMin> <formatSec offsetSec="0" visible="true">{ss}</formatSec> <formatAMPM offsetAMPM="4"></formatAMPM > Необходимо внести соответствующие изменения в ваши конфигуарционные файлы! Примеры конфигураций актуализированы в шапке. <ConfigClock visible="true" AMPM="false" blink="false" sepWidth="0"> <position x="-10" y="57"/> <text bold="false" color="0xFFFFCC" font="UniversCondC" size="22"/> <filters enable="true" filter="shadow"> <glow blurX="4" blurY="4" color="0x000000" strength="1"/> <shadow angle="45" blurX="2" blurY="2" color="0x000000" distance="2" strength="1"/> </filters> <formatHrs offsetHrs="0">{HH}</formatHrs> <formatMin offsetMin="0">{mm}</formatMin> <formatSec offsetSec="0" visible="true">{ss}</formatSec> <formatAMPM offsetAMPM="4"></formatAMPM > </ConfigClock>
-
Вариантов отображения времени на цифровых часах на самом деле много. Вот, например, в поиске https://www.google.com/search?q=цифровые+часы&sxsrf=ALeKk037bw6hsU9MdtxvGbXprm_-_zb5MQ:1589696173596&source=lnms&tbm=isch&sa=X&ved=2ahUKEwj-8ujdn7rpAhUIr4sKHR4GBNIQ_AUoAXoECA4QAw&biw=2560&bih=1329 Тут либо полностью полагаться на реалиизацию в шрифте (как я выше написал, пропорциональный для динамического отображения плохо подходит), либо уже самостоятельно размещать элементы. Я согласен, что если пошёл по пути кастомизации, то непплохо бы возможность выбора размера разделителя предоставить. Что касается приведённого куска кода, с принудительной установкой размера текстового поля в 10px - я не сторонник усложнения, поэтому это не моё видение, а костыль :) Уже прошло много времени, не помню с каким элементом было связано, но абсолютно точно с форматированием вывода текста. В общем, я попробую либо добавить параметр, либо подумать, что можно сделать. P.S. Программирование тоже не моя профессиональная деятельность, хоть я и работаю в IT сфере. ############################## Сделал аналоговые часы. Кому интересно - скачать в шапке
-
К сожалению, этого сделать не получится. <format>{HH}:{mm}:{ss}</format> - так было в самом начале создания мода, пока не появилась возможность расширенного форматирования, выбора шрифта, мигающего разделителя и т.п. Дело в том, что символы у каждого шрифта разные по размерам, в данном случае интересует ширина, у некоторых каждый символ занимает фиксированную позицию, а у некоторых нет. А текст меняется динамически в поле и начинает скакать - смещаться в стороны с каждым новым выводом. Это актуально не для всех шрифтов, но для некоторых выглядит просто отвратительно настолько, что пользоваться такими часами невозможно. В частности для привычного пользователям мода со старых времён шрифта Micra. Существуют шрифты proportional и monospaced. Micra является proportional, что в случае динамического отображения информации плохо. Подробнее можно почитать здесь, для понимания проблемы: https://blog.usejournal.com/proportional-vs-monospaced-numbers-when-to-use-which-one-in-order-to-avoid-wiggling-labels-e31b1c83e4d0 Ну и вот картинка для представления (в случае <format>{HH}:{mm}:{ss}</format> и шрифта Micra вот так начнают смещаться секунды, минуты. ) Поэтому каждая выводимая единица времени и разделитель в том числе помещены в отдельное фиксированное текстовое поле, что было делать гораздо более трудозатратно, чем при использовании конструкции <format>{HH}:{mm}:{ss}</format>, так как нужно считать и учитывать размеры всех текстовых полей, а не одного, и выравнивать их относительно экрана. Здесь похожий момент упоминался. https://kr.cm/f/t/13505/c/422305/
-
Я поправлю все же :) просто никак руки не доходили. вначале нужно импортировать библиотеку для работы с регулярными выражениями import re Ссори, с телефона, не очень удобно подробнее писать. а так там просто удаляется win32|64 из пути. если любопытно, ты можешь читать описание к функциям на оф. Документации к питону, ну и много русскоязычных ресурсов с описанием.
-
странно. По идее не должно. это предполагает дополнительное вмешательство со стороны пользователя. Пусть мод делает правильно самостоятельно. Можно, наверное, и с точкой. Когда создали пакеты модов у меня не получалось путь указать таким образом, поэтому я определял местоположение текущей директории в питоновском скрипте. Да, в этой части кода и исправлю. Обрежу правую часть с win(32|64). Можно и во флеше сделать, но в питоне проще. на выходных обновлю, может раньше, если получится.
-
В этом обновлении опять что-то сломалось, у меня не применяется конфиг, хотя часы с калькулятором работают. Также ничего не пишется в python.log Update: понял, поменялись пути Update2: как временное решение, скопировать директорию (если игра установлена в C:\Games\World_of_Tanks ): C:\Games\World_of_Tanks\mods\configs\AntonVK в C:\Games\World_of_Tanks\win32\mods\configs\AntonVK В win32 директории mods\configs нет, поэтому нужно создать В ближайшее время я исправлю мод.
-
Благодаря этим изменениям решены проблемы: - пропадание часов и калькулятора при преждевременном выходе из боя (если убили, например) - при выборе сервера при входе в танки не надо два раза тыкать на сервер - в бою по нажатию клавиши Enter не теряется фокус на окне чата Это отлично! Скажем спасибо товарищу Ekspoint! Привет! Всем добра! В шапке опубликовал исходные коды модификации. Это одна из самых старых модификаций, времен Серба и добрых танков. (скриншот специально выбирал того времени, когда артоводы доминировали) Жизнь он такая штука, завтра ее может не быть, а часы и калькулятор в ангаре всегда должны быть) Пользуйтесь. Все исходники, шрифты в архивах P.S. На картинке мод от дикей93. Тогда в танках был другой интерфейс визулизации, на AS2, калькулятор у дикея был взят с просторов Интернета и он не учитывал последовательность действий, но это была идея. После того, как картошка перешла на AS3, большинство старых модов сломалось... банальность, как калькулятор, исчез из игры, но были часы! Часы поддерживал игрок макс777, если мне не изменяет память... Это было давно, и тогда моды пихали в logos.swf/ Но настал патч 1.0. и часы по прежнему в ангаре )
-
Доброе утро! В шапке актуальные обновления для текущей версии игры. Кто использует данную модификацию - рекомендую обновиться. - внесены изменения в код AS3 и Python - вроде бы устранилась проблема с пропаданием элементов из ангара при досрочном выходе из боя, но это не точно :) - обновлены примеры конфигураций и скриншоты к ним, а то им 5 лет уже. Функция def _populate(self): уже определена в классе hangarCalculatorButton(View, AbstractViewMeta): Тебе нужно было добавить строчку в неё, а не писать дописывать целиком вниз. Поэтому и не работало.
-
[1.5.x] Вызов окна в ангаре при нажатии кнопки
AntonVK replied to AntonVK's topic in ActionScript & Python
@Ekspoint Большое спасибо! Сегодня добрался проверить, теперь вызов работает нормально. -
Добрый день! Прошу помочь в следующем вопросе. До патча 1.5.х использовал в своем моде следующую конструкцию Python (для кнопки вызова) # import os # from gui.app_loader.loader import g_appLoader from gui.Scaleform import SCALEFORM_SWF_PATH from gui.Scaleform.Flash import Flash from gui.Scaleform.framework import g_entitiesFactories, ViewSettings, ViewTypes, ScopeTemplates from gui.Scaleform.framework.entities.abstract.AbstractViewMeta import AbstractViewMeta from gui.Scaleform.framework.entities.View import View from gui.Scaleform.framework.managers.loaders import SFViewLoadParams from gui.shared import events from gui.app_loader.settings import APP_NAME_SPACE from gui.shared import g_eventBus, EVENT_BUS_SCOPE class hangarCalculatorButton(View, AbstractViewMeta): def __init__(self): View.__init__(self) def _populate(self): View._populate(self) def _dispose(self): View._dispose(self) def py_log(self, text): print('[hangarCalculatorButton]: %s' % text) def py_getWoTPath(self): __WoT__ = os.path.dirname(os.path.abspath(__file__)) __WoT__ = __WoT__[0:__WoT__.rfind('scripts')] return __WoT__ _windowAlias = 'hangarCalculatorButton' _url = 'hangarCalculatorButton.swf' _type = ViewTypes.WINDOW _event = None _scope = ScopeTemplates.GLOBAL_SCOPE _settings = ViewSettings(_windowAlias, hangarCalculatorButton, _url, _type, _event, _scope) g_entitiesFactories.addSettings(_settings) def new_afterCreate(self): old_afterCreate(self) self.addExternalCallback('hangarCalculatorButton.showCalculator', lambda name, alias: g_appLoader.getApp().loadView(SFViewLoadParams('hangarCalculator', 'hangarCalculator'))) old_afterCreate = Flash.afterCreate Flash.afterCreate = new_afterCreate def onAppInitialized(event): if event.ns == APP_NAME_SPACE.SF_LOBBY: app = g_appLoader.getApp(event.ns) if app: app.loadView(SFViewLoadParams(_windowAlias, _windowAlias)) g_eventBus.addListener(events.AppLifeCycleEvent.INITIALIZED, onAppInitialized, scope=EVENT_BUS_SCOPE.GLOBAL) AS3 (для кнопки вызова) package { import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.external.ExternalInterface; import net.wg.gui.lobby.LobbyPage; import net.wg.infrastructure.base.AbstractView; import net.wg.infrastructure.events.LoaderEvent; import net.wg.infrastructure.interfaces.IView; import scaleform.clik.events.ButtonEvent; public class hangarCalculatorButton extends AbstractView implements IhangarCalculatorButton { public function hangarCalculatorButton() { super(); this.init(); } public var py_log:Function; public var py_getWoTPath:Function; private var lobby:LobbyPage = null; private var current_alias:String = ""; private var zCalculatorButton:hCalculatorButton; private function init(param1:Event = null):void { if(!stage) { addEventListener(Event.ADDED_TO_STAGE,this.init); return; } removeEventListener(Event.ADDED_TO_STAGE,this.init); App.containerMgr.loader.addEventListener(LoaderEvent.VIEW_LOADED,this.onViewLoaded); } private function onViewLoaded(param1:LoaderEvent):void { this.processView(param1.view,false); } private function processView(param1:IView, param2:Boolean):void { var view:IView = param1; var populated:Boolean = param2; var _WoT_:String = py_getWoTPath(); try { this.zCalculatorButton = new hCalculatorButton(_WoT_); this.current_alias = view.as_config.alias; this.zCalculatorButton.addEventListener(ButtonEvent.CLICK,this.onCalcBtnClick); if(this.current_alias == "lobby") { this.lobby = view as LobbyPage; this.lobby.header.addChild(this.zCalculatorButton); //py_log("is loaded"); } } catch(error:Error) { py_log("processView" + error.getStackTrace()); } } override protected function nextFrameAfterPopulateHandler():void { if(this.parent != App.instance) { (App.instance as MovieClip).addChild(this); } visible = false; } override protected function onDispose():void { this.zCalculatorButton.removeEventListener(MouseEvent.CLICK,this.onCalcBtnClick); } private function onCalcBtnClick(param1:ButtonEvent):void { var external:Array = new Array(); external.push(this.current_alias); external.unshift("hangarCalculatorButton.showCalculator","hangarCalculatorButton"); ExternalInterface.call.apply(null,external); } } } Эти две вещи между собой взаимодействовали и далее там уже вызывался собственный код. В результате, в ангаре кнопка, нажимаешь кнопку открывается окошко и всё как надо. В текущей версии игрового клиента мои попытки что-то исправить ни к чему не привели. Python исправил следующим образом: Python (для кнопки вызова) # import os # from gui.shared.personality import ServicesLocator from gui.Scaleform import SCALEFORM_SWF_PATH from gui.Scaleform.flash_wrapper import Flash from gui.Scaleform.framework import g_entitiesFactories, ViewSettings, ViewTypes, ScopeTemplates from gui.Scaleform.framework.entities.abstract.AbstractViewMeta import AbstractViewMeta from gui.Scaleform.framework.entities.View import View from gui.Scaleform.framework.managers.loaders import SFViewLoadParams from gui.shared import events from gui.app_loader.settings import APP_NAME_SPACE from gui.shared import g_eventBus, EVENT_BUS_SCOPE class hangarCalculatorButton(View, AbstractViewMeta): def __init__(self): View.__init__(self) def _populate(self): View._populate(self) def _dispose(self): View._dispose(self) def py_log(self, text): print('[hangarCalculatorButton]: %s' % text) def py_getWoTPath(self): __WoT__ = os.path.dirname(os.path.abspath(__file__)) __WoT__ = __WoT__[0:__WoT__.rfind('scripts')] return __WoT__ _windowAlias = 'hangarCalculatorButton' _url = 'hangarCalculatorButton.swf' _type = ViewTypes.WINDOW _event = None _scope = ScopeTemplates.GLOBAL_SCOPE _settings = ViewSettings(_windowAlias, hangarCalculatorButton, _url, _type, _event, _scope) g_entitiesFactories.addSettings(_settings) def new_afterCreate(self): old_afterCreate(self) self.addExternalCallback('hangarCalculatorButton.showCalculator', lambda name, alias: ServicesLocator.appLoader.getApp().loadView(SFViewLoadParams('hangarCalculator', 'hangarCalculator'))) old_afterCreate = Flash.afterCreate Flash.afterCreate = new_afterCreate def onAppInitialized(event): if event.ns == APP_NAME_SPACE.SF_LOBBY: app = ServicesLocator.appLoader.getApp(event.ns) if app: app.loadView(SFViewLoadParams(_windowAlias, _windowAlias)) g_eventBus.addListener(events.AppLifeCycleEvent.INITIALIZED, onAppInitialized, scope=EVENT_BUS_SCOPE.GLOBAL) Python (для самого окна) # from gui.Scaleform import SCALEFORM_SWF_PATH from gui.Scaleform.daapi import LobbySubView from gui.Scaleform.daapi.view.meta.WindowViewMeta import * from gui.Scaleform.flash_wrapper import Flash from gui.Scaleform.framework import g_entitiesFactories, ViewSettings, ViewTypes, ScopeTemplates from gui.Scaleform.framework.entities.View import View from gui.shared import events LobbySubView.__background_alpha__ = 0 class hangarCalculator(LobbySubView, WindowViewMeta): def __init__(self): View.__init__(self) def _populate(self): View._populate(self) def _dispose(self): View._dispose(self) def onTryClosing(self): return True def onWindowClose(self): self.destroy() def py_log(self, text): print('[hangarCalculator]: %s' % text) _windowAlias = 'hangarCalculator' _url = 'hangarCalculator.swf' _type = ViewTypes.WINDOW _event = None _scope = ScopeTemplates.DEFAULT_SCOPE _settings = ViewSettings(_windowAlias, hangarCalculator, _url, _type, _event, _scope) g_entitiesFactories.addSettings(_settings) Ожидаемо, заменить только g_appLoader на ServicesLocator.appLoader.getApp() ничем не помогло в данном случае. Для AS3 код части, которая взаимодействует с Python, ничего не менял. Для кнопки код выше для окна вот (на всякий случай) package { import flash.display.MovieClip; import net.wg.infrastructure.base.AbstractWindowView; public class hangarCalculator extends AbstractWindowView { public function hangarCalculator() { super(); isCentered = true; } public var py_log: Function; private var zCalculator:hCalculator; override protected function onPopulate():void { super.onPopulate(); } override protected function onDispose():void { super.onDispose(); } override protected function configUI():void { try { super.configUI(); } catch(error:Error) { py_log("configUI " + error.getStackTrace()); } } } } Что в итоге, кнопка на месте, окно не вызывается. Буду признателен за помощь в решении проблемы. Спасибо!