Artikkelit

Artikkelit olivat Suomipelit.comissa sivuston sulkeuduttua. Näin ollen niihin saattaa sisältyä rikkinäisiä linkkejä tai epämääräisiä viitteitä asioihin, joita ei enää ole olemassa, ja joskus jokin saattaa näkyä väärin.

Palaa artikkelilistaan

DirectX 8 - Direct Input

Tämä artikkeli käy läpi miten Direct Input -rajapintaa käytetään. Artikkeli käsittelee näppäimistön ja hiiren hallinnan ja jättää peliohjainten käytön lukijalle harjoitukseksi jolla varmistetaan, että luettu teksti on varmasti ymmärretty.

28.2.2003 julkaistun artikkelin on kirjoittanut Jarkko Parviainen.

  1. Direct Input - Yleistä
  2. Direct Input käyttökuntoon
  3. Direct Input, vapaudu!
  4. Ohjainlaitteiden hallintaa
  5. Näppäimistöltä tutkittavat tiedot
  6. Rotanloukkua rakentelemaan
  7. Hiiren käyttöönotto
  8. Kolmion paikan päivittäminen
  9. Loppusanat

Tämä artikkeli käy läpi miten Direct Input -rajapintaa käytetään. Artikkeli käsittelee näppäimistön ja hiiren hallinnan ja jättää peliohjainten käytön lukijalle harjoitukseksi jolla varmistetaan, että luettu teksti on varmasti ymmärretty.
Koska kyseessä on opetustarkoitukseen tehty artikkeli, ei kaikki sen sisältämä koodi ole suoraan oikeaan ohjelmaan soveltuvaa ja muutenkin pääasiana on selkeys, ei tehokkuus. Artikkeli on pyritty jakamaan sopivan kokoisiin osioihin ja jokainen läpikäyty asia on pyritty selvittämään mahdollisimman selkokielisesti ilman aiheelle ominaisia monimutkaisia vieraskielestä johdettuja termejä. Artikkelin mukana tulee lähdekoodit esimerkkiohjelmaan, jota analysoiden asiat käydään lävitse. Lähdekoodi esimerkit on testattu Microsoft Visual C++ 6.0 ohjelmointiympäristössä.

Esimerkkien kääntymisen onnistuminen vaatii oikein asennettujen DirectX8.0 ohjelmointikirjastojen olemassaoloa, sekä dxguid.lib, d3d8.lib, dinput8.lib ja d3dx8.lib tiedostojen linkittämistä projektiin.

Koko artikkelin lähdekoodeineen voit imuroida <a href="http://www.suomipelit.com/artikkelit/artikkeli002.zip">tästä</a>.

Direct Input - Yleistä #

Direct Input on DirectX:n osa, joka käsittelee erilaisten peliohjaimilta, hiiriltä sekä näppäimistöiltä saadun tiedon ja muuttaa sen yleiseen, ohjaintyypille olennaiseen muotoon. Tällöin ohjelmoijan ei tarvitse suuremmin välittää käyttäjien erilaisista peliohjaimista, vaan yksi yleinen liittymä (joka on varautunut tiettyihin erikoistapauksiin) riittää erittäin hyvin. Tässä artikkelissa luotava esimerkki pohjautuu edellisen artikkelin esimerkkikoodiin. Lopputuloksena saatava ohjelma piirtää ruudulle kolmion, jonka asemoidaan XY-koordinaatistossa liikkuvan kameran avulla.

Direct Input käyttökuntoon #

Direct Input -rajapinta luodaan lähes samalla tavoin kuin edellisessä artikkelissä käsitelty Direct3D -rajapinta. Ensin siis luodaan Direct Input-objekti, jonka avulla hankitaan liittymät tarvittaviin syöttölaitteisiin. Seuraavassa koodissa luodaan Direct Input-objekti ja samalla myös näppäimistö, koska kyseessä on jokaisen tietokoneen perusohjainlaite. Huomaa, että koodissa esitellään lisäksi kameran liikutteluun tarvittavat muuttujat.

#include <dinput.h> 

LPDIRECTINPUT8 g_pDirectInput;  // Direct Input-objekti 
LPDIRECTINPUTDEVICE8 g_pNappaimisto;  // Näppäimistölaite 
BYTE g_bNapit[256]; // Taulukko, joka säilöö näppäimistön nappien tilan. 
float g_XPaikka, g_YPaikka; // Kameran paikka. 


