Como abordar os elementos da GUI?

12

Nota: Planejo criar meu próprio sistema GUI. Vai ser bom para aprender, leve, só tem pedaços de que preciso, vincula-se ao jogo, etc.

Eu estava pensando em como fazer isso. Os elementos que eu quero dizer são:

  • Botões do rádio
  • Inserir caixas de texto aqui
  • Botões
  • Sliders
  • Caixas de seleção

Ainda não estou pensando em como fazê-los. Mas mais de como eles iriam.

Idéia

Eu teria cada estado que precisasse de coisas, então quase todas, teriam um contêiner de elementos. Cada elemento é uma peça da GUI.

Cada um deles possui posição, gráfico, etc.

A parte em que fico mais preso é a lógica deles.

Minha idéia para isso, permitir modularidade e simplicidade, foi evitar um MainMenuStartButton; a OptionsOneBackButton, etc. e, em vez disso, pode executar o Slider slider1; ou Botão iniciar ;.

Em vez disso, cada um deles teria uma função boost :: para uma função em um namespace da GUI, como Gui :: StartButtonClick ou GUI :: ColourSliderHover.

Eu só estava me perguntando se isso seria excepcionalmente lento ou não.

E, nesse caso, existe alguma maneira fácil e simples de executar a GUI para jogos? Sem Qt, wxWidgets ou qualquer coisa.

O Pato Comunista
fonte

Respostas:

15

A GUI não é um problema fácil ou simples, especialmente quando você entra em jogos e deseja ter menus dinâmicos e interessantes.

Uma coisa "fácil" que você pode fazer é tentar usar o middleware. Há uma pergunta sobre isso aqui .

