Partie 16: Les décors au sol
Téléchargements
Les graphismes
Bugs
La base de données des décors de sol
<?xml version="1.0" encoding="ISO-8859-1"?>
<floor_ornates>
<floor_ornate name="Aucun">
</floor_ornate>
<floor_ornate name="Mousse">
<image_10>01_Moss_10.png</image_10>
<image_20>01_Moss_20.png</image_20>
<image_11>01_Moss_11.png</image_11>
<image_21>01_Moss_21.png</image_21>
<image_12>01_Moss_12.png</image_12>
<image_22>01_Moss_22.png</image_22>
<pos_10 x="44" y="102"/>
<pos_20 x="108" y="102"/>
<pos_11 x="11" y="113"/>
<pos_21 x="96" y="112"/>
<pos_12 x="0" y="131"/>
<pos_22 x="84" y="129"/>
</floor_ornate>
[...]
</floor_ornates>
Ici on peut voir que pour chaque type on a les noms de fichiers des 6 images et leurs coordonnées à l'écran.
Les décors de sol dans l'éditeur
<?xml version="1.0" encoding="ISO-8859-1"?>
<tiles>
<tile name="Vide">
</tile>
<tile name="Sol">
<image>Tile.png</image>
<param type="ornate">Decor</param>
</tile>
</tiles>
Ensuite c'est plus ou moins la même chose que ce que l'on a fait pour les décors des murs. La plupart des changements apparaissant dans
class CTile
{
public:
CTile();
virtual ~CTile();
void setType(uint8_t type);
uint8_t getType();
void copyWithoutWalls(CTile& rhs);
CTile& operator=(CTile& rhs);
void load(FILE* handle);
void save(FILE* handle);
CParam* findParamByName(QString name);
uint8_t getOrnateParam(QString name);
std::vector mParams;
CWall mWalls[eWallSideMax];
private:
void deleteParams();
uint8_t mType;
};
Le setType() et le getType() s'occupent d'allouer les paramètres quand on change le type de la case.
Les décors de sol dans le jeu
class CTiles
{
public:
struct COrnateElement
{
QString image;
CVec2 pos;
};
struct COrnateData
{
QString name;
COrnateElement table[WALL_TABLE_HEIGHT][(WALL_TABLE_WIDTH + 1) / 2];
};
CTiles();
void drawFloorOrnate(QImage* image, CVec2 tablePos, int ornate);
void readFloorOrnatesDB();
void readTilesDB();
std::vector<COrnateData> ornatesDatas;
};
Comme il y a beaucoup d'images pour un décor, on les stocke dans un tableau qui fait la moitié de la taille de celui qu'on a utilisé
void CTiles::readFloorOrnatesDB()
{
QDomDocument doc;
QFile f("databases/floor_ornates.xml");
f.open(QIODevice::ReadOnly);
doc.setContent(&f);
f.close();
QDomElement root = doc.documentElement();
QDomElement ornate = root.firstChild().toElement();
while(!ornate.isNull())
{
if (ornate.tagName() == "floor_ornate")
{
COrnateData newOrnate;
newOrnate.name = ornate.attribute("name");
QDomElement ornateInfo = ornate.firstChild().toElement();
while(!ornateInfo.isNull())
{
QString tag = ornateInfo.tagName();
if (tag.startsWith("image_") == true)
{
std::string str = tag.toUtf8().constData();
int x = str.at(str.size() - 2) - '0';
int y = str.at(str.size() - 1) - '0';
COrnateElement* elem = &newOrnate.table[y][x];
elem->image = QString("gfx/3DView/floor_ornates/") + ornateInfo.text();
}
else if (tag.startsWith("pos_") == true)
{
std::string str = tag.toUtf8().constData();
int x = str.at(str.size() - 2) - '0';
int y = str.at(str.size() - 1) - '0';
COrnateElement* elem = &newOrnate.table[y][x];
elem->pos.x = ornateInfo.attribute("x").toInt();
elem->pos.y = ornateInfo.attribute("y").toInt();
}
ornateInfo = ornateInfo.nextSibling().toElement();
}
ornatesDatas.push_back(newOrnate);
}
ornate = ornate.nextSibling().toElement();
}
}
Comme vous le voyez, on décode la position dans la table à partir du nom du champ en soustrayant le code ASCII de "0" aux
void CGame::displayMainView(QImage* image)
{
[...]
for (int y = 0; y < WALL_TABLE_HEIGHT; ++y)
for (int x = 0; x < WALL_TABLE_WIDTH; ++x)
{
tablePos = walls.getDrawSequence(CVec2(x, y));
localPos = walls.getMapPos(tablePos);
mapPos = player.getPosFromLocal(localPos);
CTile* tile = map.getTile(mapPos);
if (tile != NULL)
{
// dessine les murs
drawWall(image, tile, tablePos, eWallSideUp, flip);
drawWall(image, tile, tablePos, eWallSideLeft, flip);
drawWall(image, tile, tablePos, eWallSideRight, flip);
// dessine les décors au sol
if (tile->getType() == eTileGround)
{
//------------------------------------------------------------------------------
// case de sol
int ornate = tile->getOrnateParam("Decor");
tiles.drawFloorOrnate(image, tablePos, ornate);
}
// dessine les objets
// dessine les ennemis
}
}
}