//-------------------------------------------- 
// Nimi: LuoDirectInput() 
// Kuv.: Luo Direct Input -objektin ja näppäi- 
//       mistölaitteen. 
//-------------------------------------------- 
HRESULT LuoDirectInput( void ) 
{ 
    HRESULT hr = S_OK; 

    // 
    // Nollataan DirectInputin käyttämät osoittimet. 
    // 
    g_pDirectInput = NULL; 
    g_pNappaimisto = NULL; 

    // 
    // Nollataan kolmion paikka. 
    // 
    g_XPaikka = 0.0f; 
    g_YPaikka = 0.0f; 

    // 
    // Luodaan DirectInput -objekti. 
    // 
    hr = DirectInput8Create( GetModuleHandle( NULL ), 
                             DIRECTINPUT_VERSION, 
                             IID_IDirectInput8, 
                             (VOID**)&g_pDirectInput, 
                             NULL ); 
    if( hr != S_OK ){ 
        return E_FAIL; 
    } 


    // 
    // Jos luonti onnistui, luodaan näppäimistö. 
    // 
    hr = g_pDirectInput->CreateDevice( GUID_SysKeyboard, 
                             &g_pNappaimisto, 
                             NULL ); 
    if( hr != S_OK ){ 
        VapautaDirectInput(); 
        return E_FAIL; 
    } 


    // 
    // Asetetaan muoto, jossa näppäimistön tiedot halutaan. 
    // 
    hr = g_pNappaimisto->SetDataFormat( &c_dfDIKeyboard ); 
    if( hr != S_OK ){ 
        VapautaDirectInput(); 
        return E_FAIL; 
    } 


    // 
    // Asetetaan näppäimistön käyttötapa 
    // ja hankitaan se ohjelman käytettäväksi. 
    // 
    g_pNappaimisto->SetCooperativeLevel( g_hWnd, 
               DISCL_NONEXCLUSIVE|DISCL_BACKGROUND ); 
    g_pNappaimisto->Acquire(); 


    // 
    // Luonti onnistui, palautetaan OK. 
    // 
    return S_OK;

} 


Yllä oleva koodi ei vielä toimi, koska emme ole tehneet VapautaDirectInput()-funktiota. Ensimmäiseksi nollataan Direct Input-objektin ja näppäimistölaitteen osoittimet. Todellisessa ohjelmassa tämä tulisi tehdä jossakin muualla kuin Direct Inputin käynnistävässä koodissa. Tämän jälkeen Direct Input -objekti luodaan CreateDirectInput8() -funktiolla. Funktio ottaa parametreinaan liittymää käyttävän ohjelman kahvan (saadaan nyt GetModuleHandle(NULL) -funktiolla), käytettävän Direct Inputin version, käytettävän liittymän tunnisteen, osoittimen johon luotava objekti kiinnitetään sekä viimeisenä parametrina COM aggregaatioon liittyvän osoitteen. Koska emme käytä tätä ominaisuutta, asetamme viimeisen parametrin arvolle NULL. CreateDirectInput8() palauttaa tiedon onnistumisesta HRESULT-muotoisena palautusarvona, joka on S_OK jos luonti onnistui ja jotakin muuta jos se epäonnistuu.

Kun Direct Input -objekti on luotu, sitä käytetään luomaan näppäimistölaite. Tämä tapahtuu Direct Input -objektin sisältämällä CreateDevice() -funktiolla. Funktio ottaa parametreinaan luotavan laitteen tunnisteen, osoittimen johon luotava objekti kiinnitetään, sekä jälleen kerran COM aggregaatioon liittyvän osoitteen. Viimeinen parametri on taas NULL, koska emme kyseistä ominaisuutta käytä.

Näppäimistö ei ole vielä käyttövalmis. Sen käyttämä tietomuoto täytyy ensin asettaa halutuksi, jotta tiedämme millaista tietoa se lähettää ohjelmallemme. Asettaminen tapahtuu näppäimistölaitteen funktiolla SetDataFormat, jonka parametriksi annetaan Direct Inputissa määritetty globaali muuttuja c_dfDIKeyboard.

Viimeiset kaksi vaihetta näppäimistön luonnissa on näppäimistön käyttäytymisen asettaminen sekä sen hankinta ohjelman käytettäväksi. Ensimmäinen näistä tapahtuu laitteen SetCooperativeLevel() -funktiolla. Funktio ottaa parametreinaan näppäimistöä käyttävän ikkunan kahvan, sekä listan ominaisuuksista joilla näppäimistö halutaan toimimaan. Käytettävissä ovat seuraavat ominaisuudet:

