Jump to content
Korean Random
aks1983

Создание GUI с помощью Flash Professional

Recommended Posts

Итак, вы уже создали библиотеки lobby.swc, battle.swc и common.swc, а потом программным образом создали окно, а в нём контролы.

Всё хорошо, но хотелось бы в визуальный редактор, типа gui-builder. К тому же, чтобы сделать окно, нужно создавать классы, и добавлять в него контент программно. На самом деле это можно делать во Flash, только с некоторыми оговорками.

 

Для начала, рассмотрим как работает GUI в танках. Что мы знаем:

  • есть набор классов net.wg.gui
  • есть файлы gui*.swf c графикой и анимацией
  • во Flash есть возможность использовать символы из внешних swf
  • во Flash есть возможность подключать swc

Итак, поехали.

Делаем окно с кастомными кнопками - MainView.as

import net.wg.gui.components.controls.SoundButtonEx;
import net.wg.gui.lobby.header.FightButton;
import net.wg.infrastructure.base.AbstractWindowView;

import scaleform.clik.events.ButtonEvent;

public class MainView extends AbstractWindowView {

    public var redButton:FightButton;
    public var buttonNormal:SoundButtonEx;

    public function MainView() {
        super();
    }

    override protected function configUI():void {
        super.configUI();
        window.title = "Моё окно";
        if (redButton) { // можно смело убрать эти if
            redButton.label = "Просто кнопка";
        }
        if (buttonNormal) { // можно смело убрать эти if
            buttonNormal.label = "Закрыть окно";
            buttonNormal.addEventListener(ButtonEvent.CLICK, this.onClickHandler);
        }
    }

    override protected function onDispose():void {
        if (redButton) { // можно смело убрать эти if
            redButton.dispose();
        }
        if (buttonNormal) { // можно смело убрать эти if
            buttonNormal.removeEventListener(ButtonEvent.CLICK, this.onClickHandler);
            buttonNormal.dispose();
        }
        super.onDispose();
    }

    private function onClickHandler(param1:ButtonEvent):void {
        onWindowCloseS();
    }
}

Создаём пустой Flash, идём в File -> ActionScript Settings... и добавляем в Source Path путь к MainView.as; На втором табе подключаем lobby.swc; снимаем галку "Automatically declare stage instances". В поле Document Class вписываем MainView.

Нажимаем Ctrl+L, создаём новый символ - RedButton с классом RedButton ставим галку "Import for runtime sharing" и вписываем в поле "guiControlsLogin.swf". Аналогично, делаем ButtonNormal, только вместо guiControlsLogin.swf импортируем из guiControlsLoginBattle.swf

Теперь надо создать инстансы символов. Перетащим на сцену RedButton и назовём его redButton, перетащим ButtonNormal и назовём его buttonNormal (они выглядят пустыми). Вы заметили, что в классе MainView есть два публичных поля с аналогичными именами? Попробуем сделать Publish и полученный файл - MainView.swf - поместим в \res_mods\[VERSION]\gui\flash

 

Когда эта swf загрузится, она будет иметь класс документа MainView, в котором redButton и buttonNormal проинициализируются импортированными символами.

Последнее - загрузчик в \res_mods\[VERSION]\scripts\client\gui\mods\mod_test.py:

#
# mod_test.py
#

from gui.Scaleform.framework import ViewTypes
from gui.Scaleform.framework import g_entitiesFactories, ViewSettings, ScopeTemplates
from gui.Scaleform.framework.entities.abstract.AbstractWindowView import AbstractWindowView
from gui.app_loader import g_appLoader
from gui.app_loader.settings import APP_NAME_SPACE
from gui.shared import EVENT_BUS_SCOPE
from gui.shared import events
from gui.shared import g_eventBus

MAIN_VIEW_ALIAS = 'test/mainview'


class MainViewMeta(AbstractWindowView):
    pass


class MainView(MainViewMeta):
    def __init__(self, ctx):
        super(MainView, self).__init__()

    def _populate(self):
        super(MainView, self)._populate()

    def _dispose(self):
        super(MainView, self)._dispose()

    def onWindowClose(self):
        self.destroy()


