3rd person, telecamere, collisioni & eventi da tastiera (1)

by Chemello “hammeronthenet” Dario

E-mail: (chemello.dario [at] gmail.com])

Attenzione: il tutorial pubblicato sul sito è stato suddiviso in 5 parti. Linee di codice troppo lunghe potrebbero essere tagliate dal browser. Per la completezza e l'affidabilità del codice fate riferimento al tutorial completo in pdf.

scarica il seguente tutorial in formato pdf (161 kb)

scarica il codice completo in formato testo (.cpp, 10.6 Kb)

INTRODUZIONE:

Buongiorno a tutti! Premetto subito che è da pochissimo che ho preso in esame Irrlicht e, soprattutto, è da pochissimo che ho ri-preso C++ come linguaggio di programmazione. Ma forse proprio per questo ho deciso di cimentarmi nella scrittura di un tutorial che spieghi come utilizzare irrlicht per fare le seguenti cose:

-caricare una mappa BSP e un modello MD2

-muovere il nostro modello da tastiera

-gestire le collisioni tra personaggio e mappa

-gestire il salto

-varie ed eventuali

A mio “vantaggio” c’è solo il fatto che ci capisco ancora MOLTO POCO e che, quindi, posso immaginare quali siano gli errori più comuni (ovvero quelli che fino a 10 minuti fa avrei compiuto anche io) e le problematiche più banali (soprattutto per chi come me arriva fresco fresco da un ambiente strutturato completamente in maniera diversa).

Ho scritto questo tutorial principalmente perché c’è veramente poco materiale (e per lo più sparso) che tratta gli argomenti elencati sopra in un mini-esempio unico e organico, ovvero che porti ad un progettino che sia anche carino da vedere.

Tendo a sottolineare, inoltre, che quello che intendo presentare all’interno di questo tutorial è solo UNO degli n-mila modi di poter fare le stesse cose, e non è detto che sia il migliore. E’ comunque un punto di partenza.

COSA OCCORRE PER INIZIARE:

Beh… tralasciamo IDE e compilatore C++ & le librerie Irrlicht che spero abbiate già installato, altrimenti basta fare un bel “cerca” sul forum di irrlicht italia o vedere comunque una delle tante sezioni dedicate all’argomento.

E poi:

  • voglia di fare

  • voglia di imparare

  • saper programmare (che è diverso da conoscere un linguaggio specifico) un pochettino

Tutto qui!

PER ANDARE PIU’ SPEDITI:

Non sapendo bene come organizzare la spiegazione, direi di illustrare per benino le classi che compongono il progetto ed evitare il codice “inutile” (ai fini della spiegazione) come per esempio dichiarazione di variabili, define ecc.

Alla fine posterò il codice completo e “funzionante”.

Tralascio naturalmente installazioni e configurazioni del progetto (che comunque sono le “classiche” di irrlicht), consigliando (almeno per non toccare nemmeno una “virgola”) di rispettare i path standard di Irrlicht.

Io uso DEV-C++ come editor… ma sentitevi liberi di usare quello che più vi aggrada ; ) .

IL FULCRO DEL TUTTO: IL PLAYER

Questa in realtà è… l’ultima cosa che ho aggiunto!

Però si può dire che, a livello di logica, è la prima cosa da fare: creare una classe che descrive il personaggio ( o giocatore, o tipochesimuove o in qualunque modo vogliate chiamarlo):il PLAYER insomma!

class MyPlayer

{

public:

int id; //Identificativo numerico del Player… non usato (almeno per ora)

int WhatIDo;//Cosa sto facendo? Non fondamentale ma comodo da usare

int Jump; //Quanto in alto devo saltare.Se a 0, non ho più "spinta"

 

irr::scene::IAnimatedMeshSceneNode *TheNode; //La mesh animata del giocatore

irr::scene::ISceneNodeAnimatorCollisionResponse * TheCollisionAnimator; //Il collision animator del giocatore (utile poi per il salto)

MyPlayer(int TheID,irr::scene::IAnimatedMeshSceneNode *Node);//Costruttore

~MyPlayer();//Distruttore (quanto mi piace questa parola)

void addTheCollisionAnimator(irr::scene::ISceneNodeAnimatorCollisionResponse *anm);//Metodo per aggiungere un collision animator al nodo

};

I commenti già chiarificano i diversi scopi delle varie variabili/oggetti/metodi. Li vedremo comunque più dettagliatamente durante il loro “utilizzo”.

//Costruttore

