Creating Combat Sequences(3)

Creating Combat Sequences(3)

Global Data

The application class uses three global variables to contain the data about the character
and spell meshes, and the character animation information:

#define  PER_ROW_SPELLS      3

#define  PER_SPELL_WIDTH     200
#define  PER_SPELL_HEIGHT    20

#define  CLIENT_WIDTH        640
#define  CLIENT_HEIGHT       480

#define  TARGET_VERTEX_FVF   D3DFVF_XYZ | D3DFVF_DIFFUSE

typedef 
struct  sTargetVertex
{
    
float  x, y, z;
    D3DCOLOR diffuse;
} *sTargetVertexPtr;

const  sTargetVertex g_target_verts[6] = 
{
    { -20.0f,  40.0f, 0.0f, 0xFFFF4444 },
    {  20.0f,  40.0f, 0.0f, 0xFFFF4444 },
    {   0.0f,  20.0f, 0.0f, 0xFFFF4444 },
    {   0.0f, -20.0f, 0.0f, 0xFFFF4444 },
    {  20.0f, -40.0f, 0.0f, 0xFFFF4444 },
    { -20.0f, -40.0f, 0.0f, 0xFFFF4444 }
};

const   char * g_char_mesh_names[] = 
{
    { "..\\Data\\Warrior.x" },   
// Mesh # 0
    { "..\\Data\\Yodan.x"   }     // Mesh # 1
};

const  sCharAnimInfo g_char_anim_infos[] = 
{
    { "Idle",  
true   },
    { "Walk",  
true   },
    { "Swing", 
false  },
    { "Spell", 
false  },
    { "Swing", 
false  },
    { "Hurt",  
false  },
    { "Die",   
false  },
    { "Idle",  
true   }
};

const   char * g_spell_mesh_names[] = 
{
    { "..\\Data\\fireball.x"   },
    { "..\\Data\\Explosion.x"  },
    { "..\\Data\\Groundball.x" },
    { "..\\Data\\ice.x" },
    { "..\\Data\\bomb.x" },
    { "..\\Data\\heal.x" },
    { "..\\Data\\force.x" }
};
 

cApp::Init

Init, the first overloaded function in the application class, initializes the graphics
and input systems, loads all graphics, fonts, items, and other data needed for the
program:

bool  cApp::init()
{
    create_display(g_hwnd, CLIENT_WIDTH, CLIENT_HEIGHT, 16, 
true true );
    set_perspective(D3DX_PI/4, 1.3333f, 1.0f, 10000.0f);

    create_font(&m_font, "Arial", 16, 
true false );

    m_input.create(g_hwnd, get_window_inst());
    m_keyboard.create_keyboard(&m_input);
    m_mouse.create_mouse(&m_input, 
true );

    create_vertex_buffer(&m_target_vb, 6, 
sizeof (sTargetVertex), TARGET_VERTEX_FVF);
    fill_in_vertex_buffer(m_target_vb, 0, 6, g_target_verts);

    load_texture_from_file(&m_button, "..\\Data\\Buttons.bmp", 0, D3DFMT_UNKNOWN);

    m_terrain_mesh.load("..\\Data\\Battle.x", "..\\Data\\");
    m_terrain_obj.create(&m_terrain_mesh);

    
// create character stats and spell options text window
    m_char_stats.create(m_font);
    m_char_stats.move(508, 400, 128, 48, -1, -1, COLOR_DARK_BLUE, COLOR_ARGENTINE);
    m_spell_options.create(m_font);
    m_spell_options.move(4, 4, 632, 328, -1, -1, COLOR_DARK_BLUE, COLOR_ARGENTINE);

    
// load in master item list
    FILE* fp = fopen("..\\Data\\Default.mil", "rb");

    
if (fp)
    {
        fread(m_mil, 1, 
sizeof (m_mil), fp);
        fclose(fp);
    }

    m_char_controller.init(m_font, "..\\Data\\Default.mcl",
                            m_mil, m_spell_controller.get_spell_list(),
                            array_num(g_char_mesh_names), g_char_mesh_names,
                            "..\\Data\\", "..\\Data\\",
                            array_num(g_char_anim_infos), g_char_anim_infos);

    m_spell_controller.init("..\\Data\\Default.msl",
                            array_num(g_spell_mesh_names), g_spell_mesh_names,
                            "..\\Data\\");

    m_char_controller.attach(&m_spell_controller);
    m_spell_controller.attach(&m_char_controller);

    
// add player
    m_char_controller.add_char(0, 0, CHAR_PC, CHAR_STAND, 200.0f, 0.0f, 0.0f, 4.71f);

    
// hardcoded - add monster
    m_char_controller.add_char(1, 1, CHAR_MONSTER, CHAR_STAND, -200.0f, 0.0f, 0.0f,     1.57f);
    m_char_controller.add_char(2, 1, CHAR_MONSTER, CHAR_STAND, -100.0f, 0.0f, -200.0f,  1.57f);
    m_char_controller.add_char(3, 1, CHAR_MONSTER, CHAR_STAND,  0.0f,   0.0f, 100.0f,   1.57f);

    
// give an axe to one of the monsters
    m_char_controller.equip(m_char_controller.get_char(1), 8, WEAPON,  true );

    
return   true ;
}

As is typical in a graphics project, the graphics system is initialized and an Arial font
is created. Next comes initialization of the input system and devices.

As I mentioned, you need to target a character in order to attack or cast a spell
on the character. A pair of red, spinning triangles contained within a triangle list
vertex buffer with six vertices represents the target (as illustrated in Figure 18.5).

Creating Combat Sequences(3)_第1张图片

At this point in the Init function, create the vertex buffer that contains the two triangles
that represent the target.

Once the target vertex buffer is created, the various graphics need to be loaded
from disk. First, you load the button graphics used to select an action. You can see
the button graphics image in Figure 18.6. The images used to draw the charge
timer are included with the button graphics image. Next, you load the arena mesh
and object.

Creating Combat Sequences(3)_第2张图片

In order to display the player character’s status (including health and mana points), you create a text window below the character. Create a second window to contain the names of all known spells from which players can select spells as needed. As you can see in following snap this second window covers the top of the display.

Creating Combat Sequences(3)_第3张图片

Next, you need to load the master item list and initialize the character and spell
controller classes.

To finish the Init function, you position a few characters (players and monsters)
within the arena. (I was a little lazy here; hard-coding the characters encountered
and their positions in the arena should be a bit randomized, but I’ll leave that up
to you.) To add and position characters in the battle, use the character controller’s
add_char function.

Notice that a total of four characters are added to the fray. To make things a little
harder for the player, I went ahead and equipped the second character (a monster)
with an ax weapon. To equip characters with a weapon, you use the character controller’s
equip function, as I did.

你可能感兴趣的:(Creating Combat Sequences(3))