Partie 23: Objets - Partie 3: Poser et ramasser des objets
Téléchargements
Graphismes des objets
<?xml version="1.0" encoding="utf-8"?>
<items>
<!-- ======================== Armes ======================== -->
<!-- OEIL DU TEMPS -->
<item name="ITEM001">
<category>Weapon</category>
<floor_image>00W_Ring.png</floor_image>
<image_file>Items0.png</image_file>
<image_num>17</image_num>
</item>
<!-- ROND D'ECLAIRS -->
<item name="ITEM002">
<category>Weapon</category>
<floor_image>00W_Ring.png</floor_image>
<image_file>Items0.png</image_file>
<image_num>19</image_num>
</item>
[...]
</items>
On verra plus tard que certains objets ont plus d'une image, mais pour l'instant on n'en affichera qu'une.
Zones souris
enum EMouseAreaTypes
{
eMouseArea_None = 0,
// zones de l'interface
[...]
// zones du jeu
eMouseAreaG_Champion,
eMouseAreaG_DoorButton,
eMouseAreaG_PickObject,
eMouseAreaG_DropObject
};
class CMouse
{
public:
[...]
CObject mObjectInHand;
[...]
};
On peut seulement ramasser des objets qui sont à nos pieds (c'est-à-dire la rangée "arrière" de la case où on est) et
bool CObjects::isWallInFront()
{
CTile* tile = map.getTile(player.pos);
EWallSide side = player.getWallSide(eWallSideUp);
CWall* wall = &tile->mWalls[side];
return (wall->getType() != eWallNothing);
}
Pour les zones de "ramassage", on a seulement besoin d'ajouter une zone pendant qu'on dessine les objets dans
CObjects::drawObjectsStack:
// dessine l'objet à l'écran
pos -= CVec2(scaledObject.size().width() / 2, scaledObject.size().height() - 1);
graph2D.drawImage(image, pos, scaledObject, 0, false, QRect(0, 33, MAINVIEW_WIDTH, MAINVIEW_HEIGHT));
// ajoute la zone souris
if (mouse.mObjectInHand.getType() == 0)
{
if (tablePos.x >= WALL_TABLE_WIDTH - 1 && tablePos.x <= WALL_TABLE_WIDTH)
{
if (tablePos.y == (WALL_TABLE_HEIGHT - 1) * 2 ||
(tablePos.y == (WALL_TABLE_HEIGHT - 2) * 2 + 1 && isWallInFront() == false))
{
CRect mouseRect(pos, CVec2(pos.x + scaledObject.width() - 1, pos.y + scaledObject.height() - 1));
mouse.addArea(eMouseAreaG_PickObject, mouseRect, eCursor_Hand, (void*)stack, (void*)i);
}
}
}
Ici, on teste tablePos.x pour voir si l'objet est en face de nous (pas sur la gauche ni sur la droite).
void CObjects::drawBackRow(QImage* image, CVec2 mapPos, CVec2 tablePos)
{
[...]
CVec2 mapLeft = mapPos * 2 + pos1;
CVec2 mapRight = mapPos * 2 + pos2;
drawObjectsStack(image, mapLeft, tablePos * 2 + CVec2(0, 0));
drawObjectsStack(image, mapRight, tablePos * 2 + CVec2(1, 0));
// zones souris pour poser un objet
if (mouse.mObjectInHand.getType() != 0)
{
if (tablePos.x == WALL_TABLE_WIDTH / 2 &&
tablePos.y == WALL_TABLE_HEIGHT - 1)
{
CRect rectLeft(CVec2(31, 153), CVec2(111, 168));
mouse.addArea(eMouseAreaG_DropObject, rectLeft, eCursor_Hand, (void*)mapLeft.x, (void*)mapLeft.y);
CRect rectRight(CVec2(112, 153), CVec2(192, 168));
mouse.addArea(eMouseAreaG_DropObject, rectRight, eCursor_Hand, (void*)mapRight.x, (void*)mapRight.y);
}
}
}
Les coordonnées des zones sont les mêmes que celles qu'on vues dans l'image au-dessus.
void CObjects::drawFrontRow(QImage* image, CVec2 mapPos, CVec2 tablePos)
{
[...]
CVec2 mapLeft = mapPos * 2 + pos1;
CVec2 mapRight = mapPos * 2 + pos2;
drawObjectsStack(image, mapLeft, tablePos * 2 + CVec2(0, 1));
drawObjectsStack(image, mapRight, tablePos * 2 + CVec2(1, 1));
// zones souris pour poser un objet
if (mouse.mObjectInHand.getType() != 0)
{
if (tablePos.x == WALL_TABLE_WIDTH / 2 &&
tablePos.y == WALL_TABLE_HEIGHT - 2 &&
isWallInFront() == false)
{
CRect rectLeft(CVec2(46, 138), CVec2(111, 152));
mouse.addArea(eMouseAreaG_DropObject, rectLeft, eCursor_Hand, (void*)mapLeft.x, (void*)mapLeft.y);
CRect rectRight(CVec2(112, 138), CVec2(177, 152));
mouse.addArea(eMouseAreaG_DropObject, rectRight, eCursor_Hand, (void*)mapRight.x, (void*)mapRight.y);
}
}
}
Dans les paramètres des zones de "dépose" on passe les coordonnées du tas où on va mettre l'objet.
Tester les zones
void CGame::update(SMouseArea* clickedArea)
{
[...]
if (clickedArea != NULL)
{
if (mouse.mButtonPressing == true)
{
if (clickedArea->type == eMouseAreaG_Champion)
{
[...]
}
else if (clickedArea->type == eMouseAreaG_DoorButton)
{
[...]
}
else if (clickedArea->type == eMouseAreaG_PickObject)
{
CObjectStack* stack = (CObjectStack*)clickedArea->param1;
int index = (int)clickedArea->param2;
mouse.mObjectInHand = stack->getObject(index);
stack->removeObject(index);
if (stack->getSize() == 0)
map.removeObjectsStack(stack->mPos);
}
else if (clickedArea->type == eMouseAreaG_DropObject)
{
CVec2 pos = CVec2((int)clickedArea->param1, (int)clickedArea->param2);
CObjectStack* stack = map.addObjectsStack(pos);
stack->addObject(mouse.mObjectInHand);
mouse.mObjectInHand.setType(0);
}
}
}
}
Dans le cas du ramassage d'un objet, on le copie dans mObjectInHand, puis on le retire du tas, et enfin on teste si
Les objets comme curseurs
SMouseArea* CMouse::clickedArea(QImage* image)
{
[...]
if (area == NULL || area->cursor != eCursor_None)
{
if (area == NULL)
{
[...]
}
else if (area->cursor == eCursor_Arrow)
{
[...]
}
else
{
if (mObjectInHand.getType() == 0)
{
QImage cursor = fileCache.getImage("gfx/interface/CursorHand.png");
graph2D.drawImage(image, mPos, cursor);
}
else
{
CObjects::CObjectInfo object = objects.mObjectInfos[mObjectInHand.getType() - 1];
QImage cursor = fileCache.getImage(object.imageFile.toLocal8Bit().constData());
CRect rect = interface.getItemRect(object.imageNum);
graph2D.drawImageAtlas(image, mPos - CVec2(ITEM_WIDTH / 2, ITEM_HEIGHT / 2), cursor, rect);
}
}
}
[...]
}
On récupère le type de l'objet dans mObjectInHand et si il n'est pas à 0, on récupère la planche de sprite
Ecrire le nom de l'objet
void CInterface::drawObjectName(QImage* image)
{
int type = mouse.mObjectInHand.getType();
if (type != 0)
{
std::string& name = objects.mObjectInfos[type - 1].name;
drawText(image, CVec2(233, 33), eFontStandard, name.c_str(), MAIN_INTERFACE_COLOR);
}
}