[DEFTABLE]
[D]DISCL_BACKGROUND[/D]
[E]Ohjelma käyttää syöttölaitetta jatkuvasti. Myös silloin, kun syöttölaitetta käyttävä ikkuna on pienennetty. [/E]

[D]DISCL_FOREGROUND[/D]
[E]Ohjelma käyttää syöttölaitetta vain silloin, kun ohjelman ikkuna on etualalla. Kun ohjelman ikkuna joutuu taka-alalle, ohjelma lopettaa syöttölaitteen käytön ja joutuu hankkimaan sen uudelleen kun ikkuna tulee taas etualalle.[/E]

[D]DISCL_EXCLUSIVE[/D]
[E]Ohjelma ottaa syöttölaitteen kokonaan omaan käyttöönsä. Yksikään muu ohjelma ei pysty syöttölaitetta tämän jälkeen käyttämään niin kauan kun EXCLUSIVE-tilassa toimiva ohjelma on sen hankkinut itselleen. Kun ohjelma käyttää EXCLUSIVE -tilaa, sen tulisi aina lopettaa syöttölaitteen käyttö kun ikkunan kokoa muutetaan tai siirrytään valikkoviesti-silmukkaan. Muuten käyttäjä ei pysty käyttämään Windowsin valikoita tai muokkaamaan ikkunan kokoa tai paikkaa.[/E]

[D]DISCL_NONEXCLUSIVE[/D]
[E]Ohjelma käyttää syöttölaitetta häiritsemättä muiden ohjelmien toimintaa. Useat ohjelmat voivat käyttää syöttölaitetta, jos ne kaikki ovat NONEXCLUSIVE -tilassa.[/E]

[D]DISCL_NOWINKEY[/D]
[E]Windows-näppäimet pois käytöstä. Toisin sanoen win-nappeja painelemalla ohjelmasta poistuminen on tämän ominaisuuden ansiosta estettävissä. [/E]
[/DEFTABLE]

Nyt kun Direct Input on luotu, katsomme seuraavaksi sen vapauttamisen. Rajapinnan vapauttamisen jälkeen tutustumme tarkemmin rajapinnan käyttämiseen.

Direct Input, vapaudu! #

Aivan kuten luominenkin, Direct Inputin vapauttaminen tapahtuu lähes täsmälleen samoin kuin Direct3D:n tapauksessa. Ensin vapautetaan rajapinnalta hankitut laitteet ja sen jälkeen itse rajapinta. Koodina se tapahtuu kuten alla.

//-------------------------------------------- 
// Nimi: VapautaDirectInput() 
// Kuv.: Vapauttaa Direct Input -objektin ja 
//       näppäimistölaitteen. 
//-------------------------------------------- 
void VapautaDirectInput( void ) 
{ 
    // 
    // Ensin vapautetaan laitteet. 
    // 
    if( g_pNappaimisto != NULL ){ 
        g_pNappaimisto->Unacquire(); 
        g_pNappaimisto->Release(); 
        g_pNappaimisto = NULL; 
    } 

    // 
    // Ja sen jälkeen DirectInput -objekti. 
    // 
    if( g_pDirectInput != NULL ){ 
        g_pDirectInput->Release(); 
        g_pDirectInput = NULL; 
    } 
} 


Koodi on hyvin yksinkertainen: ensin poistetaan kaikki laitteet (nyt vain näppäimistö) ja sen jälkeen rajapinta. Ennen vapautusyritystä tarkistetaan, että vapautettava laite on onnistuttu luomaan. Tällöin laitteen käyttöön tarkoitettu osoitin on jotakin muuta kuin nolla. Kun tästä ollaan varmistuttu, luovutaan laitteen hallinnasta Unacquire() -funktiolla. Hallinnasta luopumisen jälkeen ohjelma ei enää saa tietoja laitteen tilasta, joten sen käytössä kannattaa olla tarkka. Varsinainen laitteen vapauttaminen tehdään Release() -funktiolla, mikä vapauttaa kaikki laitteen sidokset. Tämän jälkeen laiteosoitin pitää nollata.

Rajapinta vapautetaan myös Release() -funktiolla ja nollataan sen jälkeen. Mitään muuta ei tarvitse tehdä. Ainoa varmistettava asia on, että kaikki laitteet on vapautettu ja nollattu ennen rajapinnan vapauttamista. Muuten ohjelmasi todennäköisesti kaatuu.

