Partie 7: Se déplacer dans la map
Téléchargements
Le timer
Timer {
id: elapsedTimer
interval: 1000/60;
running: true;
repeat: true;
onTriggered: {
main.image1.source = "image://myimageprovider/" + frame;
frame++;
}
}
Il appelle l'ImageProvider approxiamtivement 60 fois par secondes. Mais il n'est pas très constant comme vous pouvez le voir si vous dé-commentez les lignes
/* static clock_t lastClock;
clock_t curClock = clock();
qDebug() << (((float)(curClock - lastClock)) * 1000.0f /CLOCKS_PER_SEC);
lastClock = curClock;
*/
Ce code affiche dans la console de QtCreator's le temps entre 2 frames en milli-secondes.
Accélération
QImage floorGfx("gfx/3DView/Floor.png");
QImage ceilingGfx("gfx/3DView/Ceiling.png");
graph2D.drawImage(&image, CVec2(0, 33), ceilingGfx);
graph2D.drawImage(&image, CVec2(0, 72), floorGfx);
Naturellement ça vaut aussi pour les graphismes des murs.
class CFileCache
{
public:
CFileCache();
virtual ~CFileCache();
CFileData getFile(std::string fileName);
QImage getImage(std::string fileName);
private:
std::map<std::string, CFileData> mCache;
std::map<std::string, QImage> mImageCache;
};
extern CFileCache fileCache;
Chaque fois qu'on aura besoin de charger un fichier qu'on utilisera souvent, on va appeler la fonction getFile().
QImage floorGfx = fileCache.getImage("gfx/3DView/Floor.png");
QImage ceilingGfx = fileCache.getImage("gfx/3DView/Ceiling.png");
graph2D.drawImage(&image, CVec2(0, 33), ceilingGfx);
graph2D.drawImage(&image, CVec2(0, 72), floorGfx);
Le clavier
// enregistre l'EventFilter pour le clavier
QApplication::instance()->installEventFilter(&keyboard);
int retValue = app.exec();
// désenregistre l'EventFilter
QApplication::instance()->removeEventFilter(&keyboard);
return retValue;
L'Event Filter lui-même se trouve dans le fichier keyboard.cpp dans les sources:
bool CKeyboard::eventFilter(QObject */*object*/, QEvent *event){
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->isAutoRepeat() == false)
{
quint32 nativeKey = keyEvent->nativeScanCode();
switch (nativeKey)
{
case 16: // 'Q' en QWERTY, 'A' en AZERTY
player.turnLeft();
break;
case 17: // 'W' en QWERTY, 'Z' en AZERTY
player.moveForward();
break;
case 18: // 'E'
player.turnRight();
break;
case 30: // 'A' en QWERTY, 'Q' en AZERTY
player.moveLeft();
break;
case 31: // 'S'
player.moveBackward();
break;
case 32: // 'D'
player.moveRight();
break;
default:
break;
}
}
return true;
}
return false;
}
Il n'y a pas grand chose à expliquer ici. Comme vous le voyez, pour chaque touche on appelle une fonction dans "player.cpp" pour
Bouger
//-----------------------------------------------------------------------------------------
void CPlayer::turnLeft()
{
dir = (dir + 1) % 4;
}
//-----------------------------------------------------------------------------------------
void CPlayer::turnRight()
{
dir = (dir + 4 - 1) % 4;
}
//-----------------------------------------------------------------------------------------
void CPlayer::moveLeft()
{
EWallSide side = getWallSide(eWallSideLeft);
moveIfPossible(side);
}
//-----------------------------------------------------------------------------------------
void CPlayer::moveRight()
{
EWallSide side = getWallSide(eWallSideRight);
moveIfPossible(side);
}
//-----------------------------------------------------------------------------------------
void CPlayer::moveForward()
{
EWallSide side = getWallSide(eWallSideUp);
moveIfPossible(side);
}
//-----------------------------------------------------------------------------------------
void CPlayer::moveBackward()
{
EWallSide side = getWallSide(eWallSideDown);
moveIfPossible(side);
}
//-----------------------------------------------------------------------------------------
void CPlayer::moveIfPossible(EWallSide side)
{
CVec2 newPos = pos;
switch (side)
{
case eWallSideUp:
newPos.y--;
break;
case eWallSideDown:
newPos.y++;
break;
case eWallSideLeft:
newPos.x--;
break;
case eWallSideRight:
newPos.x++;
break;
default:
break;
}
CTile* tile = map.getTile(pos);
if (tile->mWalls[side].mType == 0)
pos = newPos;
}
Les fonctions "turn" changent simplement la direction que l'on regarde.