Partie 20: Interface du jeu - Partie 3: Curseurs et flèches
Téléchargements
Les curseurs
MouseArea {
anchors.fill: parent
enabled: false
cursorShape: Qt.BlankCursor
}
Elle n'est pas activée, donc elle n'interceptera pas les clics, mais quand la souris sera à l'intérieur, le curseur
Les zones curseur
enum ECursorTypes
{
eCursor_None = 0,
eCursor_Arrow,
eCursor_Hand
};
struct SMouseArea
{
EMouseAreaTypes type;
CRect rect;
void* param1;
void* param2;
ECursorTypes cursor;
};
[...]
void addArea(EMouseAreaTypes type, CRect rect, ECursorTypes cursor = eCursor_Arrow, void* param1 = NULL, void* param2 = NULL);
Ensuite, il faut qu'on modifie CMouse::clickedArea(). On ne testera plus les zones seulement quand les bouton de la
SMouseArea* CMouse::clickedArea(QImage* image)
{
SMouseArea* area = NULL;
for (int i = mAreaList.size() - 1; i >= 0; --i)
{
CRect* rect = &mAreaList[i].rect;
if (mPos.x >= rect->tl.x &&
mPos.y >= rect->tl.y &&
mPos.x <= rect->br.x &&
mPos.y <= rect->br.y)
{
area = &mAreaList[i];
break;
}
}
if (area == NULL || area->cursor != eCursor_None)
{
std::string fileName;
if (area == NULL)
fileName = "gfx/interface/CursorArrow.png";
else if (area->cursor == eCursor_Arrow)
fileName = "gfx/interface/CursorArrow.png";
else
fileName = "gfx/interface/CursorHand.png";
QImage cursor = fileCache.getImage(fileName);
graph2D.drawImage(image, mPos, cursor);
}
if (mButtonPressed == true)
{
return area;
}
return NULL;
}
Vous pouvez voir que par défaut on affiche le curseur flèche.
void CGame::displayMainView(QImage* image)
{
if (interface.isInInventory() == false)
{
CRect mainRect(CVec2(0, 33), CVec2(MAINVIEW_WIDTH - 1, 33 + MAINVIEW_HEIGHT - 1));
mouse.addArea(eMouseArea_None, mainRect, eCursor_Hand);
La même chose se passe dans le cas de la feuille de personnage et à quelques autres endroits.
Les flèches de déplacement
CInterface::CInterface()
{
[...]
arrowsRects[eArrowTurnLeft] = CRect(CVec2(234, 125), CVec2(261, 145));
arrowsRects[eArrowForward] = CRect(CVec2(263, 125), CVec2(289, 145));
arrowsRects[eArrowTurnRight] = CRect(CVec2(291, 125), CVec2(318, 145));
arrowsRects[eArrowLeft] = CRect(CVec2(234, 147), CVec2(261, 167));
arrowsRects[eArrowBackward] = CRect(CVec2(263, 147), CVec2(289, 167));
arrowsRects[eArrowRight] = CRect(CVec2(291, 147), CVec2(318, 167));
}
Dans le jeu on ne se déplace pas seulement en cliquant sur les flèche, mais aussi en utilisant le clavier.
bool CKeyboard::eventFilter(QObject */*object*/, QEvent *event){
if (event->type() == QEvent::KeyPress)
{
[...]
if (keyEvent->isAutoRepeat() == false)
{
[...]
switch (nativeKey)
{
case 16: // 'Q' en QWERTY, 'A' en AZERTY
tempKeys[eTurnLeft] = true;
break;
case 17: // 'W' en QWERTY, 'Z' en AZERTY
tempKeys[eForward] = true;
[...]
Quand on aura besoin de tester les touches, on appellera une fonction de mise à jour qui fera une copie de ce
void CKeyboard::update()
{
for (int i = 0; i < eKeyCount; ++i)
{
keys[i] = tempKeys[i];
tempKeys[i] = false;
}
}
Ensuite on va tester à la fois les clics souris et le clavier dans une fonction updateArrows():
//------------------------------------------------------------
bool CInterface::isClickingOnArrow(SMouseArea* clickedArea, EMouseAreaTypes type)
{
return (mouse.mButtonPressing && clickedArea != NULL && clickedArea->type == type);
}
//------------------------------------------------------------
void CInterface::updateArrows(SMouseArea* clickedArea)
{
if (isClickingOnArrow(clickedArea, eMouseArea_ArrowForward) == true || keyboard.keys[CKeyboard::eForward] == true)
{
arrowHighlightTime = ARROWS_HIGHLIGHT_TIME;
currentArrow = eArrowForward;
player.moveForward();
}
else if (isClickingOnArrow(clickedArea, eMouseArea_ArrowBackward) == true || keyboard.keys[CKeyboard::eBackward] == true)
{
arrowHighlightTime = ARROWS_HIGHLIGHT_TIME;
currentArrow = eArrowBackward;
player.moveBackward();
}
else if (isClickingOnArrow(clickedArea, eMouseArea_ArrowLeft) == true || keyboard.keys[CKeyboard::eLeft] == true)
{
arrowHighlightTime = ARROWS_HIGHLIGHT_TIME;
currentArrow = eArrowLeft;
player.moveLeft();
}
else if (isClickingOnArrow(clickedArea, eMouseArea_ArrowRight) == true || keyboard.keys[CKeyboard::eRight] == true)
{
arrowHighlightTime = ARROWS_HIGHLIGHT_TIME;
currentArrow = eArrowRight;
player.moveRight();
}
else if (isClickingOnArrow(clickedArea, eMouseArea_ArrowTurnLeft) == true || keyboard.keys[CKeyboard::eTurnLeft] == true)
{
arrowHighlightTime = ARROWS_HIGHLIGHT_TIME;
currentArrow = eArrowTurnLeft;
player.turnLeft();
}
else if (isClickingOnArrow(clickedArea, eMouseArea_ArrowTurnRight) == true || keyboard.keys[CKeyboard::eTurnRight] == true)
{
arrowHighlightTime = ARROWS_HIGHLIGHT_TIME;
currentArrow = eArrowTurnRight;
player.turnRight();
}
}
Rassembler la souris et le clavier au même endroit sera utile plus tard pour limiter le mouvement quand les
Surligner les flèches
void CGraphics2D::Xor(QImage* image, CRect rect, QColor color)
{
for (int y = rect.tl.y; y <= rect.br.y; ++y)
for (int x = rect.tl.x; x <= rect.br.x; ++x)
{
QColor newColor;
QRgb pixel = image->pixel(QPoint(x, y));
newColor.setRed(qRed(pixel) ^ color.red());
newColor.setGreen(qGreen(pixel) ^ color.green());
newColor.setBlue(qBlue(pixel) ^ color.blue());
image->setPixel(QPoint(x, y), newColor.rgba());
}
}
Enfin, pour finir, jetons un oeil à la fonction drawArrows() où on peut voir l'utilisation de notre tableau de
void CInterface::drawArrows(QImage* image)
{
QImage arrowsBg = fileCache.getImage("gfx/interface/MovementArrows.png");
CVec2 pos(233, 124);
graph2D.drawImage(image, pos, arrowsBg);
if (isArrowsGreyed() == true)
{
CRect rect(CVec2(233, 124),
CVec2(319, 168));
graph2D.patternRectangle(image, rect);
}
else
{
static const EMouseAreaTypes arrowsMouseAreas[] =
{
eMouseArea_ArrowForward,
eMouseArea_ArrowBackward,
eMouseArea_ArrowLeft,
eMouseArea_ArrowRight,
eMouseArea_ArrowTurnLeft,
eMouseArea_ArrowTurnRight
};
for (int i = 0; i < eArrowsCount; ++i)
{
mouse.addArea(arrowsMouseAreas[i], arrowsRects[i]);
}
if (arrowHighlightTime > 0)
{
arrowHighlightTime--;
graph2D.Xor(image, arrowsRects[currentArrow], MAIN_INTERFACE_COLOR);
}
}
}