Seuraavaksi on vuorossa laitteen antaman syötteen käsittely. Näppäimistön ja hiiren tapauksessa se on hyvin yksinkertaista. Muilla ohjainlaitteilla huomioon otettavia asioita on enemmän, mutta ei onneksi ylimaallisen paljoa. Siirtykäämme siis ohjainlaitteen käsittelyyn.

Ohjainlaitteiden hallintaa #

Kaikkien ohjainlaitteiden hallinta koostuu niitä käyttävän ohjelman näkökulmasta seuraavista toimenpiteistä:
<ol>
<li>Päivitä laitteen tila. </li>
<li>Tutki tiedot ja toimi sen mukaisesti. </li>
<li>Tee muut toiminnot ja palaa kohtaan 1. </li>
</ol>
Laitteen tilan päivittäminen suoritetaan useimmiten ohjelmasilmukassa ensimmäiseksi. Tällöin ohjelmalla on käytössään viimeisimmät tiedot siitä, miten käyttäjä on rusikoinut ohjainlaitettaan.

Näppäimistöltä tutkittavat tiedot #

Koska kaikilla kotitietokoneen käyttäjillä on käytössään näppäimistö, tutkitaan sen hallinta tarkemmin.

//-------------------------------------------- 
// Nimi: PaivitaNappaimisto() 
// Kuv.: Päivittää näppäimistöltä saatavan 
//       syötteen. 
//-------------------------------------------- 
void PaivitaNappaimisto( void ) 
{ 

    HRESULT hr = S_OK; 

    // 
    // Hankitaan näppäimistön tämänhetkinen tilatieto. 
    // 
    if( g_pNappaimisto != NULL ){ 
        hr = g_pNappaimisto->GetDeviceState(sizeof(g_bNapit),
              (LPVOID)&g_bNapit); 

        // 
        // Joskus saatamme menettää näppäimistön 
        // jolloin tilan hankkiva funktio palauttaa 
        // Direct Input -virheen DIERR_INPUTLOST. 
        // Yritetään hankkia näppäimistöä kerran 
        // takaisin ja lukea tilatietoa uudelleen. 
        // Jos se ei onnistu, poistutaan koko 
        // päivitysfunktiosta. 
        // 
        if( hr == DIERR_INPUTLOST ){ 
            g_pNappaimisto->Acquire(); 
            hr = g_pNappaimisto->GetDeviceState(sizeof(g_bNapit),
                  (LPVOID)&g_bNapit); 
            if( FAILED( hr ) ){ 
                return; 
            } 
        } 
    } 

    // 
    // Siirretään kameraa syötteen mukaan. 
    // 
    if( g_pNapit[DIK_LEFT] & 0x80 ){ 
        g_XPaikka -= 0.05f; 
    } 
    if( g_pNapit[DIK_RIGHT] & 0x80 ){ 
        g_XPaikka += 0.05f; 
    } 
    if( g_pNapit[DIK_UP] & 0x80 ){ 
        g_YPaikka += 0.05f; 
    } 
    if( g_pNapit[DIK_DOWN] & 0x80 ){ 
        g_YPaikka -= 0.05f; 
    } 
} 


Yllä oleva koodi suorittaa aluksi tietojen hankkimisen näppäimistöltä aiemmin luotuun tietorakenteeseen funktiolla GetDeviceState(). Funktio palauttaa normaalisti S_OK ja virheen sattuessa DIERR_ -alkuisen virhekoodin. Useimmiten ohjelman ajon aikana saatava virhe on DIERR_INPUTLOST, mikä tarkoittaa että laitteen hallinta on menetetty. Kuten aiemmin todettiin, laitteelta ei saa tietoa jos sen hallinta on menetetty. Tämän vuoksi yllä olevassa koodissa Acquire()-funktiolla pyritään hankkimaan laite takaisin ja toistetaan sen jälkeen tietojen hankkiminen GetDeviceState() -funktiolla. Jos epäonnistutaan uudelleen, funktiosta poistutaan ja näppäimistön tila jää päivittämättä.

Kun näppäimistön tila on päivitetty, siirrellään kameraa, joka katsoo ruudulla näkyvää kolmiota syötteen mukaan. Eri näppäimet kuuluvat DIK_ -koodien alle (määritelty dinput.h -tiedostossa), jolloin niitä on selkeä käsitellä.