def onLobbyAppInitialized(event):
    if event.ns != APP_NAME_SPACE.SF_LOBBY:
        return

    app = g_appLoader.getDefLobbyApp()
    app.loadView(MAIN_VIEW_ALIAS, ctx={})


g_entitiesFactories.addSettings(ViewSettings(MAIN_VIEW_ALIAS, MainView, 'MainView.swf', ViewTypes.WINDOW, None, ScopeTemplates.GLOBAL_SCOPE, False))

# покажем окно сразу после загрузки лобби
g_eventBus.addListener(events.AppLifeCycleEvent.INITIALIZED, onLobbyAppInitialized, EVENT_BUS_SCOPE.GLOBAL)

Вот такой результат получился у меня, кнопки нажимаются (две голубые кнопки вверху - другой эксперимент):

shot_004.jpg

 

 

Думаю, теперь понятно, как делать более сложные интерфейсы - надо импротировать другие контролы. Где они находятся, можно выяснить только посмотрев, что внутри файлов gui*.swf

 

Подводные камни:

  • во Flash не видно размеров контролов, вообще ничего не видно
  • (не проверял, но думаю что) не все gui*.swf можно использовать, некоторые - не загружены
  • Upvote 4

Share this post


Link to post

Short link
Share on other sites

Подводные камни:

Flash Professional покупать ради такого перебор, а пиратить в 2к16 это зашквар...

P.S. в FlashDevelop можно на mxml описать интерфейс, но при этом линкуется в swf всякая бурда ненужная...

Edited by SkepticalFox

Share this post


Link to post

Short link
Share on other sites

(не проверял, но думаю что) не все gui*.swf можно использовать, некоторые - не загружены

При проставлении параметра "Import for runtime sharing", никаких проблем с "не загружены" не возникнет.

Проблемы такого рода возникают если создавать на лету с помощью AS без пред загрузки нужных библиотек.

 

во Flash не видно размеров контролов, вообще ничего не видно

Ну почему же видно, если перед проставлением символу параметра "Import for runtime sharing" добавить на него то что хотите видеть.

У Wargaming-a во flash-е контролы выглядят вот так клик, и знаете, это таки удобно =)

Еще могу посоветовать обратить внимание на "Component definition..." клик, клик, кликклик, клик, если его использовать количество написанного вручную AS кода уменьшается.

 

вы уже создали библиотеки lobby.swc, battle.swc и common.swc

Вместо создания оных можно использовать swc которые предоставляет Wargaming (находятся по пути gui/flash/swc, внутри gui.pkg)

 

Flash Professional покупать ради такого перебор, а пиратить в 2к16 это зашквар...

Согласен, но там подписка копеечная, а если софт еще и прибыль приносит то грех его не купить.

 

 

UP ввиду того что картошка как всегда и файлы из под коробки на данный момент битые, то вот swc.zip

Edited by POLIROID

Share this post


Link to post

Short link
Share on other sites
В 28.12.2016 в 16:43, aks1983 сказал:

Итак, вы уже создали библиотеки lobby.swc, battle.swc и common.swc, а потом программным образом создали окно, а в нём контролы.

Всё хорошо, но хотелось бы в визуальный редактор, типа gui-builder. К тому же, чтобы сделать окно, нужно создавать классы, и добавлять в него контент программно. На самом деле это можно делать во Flash, только с некоторыми оговорками.

 

Для начала, рассмотрим как работает GUI в танках. Что мы знаем:

  • есть набор классов net.wg.gui
  • есть файлы gui*.swf c графикой и анимацией
  • во Flash есть возможность использовать символы из внешних swf
  • во Flash есть возможность подключать swc

Итак, поехали.

Делаем окно с кастомными кнопками - MainView.as


import net.wg.gui.components.controls.SoundButtonEx;
import net.wg.gui.lobby.header.FightButton;
import net.wg.infrastructure.base.AbstractWindowView;

import scaleform.clik.events.ButtonEvent;

public class MainView extends AbstractWindowView {

    public var redButton:FightButton;
    public var buttonNormal:SoundButtonEx;

    public function MainView() {
        super();
    }

