Creare Videogiochi - Game Developer
Tutorial 5 - User Interface - Versione stampabile

+- Creare Videogiochi - Game Developer (https://www.making-videogames.net/giochi)
+-- Forum: Altri Programmi per la Creazione di Videogames (https://www.making-videogames.net/giochi/Forum-Altri-Programmi-per-la-Creazione-di-Videogames)
+--- Forum: Irrlicht Engine (https://www.making-videogames.net/giochi/Forum-Irrlicht-Engine)
+--- Discussione: Tutorial 5 - User Interface (/thread-Tutorial-5-User-Interface)



Tutorial 5 - User Interface - Chip - 10-08-2015

Tutorial 5: User Interface

[Immagine: 005shot.jpg]

Questo tutorial spiega come utilizzare la User Interface (UI) integrata in Irrlicht Engine. Verrà fornita una breve panoramica su come si creano finestre, pulsanti, scrollbars, etichette di testo e listbox. Come sempre iniziamo mostrando l'header dove si utilizza il namespace irr e diamo indicazioni al linker di inserire la libreria irrlicht.lib. Creiamo anche una variabile puntatore al device Irrlicht, una variabile per gestire la posizione della finestra e un puntatore ad una listbox.
Codice PHP:
#include <irrlicht.h>
#include "driverChoice.h"

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
    
IrrlichtDevice *device;
    
s32             counter;
    
IGUIListBox*    listbox;
};

// Define some values that we'll use to identify individual GUI controls.
enum
{
    
GUI_ID_QUIT_BUTTON 101,
    
GUI_ID_NEW_WINDOW_BUTTON,
    
GUI_ID_FILE_OPEN_BUTTON,
    
GUI_ID_TRANSPARENCY_SCROLL_BAR
}; 
Variamo la trasparenza dello skin della nostra GUI agendo sul valore alpha della proprietà skin-colors.
Codice PHP:
void setSkinTransparency(s32 alphairr::gui::IGUISkin skin)
{
    for (
s32 i=0i<irr::gui::EGDC_COUNT ; ++i)
    {
        
video::SColor col skin->getColor((EGUI_DEFAULT_COLOR)i);
        
col.setAlpha(alpha);
        
skin->setColor((EGUI_DEFAULT_COLOR)icol);
    }

L'Event Receiver non è solo in grado di catturare gli eventi dalla tastiera o dal mouse, può anche catturare gli eventi che provengono dalla GUI. Ogni componente ha i suoi eventi: un click sul pulsante, la selezione di un range per la Listbox, tutti eventi che ci dicono quando un elemento ha interagito con i nostri input. Per gestire la reazione a questi eventi creiamo un event receiver. Reagiremo solo ad eventi della GUI e quando ciò accadrà andremo a prenderci l'id del chiamante (cioè identifichiamo chi della componente GUI ha sollevato l'evento) e con questo otterremo il puntatore a quell'elemento grafico.
Codice PHP:
class MyEventReceiver : public IEventReceiver
{
public:
    
MyEventReceiver(SAppContext context) : Context(context) { }

    
virtual bool OnEvent(const SEventevent)
    {
        if (
event.EventType == EET_GUI_EVENT)
        {
            
s32 id event.GUIEvent.Caller->getID();
            
IGUIEnvironmentenv Context.device->getGUIEnvironment();

            switch(
event.GUIEvent.EventType)
            { 
Quando la scrollbar cambia la sua posizione e capiamo che si tratta della “nostra” (quella con l'id GUI_ID_TRANSPARENCY_SCROLL_BAR) allora andremo a cambiare la trasparenza di tutti gli elementi della GUI. La cosa è facile perché c'è l'oggetto skin che contiene tutti i settaggi dei colori. Basterà scorrerci tutti questi valori e cambiare di conseguenza il valore alpha.
Codice PHP:
case EGET_SCROLL_BAR_CHANGED:
                  if (
id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
                {
                    
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
                    
setSkinTransparency(posenv->getSkin());
                }
                break; 
Quando un pulsante è premuto ed è uno dei nostri. Se è il primo chiudiamo l'engine. Se il secondo andiamo a creare un'altra finestra con del testo dentro “Test windows”. Inseriamo anche nella listbox che fa da log quello che accade. Se è il terzo pulsante apriamo una finestra di dialogo di tipo “Apri file” e anche in questo caso aggiungiamo al log sulla listbox. Questo è tutto per levent receiver.
Codice PHP:
case EGET_BUTTON_CLICKED:
                  switch(
id)
                {
                case 
GUI_ID_QUIT_BUTTON:
                    
Context.device->closeDevice();
                    return 
true;

                case 
GUI_ID_NEW_WINDOW_BUTTON:
                    {
                    
Context.listbox->addItem(L"Window created");
                    
Context.counter += 30;
                    if (
Context.counter 200)
                        
Context.counter 0;

                    
IGUIWindowwindow env->addWindow(
                        
rect<s32>(100 Context.counter100 Context.counter300 Context.counter200 Context.counter),
                        
false// modal?
                        
L"Test window");

                    
env->addStaticText(L"Please close me",
                        
rect<s32>(35,35,140,50),
                        
true// border?
                        
false// wordwrap?
                        
window);
                    }
                    return 
true;

                case 
GUI_ID_FILE_OPEN_BUTTON:
                    
Context.listbox->addItem(L"File open");
                    
// There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                
env->addFileOpenDialog(L"Please choose a file."true0, -1true);
                    return 
true;
                default:
                    return 
false;
                }
                break;

            case 
EGET_FILE_SELECTED:
                {
                    
// show the model filename, selected in the file dialog
                    
IGUIFileOpenDialogdialog =
                        (
IGUIFileOpenDialog*)event.GUIEvent.Caller;
                    
Context.listbox->addItem(dialog->getFileName());
                }
                break;
            default:
                break;
            }
        }
        return 
false;
    }
private:
    
SAppContext Context;
}; 
Ok ora la parte più interessante. Primo creiamo il device Irrlicht. Come in un esempio precedente chiediamo all'utente che genere di device vuole utilizzare (risoluzione, ecc..):
Codice PHP:
int main()
{
    
// ask user for driver
    
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
    if (
driverType==video::EDT_COUNT)
        return 
1;

    
// create device and exit if creation failed

    
IrrlichtDevice device createDevice(driverTypecore::dimension2d<u32>(640480));

    if (
device == 0)
        return 
1// could not create selected driver. 
Se il device è stato creato correttamente settiamo il nostro event receiver e prendiamoci il puntatore al nostro driver e quello del nostro nuovi ambiente GUI.
Codice PHP:
device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
     
device->setResizable(true);
     
video::IVideoDriverdriver device->getVideoDriver();
     
IGUIEnvironmentenv device->getGUIEnvironment(); 
Per rendere il font un po' più carino, carichiamone uno esterno e lo settiamo come default per la skin della nostra GUI. Per mantenere invece il font standard sui tool tip, lo andiamo a reimpostare tramite la proprietà getBuiltInFont().
Codice PHP:
IGUISkinskin env->getSkin();
    
IGUIFontfont env->getFont("../../media/fonthaettenschweiler.bmp");
    if (
font)
        
skin->setFont(font);
    
skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP); 
Aggiungiamo i tre pulsanti. Il primo chiude l'engine. Il secondo crea una finestra e il terzo apre una finestra di dialogo. Il terzo parametro è l'id del pulsante, con cui potremo facilmente identificarlo quando saremo nell'event receiver.
Codice PHP:
env->addButton(rect<s32>(10,240,110,240 32), 0GUI_ID_QUIT_BUTTON,
            
L"Quit"L"Exits Program");
    
env->addButton(rect<s32>(10,280,110,280 32), 0GUI_ID_NEW_WINDOW_BUTTON,
            
L"New Window"L"Launches a new Window");
    
env->addButton(rect<s32>(10,320,110,320 32), 0GUI_ID_FILE_OPEN_BUTTON,
            
L"File Open"L"Opens a file"); 
Ora aggiungiamo un'etichetta testo e una scrollbar che modichi la trasparenza di tutti gli elementi della GUI. Impostiamo il valore massimo della scrollbar a 255, perché è il massimo che il valore dei colori può assumere. Quindi creiamo l'etichetta di test e una listbox.
Codice PHP:
env->addStaticText(L"Transparent Control:"rect<s32>(150,20,350,40), true);
    
IGUIScrollBarscrollbar env->addScrollBar(true,
            
rect<s32>(1504535060), 0GUI_ID_TRANSPARENCY_SCROLL_BAR);
    
scrollbar->setMax(255);
    
scrollbar->setPos(255);
    
setSkinTransparencyscrollbar->getPos(), env->getSkin());

    
// set scrollbar position to alpha value of an arbitrary element
    
scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());

    
env->addStaticText(L"Logging ListBox:"rect<s32>(50,110,250,130), true);
    
IGUIListBox listbox env->addListBox(rect<s32>(50140250210));
    
env->addEditBox(L"Editable Text"rect<s32>(35080550100));

    
// Store the appropriate data in a context structure.
    
SAppContext context;
    
context.device device;
    
context.counter 0;
    
context.listbox listbox;

    
// Then create the event receiver, giving it that context structure.
    
MyEventReceiver receiver(context);

    
// And tell the device to use our custom event receiver.
    
device->setEventReceiver(&receiver); 
Alla fine creiamo un simpatico logo dell'Irrlicht Engine in alto a sinistra.
Codice PHP:
env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
            
position2d<int>(10,10)); 
Questo è tutto, non resta che disegnare tutto quanto.
Codice PHP:
while(device->run() && driver)
    if (
device->isWindowActive())
    {
        
driver->beginScene(truetrueSColor(0,200,200,200));

        
env->drawAll();
    
        
driver->endScene();
    }

    
device->drop();

    return 
0;


Versione pdf da scaricare QUI


RE: Tutorial 5 - User Interface - Master Gabriel - 10-08-2015

Grazie Chip, appena ho tempo scarico codeblocks e provo a cavarci fuori qualcosa Wink