Rotanloukkua rakentelemaan #

Seuraavaksi käsittelemme hiiren hallinnan. Alustavat toimenpiteet tämän laitteen hallinnassa ovat hyvin samankaltaiset kuin näppäimistönkin kohdalla, joten niihin ei syvällisemmin puututa. Pureudunkin tässä syvemmin hiiren käyttöön ohjainlaitteena.

Hiiren käyttöönotto #

Hiiren saa käyttöön alla olevan koodin mukaisesti. Mitään merkittäviä eroja näppäimistön käyttöönottoon verrattuna ei siis ole. Selvyyden vuoksi esittelen koko DirectInput-luontifunktion, sekä kaikki globaalit muuttujat.

#include <dinput.h> 

LPDIRECTINPUT8 g_pDirectInput;  // Direct Input-objekti 
LPDIRECTINPUTDEVICE8 g_pNappaimisto;  // Näppäimistölaite 
LPDIRECTINPUTDEVICE8 g_pHiiri;  // Hiirilaite 
BYTE g_bNapit[256]; // Taulukko, joka säilöö näppäimistön nappien tilan. 
DIMOUSESTATE2 g_HiirenTila;  // Hiiren tilatiedon säilövä tietorakenne. 
float g_XPaikka, g_YPaikka; // Kolmion paikka. 


//-------------------------------------------- 
// Nimi: LuoDirectInput() 
// Kuv.: Luo Direct Input -objektin ja näppäi- 
//       mistölaitteen. 
//-------------------------------------------- 
HRESULT LuoDirectInput( void ) 
{ 
    HRESULT hr = S_OK; 

    // 
    // Nollataan DirectInputin käyttämät osoittimet. 
    // 
    g_pDirectInput = NULL; 
    g_pNappaimisto = NULL; 
    g_pHiiri = NULL; 

    // 
    // Nollataan kolmion paikka. 
    // 
    g_XPaikka = 0.0f; 
    g_YPaikka = 0.0f; 

    // 
    // Luodaan DirectInput -objekti. 
    // 
    hr = DirectInput8Create( GetModuleHandle( NULL ), 
                             DIRECTINPUT_VERSION, 
                             IID_IDirectInput8, 
                             (VOID**)&g_pDirectInput, 
                             NULL ); 
    if( hr != S_OK ){ 
        return E_FAIL; 
    } 


    // 
    // Jos luonti onnistui, luodaan näppäimistö. 
    // 
    hr = g_pDirectInput->CreateDevice( GUID_SysKeyboard, 
                             &g_pNappaimisto, 
                             NULL ); 
    if( hr != S_OK ){ 
        VapautaDirectInput(); 
        return E_FAIL; 
    } 


    // 
    // Asetetaan muoto, jossa näppäimistön tiedot halutaan. 
    // 
    hr = g_pNappaimisto->SetDataFormat( &c_dfDIKeyboard ); 
    if( hr != S_OK ){ 
        VapautaDirectInput(); 
        return E_FAIL; 
    } 


    // 
    // Asetetaan näppäimistön käyttötapa 
    // ja hankitaan se ohjelman käytettäväksi. 
    // 
    g_pNappaimisto->SetCooperativeLevel( g_hWnd, 
               DISCL_NONEXCLUSIVE|DISCL_BACKGROUND ); 
    g_pNappaimisto->Acquire(); 


    // 
    // Luodaan tämän jälkeen hiiri. 
    // 
    hr = g_pDirectInput->CreateDevice( GUID_SysMouse, 
                             &g_pHiiri, 
                             NULL ); 
    if( hr != S_OK ){ 
        VapautaDirectInput(); 
        return E_FAIL; 
    } 


    // 
    // Asetetaan muoto, jossa hiiren tiedot halutaan. 
    // 
    hr = g_pHiiri->SetDataFormat( &c_dfDIMouse2 ); 
    if( hr != S_OK ){ 
        VapautaDirectInput(); 
        return E_FAIL; 
    } 


    // 
    // Asetetaan hiiren käyttötapa 
    // ja hankitaan se ohjelman käytettäväksi. 
    // 
    g_pHiiri->SetCooperativeLevel( g_hWnd, 
               DISCL_NONEXCLUSIVE|DISCL_BACKGROUND ); 
    g_pHiiri->Acquire(); 


    // 
    // Luonti onnistui, palautetaan OK. 
    // 
    return S_OK;

} 