MyPlayer::MyPlayer(int TheID,scene::IAnimatedMeshSceneNode *Node){

id=TheID;

WhatIDo=1;

Jump=0;

TheNode=Node;

TheNode->grab();

}

//Distruttore

MyPlayer::~MyPlayer(){

TheNode->drop();

TheCollisionAnimator->drop();

}

//Carica il collision animator

void MyPlayer::addTheCollisionAnimator(irr::scene::ISceneNodeAnimatorCollisionResponse *anm)

{

TheCollisionAnimator=anm;

TheNode->addAnimator(anm);

anm->drop();

}

Al costruttore verranno passati un Id numerico (per ora assolutamente inutile… l’ho inserito per ulteriori “esperimenti” che non vi sto a spiegare) e il nodo vero e proprio che conterrà la mesh del personaggio.

Tralasciando il “Distruttore”, vediamo cosa fa il metodo “addTheCollisionAnimator”.

In pratica, questo metodo assegna un IsceneNodeCollisionResponse (ovvero un particolare animator che si occupa di gestire le collisioni, per chi non lo conoscesse) al nodo del personaggio, in modo da gestire automaticamente le collisioni e impedire, tanto per capirsi, che il nostro personaggio diventi un fantasma e incominci ad attraversare i muri (eh eh eh…).

Da notare che la nostra classe, così come è fatta, permette di caricare un solo animator e per giunta SOLO di quel tipo… ma essendo che si tratta di un esempio diciamo che va bene così.

Il Collision Animator viene inoltre “memorizzato” all’interno della variabile pubblica “TheCollisionAnimator” del Player, permettendoci in questo modo di avere sempre a disposizione il puntatore all’oggetto.

Inutile dire che questo ci servirà in particolar modo per far saltare allegramente il nostro personaggio.

IL NOSTRO MONDO, OVVERO: COME TI CARICO LA SCENA

Vediamo ora una simpatica procedura che servirà a caricare una mappa BSP, ovvero il mondo dove sarà inserito il nostro Player e al quale farà riferimento il nostro collision animator:

void loadSceneData()

{

device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

quakeLevelMesh = smgr->getMesh("20kdm2.bsp");

if (quakeLevelMesh)

{

quakeLevelNode = smgr->addOctTreeSceneNode(quakeLevelMesh->getMesh(0));

if (quakeLevelNode)

{

quakeLevelNode->setPosition(core::vector3df(-1300,-85,-1249));

quakeLevelNode->setVisible(true);

// create map triangle selector

mapSelector = smgr->createOctTreeTriangleSelector(quakeLevelMesh->getMesh(0),

quakeLevelNode, 128);

}

}

}

(Sì, indento come un maiale e $ProgrammaDiScritturaAPagamentoDiBill non aiuta :D )

In definitiva non c’è niente di nuovo: apro il file PK3 (una sorta di “zip” contenente le info della mappa), carico la mappa vera e propria, dopodichè la posiziono, la rendo visibile e creo un Triangle Selector di nome “mapselector”, di tipo OCTREE (ideale per le collisioni con una mappa).

Questo Triangle Selector è molto importante poiché è uno dei due fulcri dell’intero “sistema” di collisioni che andremo a vedere in questo esempio, e servirà al Collision Animator del nostro nodo (personaggio) per gestire “magicamente” (sembra proprio una magia, ve lo assicuro) le collisioni.

 


6 commenti per “3rd person, telecamere, collisioni & eventi da tastiera (1)”

  1. keeper ha scritto:

    pare che il codice contenga diversi errori, non funziona. :(

  2. paooolino ha scritto:

    hai utilizzato il codice del pdf? scrivi sul forum, oppure manda un’email a me o all’autore del tutorial specificando meglio il problema.
    Ciao!

  3. nmbjuiq camfdzq ha scritto:

    mscypkxr oxrgqtbj lishkg wlyunbh ysjzrm pqex faixg

  4. tmulyvgj qfps ha scritto:

    wviauqt dmgbp iacj brtpcfj hpjzik rmyka cglin http://www.savkmnl.hqpvzj.com

  5. xwhvztqoi zgdsx ha scritto:

    jopvres obidewk pelqfxhs euvxhqcz mtcb ksoufcnb wrzjhl

  6. wjaqlysb yojlgw ha scritto:

    ftkmcovel ykghbj qkyihbxdc pxiucfl hnmepu nfwhz pkztl http://www.fykaziw.snpmrbvu.com

Lascia un commento