Se você vai fazer a rolagem, há algumas coisas que eu sugeriria.

  • Os elementos da GUI geralmente têm um "pai", outro elemento da GUI ou uma "janela" ou algo parecido. Apontar para cima ou apontar o pai para baixo significa que você pode definir estado / posição / etc em tudo que é filho.

  • Você pode criar elementos da GUI por composição. Muitos widgets têm rótulos (praticamente todos), e pode fazer sentido transformar o conceito de rótulo em um componente ou filho de seus outros elementos da interface do usuário do que copiar / colar o código ou tentar herdar de uma classe base com funcionalidade de etiqueta.

  • Muitos dos chamados widgets especializados são apenas botões disfarçados. Caixas de seleção são apenas botões com estados e imagens especiais. Os botões de opção são apenas caixas de seleção com metaestado (um e apenas um está ativo a qualquer momento) com outros botões de opção. Use isso para sua vantagem. Em um jogo em que trabalhei, "caixas de seleção" eram feitas com botões regulares inteiramente por meio de scripts e arte.

  • Para o seu primeiro projeto, considere a rota mais direta. Sim, torne seus eventos acionáveis ​​delegados e atribua o que você precisa na criação de elementos (por exemplo, onMouseButtonDown, onMouseButtonUp, onHover etc), mas considere codificar apenas o que você deseja que aconteça (por exemplo, mudar a cor do cursor, pressionar o botão) até obter algo funcional. Quando estiver nesse ponto, considere criar esses dados de comportamento (por exemplo, tenha uma variável no botão para "pressionar o som" ou talvez tenha componentes que seus elementos de interface do usuário usem para definir o comportamento que você apenas anexa a eles quando os cria.

  • os delegados não são tão lentos, você provavelmente não terá tantos widgets que isso seria um problema, e o código do menu geralmente não é de alto impacto. Eu não me preocuparia muito com o desempenho neste momento do jogo. Não escolha algoritmos e perfis ingênuos depois de colocar seu código em funcionamento.

Tetrad
fonte
2
Para coisas mais complexas da GUI, você precisará de algum tipo de gerenciamento de layout em breve. Layouts básicos como HBox e VBox são muito mais fáceis de usar do que posicionar todos os elementos com coordenadas absolutas. Exemplo: web.archive.org/web/20100410150433/http://doc.qt.nokia.com/4.6/... que torna a sua GUI fácil de usar, mas não tão fácil de implementar;)
bummzack
8

Houve alguns avanços realmente interessantes nos kits de ferramentas de interface do usuário convencionais nos últimos anos. As interfaces de jogo também estão evoluindo, mas em um ritmo um pouco mais lento. Isso é provável porque o desenvolvimento de um subsistema de interface do usuário com todos os recursos é uma tarefa significativa por si só e é difícil justificar o investimento em recursos.

Meu sistema de interface do usuário favorito é o Windows Presentation Foundation (WPF). Realmente leva o potencial de diferenciação da interface do usuário para o próximo nível. Aqui estão algumas de suas características mais interessantes:

  1. Os controles são "sem aparência" por padrão. A lógica e a aparência visual de um controle geralmente são dissociadas. Todo controle é fornecido com um estilo e modelo padrão, que descreve sua aparência visual padrão. Por exemplo, um botão pode ser representado como um retângulo arredondado com um traço externo, uma cor sólida ou um fundo gradiente e um apresentador de conteúdo (para apresentar a legenda). Os desenvolvedores (ou designers) podem criar modelos de estilos personalizados que alteram a aparência e (em certa medida) o comportamento de um controle. Os estilos podem ser usados ​​para substituir propriedades simples de um controle, como cor de primeiro plano / plano de fundo, modelo etc. modelos alteram a estrutura visual real.

  2. Estilos e modelos podem incluir "Disparadores". Os gatilhos podem ouvir determinados eventos ou valores de propriedade (ou combinações de valores) e alterar condicionalmente aspectos de um estilo ou modelo. Por exemplo, um modelo de botão geralmente teria um gatilho na propriedade "IsMouseOver" com a finalidade de alterar a cor do plano de fundo quando o mouse passar o mouse sobre o botão.

  3. Existem alguns "níveis" diferentes de elementos da interface do usuário, que variam de elementos de peso mais leve com funcionalidade mínima a controles de peso pesado completos. Isso permite flexibilidade na estrutura da interface do usuário. A mais simples das classes de elementos da interface do usuário,, UIElementnão possui estilo ou modelo e suporta apenas o mais simples dos eventos de entrada. Para elementos simples, como indicadores de status, essa funcionalidade pode ser tudo o que você precisa. Se você precisar de suporte de entrada mais extenso, poderá derivar de FrameworkElement(que se estende UIElement). Os widgets tradicionais geralmente derivam Control, o que estende FrameworkElemente adiciona estilo personalizado e suporte a modelos (entre outras coisas).

  4. O WPF usa um modelo de gráficos vetoriais retido, escalável e independente de resolução. No Windows, os aplicativos WPF são renderizados e compostos usando o Direct3D.

  5. A introdução do WPF incluiu uma nova linguagem de programação declarativa chamada Xaml. Xaml, baseado em Xml, é o idioma preferido para declarar "cenas" da interface do usuário. Na verdade, é bastante liso e, embora possa parecer semelhante à primeira vista, é fundamentalmente diferente dos idiomas existentes como o XUL (e muito mais poderoso).

  6. O WPF possui um subsistema de texto muito avançado. Ele suporta quase todos os recursos de fonte OpenType, antialiasing bidirecional ClearType, posicionamento de subpixel, etc.

"Ok, ótimo, agora, como isso é relevante para o desenvolvimento de jogos?"

Quando o WPF ainda estava em desenvolvimento (e conhecido como "Avalon"), eu estava fazendo um curso de design de videogames na Georgia Tech. Meu projeto final foi um jogo de estratégia baseado em turnos e eu queria uma interface do usuário muito capaz. O WPF / Avalon parecia um bom caminho a percorrer, porque tinha um conjunto completo de controles completos e me permitia alterar completamente a aparência e o controle desses controles. O resultado foi um jogo com uma interface de usuário bonita e nítida, com o nível de funcionalidade que você normalmente só vê em aplicativos completos.

Agora, o problema com o uso do WPF para jogos é que ele é bastante pesado e é renderizado em sua própria "caixa de areia". Com isso, quero dizer que não há maneira suportada de hospedar o WPF em um ambiente de jogo Direct3D ou OpenGL. É possível hospedar o conteúdo do Direct3D em um aplicativo WPF, mas você ficará limitado pela taxa de quadros do aplicativo WPF, que geralmente é menor do que o desejado. Para alguns tipos de jogos, como jogos de estratégia 2D (captura de tela do meu projeto de jogo atual do WPF), ainda pode funcionar muito bem. Para qualquer outra coisa, nem tanto. Mas você ainda pode aplicar alguns dos conceitos arquiteturais mais atraentes do WPF no desenvolvimento de sua própria estrutura de interface do usuário.

Há também uma implementação de código aberto do C ++ / Direct3D não gerenciada do WPF chamada "WPF / G (WPF para jogos)"]] ( http://wpfg.codeplex.com/ ) projetada especificamente para uso em jogos no Win32 e Windows Mobile. O desenvolvimento ativo parece ter cessado, mas a última vez que fiz o check-out, foi uma implementação bastante completa. O subsistema de texto era a única área que realmente faltava em comparação com a implementação WPF da Microsoft, mas isso é menos problemático para jogos. Eu imaginaria que integrar o WPF / G a um mecanismo de jogo baseado no Direct3D seria relativamente simples. Seguir essa rota pode fornecer uma estrutura de interface do usuário extremamente capaz e independente de resolução, com amplo suporte à personalização da interface do usuário.

Apenas para lhe dar uma ideia de como seria uma interface de jogo baseada em WPF, aqui está uma captura de tela do meu projeto de estimação:

Captura de tela do meu projeto de jogo baseado em WPF em andamento

Mike Strobel
fonte
NoesisGUI usa WPF. É muito bom, mas não conheço o WPF e acho difícil aprender. Eu preferiria uma abordagem de pilha da web pessoalmente.
User441521
2

Eu usaria uma GUI imediata, como esta: http://code.google.com/p/nvidia-widgets/

Os widgets da nVidia são baseados em IMGUI (Immediate GUI) da MollyRocket.

Eu acho que é o mais simples que uma GUI pode obter.

Tudo depende de quais são suas necessidades.

jacmoe
fonte
1
Simples, sim e ideal para trabalhos de depuração rápida ou prototipagem, mas a quantidade de acoplamento entre a interface do usuário e a lógica do jogo nas GUIs imediatas me assusta.
Tenpn
2

No jogo em que estou trabalhando, temos nossa própria estrutura de interface gráfica personalizada. Descobri que é muito simples, mas ainda estou fazendo tudo o que quero. Não sei se é um "padrão" que muitos outros usam, mas funciona bem para nós.

Basicamente, todos os botões, caixas de seleção etc. são subclasses da classe Element; e elementos têm eventos. Depois, temos CompoundElements (que são eles próprios uma subclasse de Element), que contêm outros elementos. Em cada ciclo, três métodos são chamados: processEvent (evento), tick (tempo) e draw (superfície). Cada CompoundElement chama esses métodos em seus elementos filhos. Nessas chamadas (particularmente o método processEvent), disparamos quaisquer eventos relevantes.

Tudo isso está em Python (uma linguagem muito mais lenta que C ++) e funciona perfeitamente bem.

Smashery
fonte
2

Se você precisar de interfaces de usuário bastante sofisticadas, provavelmente a melhor opção é incorporar um renderizador de HTML - você obtém todas as primitivas de interface de usuário comuns com as quais está acostumado e pode adicionar trivialmente uma interface de usuário complexa ao seu jogo que se comportará da maneira os usuários esperam, ficam ótimos e correm rápido (porque os navegadores têm pipelines de renderização bastante otimizados neste momento).

Existem algumas bibliotecas disponíveis para incorporar Webkit em jogos: o Berkelium é o que eu recomendo, e ouço que o Awesomium é muito bom (usado pelo EVE Online) e o CEF (usado pelo Steam). Você também pode tentar incorporar o Gecko - é muito mais difícil de fazer, mas também tem algumas vantagens interessantes. Atualmente, estou usando o Berkelium para toda a interface do jogo (substituiu uma combinação de elementos personalizados da interface do usuário e da interface do usuário nativa e reduziu drasticamente a quantidade de código que eu tinha que escrever para executar as coisas).

Kevin Gadd
fonte
^ Este 100%. Estou triste com a falta de uma boa pilha da Web para implementações de jogos por aí. A pilha da Web é brilhante para a interface do usuário e precisa começar a ser mais comum em todos os jogos para a interface do usuário. Até agora, as bibliotecas com as quais eu tentei trabalhar eram difíceis de implementar ou não são 100% verdadeiras html / css / javascript. Atualmente, estou olhando para o Coherent Labs e parece promissor, mas custa uma quantia justa, mas tem versões independentes para alguns motores.
User441521
2

Certifique-se de que você realmente precisa de um sistema GUI sofisticado para o seu jogo. Se você estiver criando um RPG de computador, obviamente será um requisito; mas para algo como um jogo de corrida, não complique demais as coisas. Às vezes, apenas renderizar texturas (imagens de botão personalizadas) e ter algumas instruções "if" com coordenadas codificadas na função de entrada podem fazer o trabalho. Uma máquina de estado de jogo (FSM) ajuda com essa abordagem simples. Ou, em algum lugar no meio, esqueça a hierarquia complicada e a abordagem dos gráficos de cena e apenas tenha uma classe "Button" que empacota a textura acima mencionada e as verificações de entrada em simples chamadas de função, mas não faz nada complicado.

Pregar suas necessidades é importante. Se não tiver certeza, lembre-se YAGNI .

Ricket
fonte
1

Aqui está um exemplo (código fonte e tudo) de uma GUI criada para o OpenGL, especificamente para o Slick2D, chamada Thingle, que é uma porta do Thinlet .

Outra GUI do Slick2D foi a SUI, que você pode querer conferir.

Eu seguiria esses exemplos e iria com uma GUI orientada a XML. Embora esses projetos sejam antigos / mortos, você pode conseguir algumas idéias deles.

Bryan Denny
fonte
1

Acho que uma das melhores maneiras de "descobrir" seria ver como as estruturas de GUI altamente desenvolvidas funcionam, como o Windows Forms no .NET.

Por exemplo, todos eles são Controles, que têm um local, tamanho, lista de controles filhos, uma referência ao pai, uma Textpropriedade para o que o controle possa usá-lo, além de várias funções substituíveis e ações predefinidas.

Todos eles contêm vários eventos, como Click, MouseOvere Resizing.

Por exemplo, quando um controle filho é alterado, ele envia uma notificação na cadeia informando que seu layout foi alterado e todos os pais chamam PerformLayout() .

Além disso, o dimensionamento automático e o arranjo automático são recursos comuns dessas GUIs, permitindo que os programadores adicionem controles e os controles pai os ajustem ou organizem automaticamente.

Nick Bedford
fonte
1

Por interesses, pensei em jogar fora o Scaleform . Basicamente, os artistas podem usar o ilustrador, o photoshop etc., e o designer da interface do usuário usa o Flash para organizar toda a interatividade. Em seguida, o Scaleform o transforma em código para o seu mecanismo (bem, isso é meu entendimento, pois eu não o usei). O Crysis Warhead usou esse sistema para o lobby deles.

Allan
fonte