Hiiren tilatietojen päivittäminen on samankaltaista kuin näppäimistölläkin.

//-------------------------------------------- 
// Nimi: PaivitaHiiri() 
// Kuv.: Päivittää hiireltä saatavan 
//       syötteen. 
//-------------------------------------------- 
void PaivitaHiiri( void ) 
{ 

    HRESULT hr = S_OK; 

    // 
    // Hankitaan hiiren tämänhetkinen tilatieto. 
    // 
    if( g_pHiiri != NULL ){ 
        hr = g_pHiiri->GetDeviceState(sizeof(g_HiirenTila),
             (LPVOID)&g_HiirenTila); 

        // 
        // Joskus saatamme menettää hiiren 
        // jolloin tilan hankkiva funktio palauttaa 
        // Direct Input -virheen DIERR_INPUTLOST. 
        // Yritetään hankkia hiiri kerran 
        // takaisin ja lukea tilatietoa uudelleen. 
        // Jos se ei onnistu, poistutaan koko 
        // päivitysfunktiosta. 
        // 
        if( hr == DIERR_INPUTLOST ){ 
            g_pHiiri->Acquire(); 
            hr = g_pHiiri->GetDeviceState(sizeof(g_HiirenTila),
                     (LPVOID)&g_HiirenTila); 
            if( FAILED( hr ) ){ 
                return; 
            } 
        } 
    } 

    // 
    // Siirretään kameraa syötteen mukaan. 
    // 
    g_XPaikka += (float)(g_HiirenTila.lX) * 0.1f; 
    g_YPaikka += (float)(g_HiirenTila.lY) * 0.1f; 
} 


Hiiren antamaa syötettä käytettäessä tulee huomioida se, että DirectInput palauttaa muutoksen hiiren paikassa, ei sen varsinaista paikkaa ruudulla. Mikäli haluat luoda hiiren kursorin, on luotava 2 muuttujaa jotka säilövät hiiren paikan ruudulla. Näiden muuttujien paikkaa voi päivittää samalla tavoin kuin yllä olevassa koodissa päivitetään kolmion paikkaa.

Kolmion paikan päivittäminen #

Syöttölaitteiden antama tieto esitellään tässä esimerkissä edellisessä artikkelissa luodun kolmion avulla. Sekä näppäimistö, että hiiri siirtävät kolmiota katsovaa kameraa vaaka- ja pystysuorassa käyttäjän syötteen mukaisesti.

//--------------------------------------------
// Nimi  : AsetaMatriisit() 
// Kuvaus: Asettaa world (maailma), view
//         (kuvakulma) sekä projection
//         (projektio) matriisit.
//--------------------------------------------
void AsetaMatriisit( void ) 
{


    ...koodia...

    //
    // Asetetaan näkymä-matriisi. Näkymä-matriisi määrää
    // paikan josta piirrettävää 3-ulotteista kuvaa
    // katsotaan. Käytetään D3DX-apukirjaston
    // LookAt-funktiota apuna sitä asetettaessa.
    // Nyt kameran paikka asetetaan syötteen mukaisesti.
    //
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView,
                        &D3DXVECTOR3( g_XPaikka, g_YPaikka, 5.0f ),
                        &D3DXVECTOR3( 0.0f, 0.0f, -5.0f ),
                        &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    g_pD3DLaite->SetTransform( D3DTS_VIEW, &matView );

    ...koodia...

}


Muut matriisit asetetaan samalla tavoin kuin edellisessä artikkelissa. Yllä oleva koodi siirtelee kameraa kolmion edessä XY-tasossa. Kamera katsoo koko ajan kolmiota kohti, minkä vuoksi kolmio näyttää kääntyvän. Todellisuudessa ainoastaan kamera kääntyilee ja kolmio pysyy paikallaan.

Loppusanat #

Kuten huomasit, syötteen saaminen käyttäjältä on suhteellisen suoraviivainen toiminto. Se miten syötettä käsitellään joustavasti pelimoottorin sisällä on oma lukunsa. Tällöin tulee ottaa huomioon ohjelman asettamat vaatimukset syötteelle, syöttölaitteen ominaisuudet sekä vaihteleva nappien määrä. Aiheen luoteen vuoksi jätän käytännön ratkaisujen pohtimisen pienten harmaiden aivosolujesi harteille.

Kiitokset Risto Karjalaiselle sekä Olli-Pekka Hoskarille avusta artikkelin teossa.