    override protected function configUI():void {
        super.configUI();
        window.title = "Моё окно";
        if (redButton) { // можно смело убрать эти if
            redButton.label = "Просто кнопка";
        }
        if (buttonNormal) { // можно смело убрать эти if
            buttonNormal.label = "Закрыть окно";
            buttonNormal.addEventListener(ButtonEvent.CLICK, this.onClickHandler);
        }
    }

    override protected function onDispose():void {
        if (redButton) { // можно смело убрать эти if
            redButton.dispose();
        }
        if (buttonNormal) { // можно смело убрать эти if
            buttonNormal.removeEventListener(ButtonEvent.CLICK, this.onClickHandler);
            buttonNormal.dispose();
        }
        super.onDispose();
    }

    private function onClickHandler(param1:ButtonEvent):void {
        onWindowCloseS();
    }
}

Создаём пустой Flash, идём в File -> ActionScript Settings... и добавляем в Source Path путь к MainView.as; На втором табе подключаем lobby.swc; снимаем галку "Automatically declare stage instances". В поле Document Class вписываем MainView.

Нажимаем Ctrl+L, создаём новый символ - RedButton с классом RedButton ставим галку "Import for runtime sharing" и вписываем в поле "guiControlsLogin.swf". Аналогично, делаем ButtonNormal, только вместо guiControlsLogin.swf импортируем из guiControlsLoginBattle.swf

Теперь надо создать инстансы символов. Перетащим на сцену RedButton и назовём его redButton, перетащим ButtonNormal и назовём его buttonNormal (они выглядят пустыми). Вы заметили, что в классе MainView есть два публичных поля с аналогичными именами? Попробуем сделать Publish и полученный файл - MainView.swf - поместим в \res_mods\[VERSION]\gui\flash

 

Когда эта swf загрузится, она будет иметь класс документа MainView, в котором redButton и buttonNormal проинициализируются импортированными символами.

Последнее - загрузчик в \res_mods\[VERSION]\scripts\client\gui\mods\mod_test.py:


#
# mod_test.py
#

from gui.Scaleform.framework import ViewTypes
from gui.Scaleform.framework import g_entitiesFactories, ViewSettings, ScopeTemplates
from gui.Scaleform.framework.entities.abstract.AbstractWindowView import AbstractWindowView
from gui.app_loader import g_appLoader
from gui.app_loader.settings import APP_NAME_SPACE
from gui.shared import EVENT_BUS_SCOPE
from gui.shared import events
from gui.shared import g_eventBus

MAIN_VIEW_ALIAS = 'test/mainview'


class MainViewMeta(AbstractWindowView):
    pass


class MainView(MainViewMeta):
    def __init__(self, ctx):
        super(MainView, self).__init__()

    def _populate(self):
        super(MainView, self)._populate()

    def _dispose(self):
        super(MainView, self)._dispose()

    def onWindowClose(self):
        self.destroy()


def onLobbyAppInitialized(event):
    if event.ns != APP_NAME_SPACE.SF_LOBBY:
        return

    app = g_appLoader.getDefLobbyApp()
    app.loadView(MAIN_VIEW_ALIAS, ctx={})


g_entitiesFactories.addSettings(ViewSettings(MAIN_VIEW_ALIAS, MainView, 'MainView.swf', ViewTypes.WINDOW, None, ScopeTemplates.GLOBAL_SCOPE, False))

# покажем окно сразу после загрузки лобби
g_eventBus.addListener(events.AppLifeCycleEvent.INITIALIZED, onLobbyAppInitialized, EVENT_BUS_SCOPE.GLOBAL)

Вот такой результат получился у меня, кнопки нажимаются (две голубые кнопки вверху - другой эксперимент):

shot_004.jpg

 

 

Думаю, теперь понятно, как делать более сложные интерфейсы - надо импротировать другие контролы. Где они находятся, можно выяснить только посмотрев, что внутри файлов gui*.swf

 

Подводные камни:

  • во Flash не видно размеров контролов, вообще ничего не видно
  • (не проверял, но думаю что) не все gui*.swf можно использовать, некоторые - не загружены

А можно ли видео тутор?) Я думаю это было бы намного удобнее

Share this post


Link to post

Short link
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...