Game interface - Part 1

Downloads

Source code
Executable for the map editor - exactly the same as in part 10 (Windows 32bits)
Executable for the game (Windows 32bits)

Before you try to compile the code go to the "Projects" tab on the left menu, select the "Run" settings for your kit,
and set the "Working directory" to the path of "editor\data" for the editor or "game\data" for the game.

Adding movement

If you played to the game so far, you may have noticed that we have a feeling of "sliding" inside the map instead of walking.
That's because the graphics - especially the ground - does not change when we move from one tile to another.
To avoid this problem, without having to draw more graphs, Dungeon Master developers used a simple trick: flipping.
Every time you walk on a new tile - and every time you turn too - the ground, the ceiling and the facing walls are flipped
horizontally.


The side walls are exchanged with their flipped counterparts. I.e. Wall20_L is replaced by a flipped Wall20_R.
These changes are mostly visible on the ground, on the walls only a few pixels change. But this is sufficient to give us the
feeling that we really "move" between each tile.
So I had to change the drawImage() function and the wall drawing routines a little bit. If you search "flip" in the code, you
will find all the changes.

The same trick was used in many other games: Eye of the Beholder, Black Crypt, Might & Magic 3...

The interface



I began to draw some interface elements and to set up most of the functions needed. Have a look at "interface.h":

		#ifndef INTERFACE_H
		#define INTERFACE_H

		#include <QTimer>
		#include <QImage>
		#include "../common/sources/system/cmaths.h"
		#include "character.h"

		#define MAIN_INTERFACE_COLOR    QColor(0, 204, 204)

		class CInterface
		{
		public:
			// Main state of the interface
			enum EMainState
			{
				eMainGame = 0,  // standard window with the 3D view
				eMainInventory  // Inventory sheet
			};

			// States of the weapon's area
			enum EWeaponsAreaState
			{
				eWeaponsAreaWeapons = 0,    // The 4 weapons boxes
				eWeaponsAreaAttacks,        // The attacks of a weapon
				eWeaponsAreaDamage          // The damages when we hit a monster
			};

			CInterface();
			~CInterface();

			void    display(QImage* image);
			bool    isInInventory();

		private:
			bool    isChampionEmpty(int num);
			bool    isChampionDead(int num);

			bool    isWeaponEmpty(int num);
			bool    isWeaponGreyed(int num);

			bool    isArrowsGreyed();

			void    drawBar(QImage* image, int num, CVec2 pos, CCharacter::EStatsNames statName);
			void    drawChampion(QImage* image, int num);
			void    drawSpells(QImage* image);
			void    drawWeaponsArea(QImage* image);
			void    drawWeapon(QImage* image, int num);
			void    drawArrows(QImage* image);
			void    drawInventory(QImage* image);
			void    greyRectangle(QImage* image, CRect rect);
			int     getWeapon(int num);
			CCharacter::SStat   getStat(int num, CCharacter::EStatsNames statName);

			EMainState          mainState;
			EWeaponsAreaState   weaponsAreaState;
			int     currentChampion;
			int     currentWeapon;
			QTimer* weaponCoolDown[4];
		};

		extern CInterface   interface;

		#endif // INTERFACE_H
				
I also needed to set up some functions for the character stats. Here is "character.h":

		#ifndef CHARACTER_H
		#define CHARACTER_H

		#include <string>

		class CCharacter
		{
		public:
			enum EBodyParts
			{
				eBodyPartHead = 0,
				eBodyPartNeck,
				eBodyPartTorso,
				eBodyPartLeftHand,
				eBodyPartRightHand,
				eBodyPartLegs,
				eBodyPartFeets,
				eBodyPartCount
			};

			enum EStatsNames
			{
				eStatHealth = 0,
				eStatStamina,
				eStatMana,
				eStatStrength,
				eStatDexterity,
				eStatWisdom,
				eStatAntiFire,
				eStatAntiMagic,
				eStatLoad,
				eStatCount
			};

			struct SStat
			{
				int value;
				int maxValue;
				int startValue;
			};

			CCharacter();
			bool    isDead();

			int     picture;
			std::string name;
			SStat   stats[eStatCount];
			int     bodyObjects[eBodyPartCount];
		};

		#endif // CHARACTER_H
				
Finally I wrote some default values to the characters stats in "game.cpp" to test the different states.

You can see the details of how the various states of each element are handled in "interface.cpp".
I will probably follow this work in part 13.

Level 1



I drew a first version of the first level of the game. Of course some elements are missing, the stairs,
the doors, the pictures to choose the champions, the secret passage to the alternate ending...
And a lot of small decorations.
We will begin to add those elements in the next part.

Obviously I had to change the starting player position too. You can see that in "main.cpp" right after the
loading of the map.