Putting Together a Full Game(12)

Putting Together a Full Game(12)

 

status_frame:

You use the status_frame function to display the player's statistics (health points,
mana points, known spells, and so on) when the player's status window is displayed.
This function handles equipping items and checking on the player's statistics.

void  status_frame( void * data,  long  purpose)
{
    
if (purpose == SHUTDOWN_PURPOSE)
        
return ;

    cApp* app = (cApp*) data;

    
if (purpose == INIT_PURPOSE)
    {
        app->m_text_header.set_text("Status", COLOR_WHITE);
        app->m_text_window.set_text("", COLOR_WHITE);
    }
    
else      // process a frame of status screen
    {
        
// exit screen if ESC or right mouse button pressed
         if (app->m_keyboard.get_key_state(KEY_ESC) || app->m_mouse.get_button_state(MOUSE_RBUTTON))
        {
            app->m_keyboard.m_locks[KEY_ESC]    = 
true ;
            app->m_mouse.m_locks[MOUSE_RBUTTON] = 
true ;

            app->m_state_manager.pop(app);
            
return ;
        }

        sCharDef& char_def = g_player->char_def;

        
// determine which item is selected with mouse

        
long  sel = app->m_mouse.get_y_pos() - STATUS_TOP_HEIGHT;

        
if (sel >= 0)
            sel /= STATUS_MENU_HEIGHT;

        
// see if click on item to use or equip
         if (app->m_mouse.get_button_state(MOUSE_LBUTTON))
        {
            app->m_mouse.m_locks[MOUSE_LBUTTON] = 
true ;

            
// see which item was clicked
             if (sel >= 0 && sel < g_player->char_ics->get_num_items())
            {
                sCharItem* char_item = g_player->char_ics->get_item(sel);
                
bool  is_consume =  false ;
                
bool  is_equip_now;

                
// determine what to do with item
                 switch (app->m_mil[char_item->item_index].category)
                {
                
case  WEAPON:     // equip/unequip weapon
                    is_equip_now = (char_def.weapon != char_item->item_index);                    
                    app->m_game_chars.equip(g_player, char_item->item_index, WEAPON, is_equip_now);
                    
break ;

                
case  ARMOR:      // equip/unequip armor
                    is_equip_now = (char_def.armor != char_item->item_index);
                    app->m_game_chars.equip(g_player, char_item->item_index, ARMOR, is_equip_now);
                    
break ;

                
case  SHIELD:      // equip/unequip shield
                    is_equip_now = (char_def.shield != char_item->item_index);
                    app->m_game_chars.equip(g_player, char_item->item_index, SHIELD, is_equip_now);
                    
break ;

                
case  HEALING:
                    
if (g_player->health_points < g_player->char_def.health_points)
                    {
                        g_player->health_points += app->m_mil[char_item->item_index].value;

                        
if (g_player->health_points > char_def.health_points)
                            g_player->health_points = char_def.health_points;

                        is_consume = 
true ;
                    }

                    
break ;
                }

                
// reduce quantity if flagged as use once and consume flag
                 if (check_bit(app->m_mil[char_item->item_index].flags, USEONCE) && is_consume)
                {
                    
if (char_item->quantity == 1)
                        g_player->char_ics->remove(char_item);
                    
else
                        char_item->quantity--;
                }

                app->play_sound(SOUND_BEEP);
            }
        } 
// [end] if(app->m_mouse.get_button_state(MOUSE_LBUTTON))

        // render the scene

        begin_display_scene();

        app->render_frame(0);
        app->m_text_window.render(NULL, COLOR_WHITE);
        app->m_text_header.render(NULL, COLOR_WHITE);

        
// display inventory on left
        
        draw_font(app->m_font, "Inventory:", 8, 96, 0, 0, D3DCOLOR_RGBA(255, 213, 191, 255), DT_LEFT);
        
        
long  index = 0;

        
for (sCharItem* item_ptr = g_player->char_ics->get_root_item(); item_ptr != NULL; item_ptr = item_ptr->next)
        {
            
// calculate color to draw based on mouse position
             long  color = ((index == sel) ? D3DCOLOR_RGBA(255, 255, 0, 255) : D3DCOLOR_RGBA(128, 128, 128, 255));

            
// display item name and quantity

            
char  text[256];
            sprintf(text, "%lu x %s", item_ptr->quantity, app->m_mil[item_ptr->item_index].name);

            
long  y_pos = index * STATUS_MENU_HEIGHT + STATUS_TOP_HEIGHT;
            draw_font(app->m_font, text, 32, y_pos, 0, 0, color, DT_LEFT);
            
            
// if item is equipped, then show E next to it.
             if (char_def.weapon == item_ptr->item_index ||
               char_def.armor  == item_ptr->item_index ||
               char_def.shield == item_ptr->item_index)
            {
                draw_font(app->m_font, "E", 16, y_pos, 0, 0, color, DT_LEFT);
            }

            index++;    
// go down one line
        }

        
static   const   int  x_pos = 250;
        
char  text[256];

        
// display character's stats at top-right

        draw_font(app->m_font, "Stats:", x_pos, 32, 0, 0, 
                  D3DCOLOR_RGBA(255, 213, 191, 255), DT_LEFT);

        sprintf(text, "HP: %ld/%ld", g_player->health_points, char_def.health_points);
        draw_font(app->m_font, text, x_pos + 20, 64, 0, 0, COLOR_WHITE, DT_LEFT);

        sprintf(text, "MP: %ld/%ld", g_player->mana_points, char_def.mana_points);
        draw_font(app->m_font, text, x_pos + 20, 96, 0, 0, COLOR_WHITE, DT_LEFT);        

        sprintf(text, "Level(Max %lu): %lu", MAX_PLAYER_LEVEL, char_def.level);
        draw_font(app->m_font, text, x_pos + 20, 128, 0, 0, COLOR_WHITE, DT_LEFT);
        
        
if (char_def.level < MAX_PLAYER_LEVEL)
            sprintf(text, "Exp/Next: %lu/%lu", char_def.exp, g_level_up_exp[char_def.level-1]);
        
else
            sprintf(text, "Exp/Next: %lu/99999", char_def.exp);

        draw_font(app->m_font, text, x_pos + 20, 160, 0, 0, COLOR_WHITE, DT_LEFT);

        sprintf(text, "$: %lu", char_def.money);
        draw_font(app->m_font, text, x_pos + 20, 192, 0, 0, COLOR_LIGHT_YELLOW, DT_LEFT);

        
long  change = 0;

        
// print attack

        
if (g_player->char_def.weapon == -1)        
            sprintf(text, "Attack: %lu", char_def.attack);
        
else
        {            
            change = app->m_game_chars.get_attack(g_player) - char_def.attack;
            sprintf(text, "Attack: %lu + %lu", char_def.attack, change); 
        }

        draw_font(app->m_font, text, x_pos + 220, 64, 0, 0, COLOR_WHITE, DT_LEFT);

        
// print defense        

        
if (char_def.armor == -1 && char_def.shield == -1)
            sprintf(text, "Defense: %lu", char_def.defense);
        
else
        {
            change = app->m_game_chars.get_defense(g_player) - char_def.defense;
            sprintf(text, "Defense: %lu + %lu", char_def.defense, change); 
        }

        draw_font(app->m_font, text, x_pos + 220, 96, 0, 0, COLOR_WHITE, DT_LEFT);

        sprintf(text, "Agility: %lu", char_def.agility);
        draw_font(app->m_font, text, x_pos + 220, 128, 0, 0, COLOR_WHITE, DT_LEFT);

        sprintf(text, "Registance: %lu", char_def.resistance);
        draw_font(app->m_font, text, x_pos + 220, 160, 0, 0, COLOR_WHITE, DT_LEFT);

        sprintf(text, "Mental: %lu", char_def.mental);
        draw_font(app->m_font, text, x_pos + 220, 192, 0, 0, COLOR_WHITE, DT_LEFT);

        sprintf(text, "ToHit: %lu", char_def.to_hit);
        draw_font(app->m_font, text, x_pos + 220, 224, 0, 0, COLOR_WHITE, DT_LEFT);

        
// display known spells at right

        draw_font(app->m_font, "Spells:", x_pos , 240, 0, 0, D3DCOLOR_RGBA(255, 213, 191, 255), DT_LEFT);

        
for ( long  i = 0; i < NUM_SPELL_DEF; i++)
        {
            
if (char_def.magic_spell[i/32] & (1 << (i & 31)))
            {
                sSpell* spell = app->m_game_spells.get_spell(i);                

                
if (i == SPELL_HEAL)
                {                    
                    sprintf(text, "%lu: %s (Cost MP: %lu, Heal HP: %lu)", 
                        i+1, spell->name, spell->cost, (
long )spell->value[0]);
                }
                
else   if (i == SPELL_TELEPORT)
                {
                    sprintf(text, "%lu: %s (Cost MP: %lu, Move to town!)", i+1, spell->name, spell->cost);
                }
                
else
                {
                    sprintf(text, "%lu: %s (Cost MP: %lu, Damage: %lu)", 
                        i+1, spell->name, spell->cost, -(
long )spell->value[0]);
                }

                draw_font(app->m_font, text, x_pos + 20, i * STATUS_MENU_HEIGHT + 272, 0, 0, COLOR_WHITE, DT_LEFT);
            }
        }

        end_display_scene();
        present_display();
    }
}

 

barter_frame:

The last of the state functions, barter_frame displays the store clerk's wares and allows the
player to click-and-buy those items for sale.

void  barter_frame( void * data,  long  purpose)
{
    
static  cCharIcs char_ics;

    cApp* app = (cApp*) data;

    
if (purpose == INIT_PURPOSE)      // initialize barter data
    {
        app->m_keyboard.m_locks[KEY_SPACE] = 
true ;
        app->m_keyboard.set_key_state(KEY_SPACE, 
false );
        app->m_mouse.m_locks[MOUSE_LBUTTON] = 
true ;
        app->m_mouse.set_button_state(MOUSE_LBUTTON, 
false );

        char_ics.load(g_barter_ics_file);            

        app->m_text_header.set_text("Shop", COLOR_WHITE);
        app->m_text_window.set_text("\r\n\nWhat would you like to buy?", COLOR_WHITE);
    }
    
else   if (purpose == SHUTDOWN_PURPOSE)
    {
        char_ics.free();
    }
    
else      // process a frame of bartering
    {
        
// exit bartering if ESC or right mouse button pressed
         if (app->m_keyboard.get_key_state(KEY_ESC) || app->m_mouse.get_button_state(MOUSE_RBUTTON))
        {
            app->m_keyboard.m_locks[KEY_ESC]    = 
true ;
            app->m_mouse.m_locks[MOUSE_RBUTTON] = 
true ;

            app->m_state_manager.pop(app);
            
return ;
        }

        
// dertermine which item is selected with mouse

        
long  sel = app->m_mouse.get_y_pos() - BARTER_TOP_HEIGHT;

        
if (sel >= 0)
            sel /= BARTER_MENU_HEIGHT;

        
// see if click on item to buy
         if (app->m_mouse.get_button_state(MOUSE_LBUTTON))
        {
            app->m_mouse.m_locks[MOUSE_LBUTTON] = 
true ;

            
// see which item was clicked
             if (sel >= 0 && sel < char_ics.get_num_items())
            {
                sCharItem* char_item = char_ics.get_item(sel);

                
// make sure player has enough gold for item
                 if (g_player->char_def.money >= app->m_mil[char_item->item_index].price)
                {
                    sCharItem* item_ptr;

                    
// search for item alreay in inventory
                     for (item_ptr = g_player->char_ics->get_root_item(); item_ptr != NULL; item_ptr = item_ptr->next)
                    {
                        
// increase quantity if item already in inventory
                         if (char_item->item_index == item_ptr->item_index)
                        {
                            item_ptr->quantity++;
                            
break ;
                        }
                    }

                    
// add item to player's inventory if not already
                     if (item_ptr == NULL)
                        g_player->char_ics->add(char_item->item_index, 1, NULL);

                    g_player->char_def.money -= app->m_mil[char_item->item_index].price;

                    app->play_sound(SOUND_BEEP);
                }                
            }
        }

        
// render the bartering scene
        
        begin_display_scene();

        app->render_frame(0);
        app->m_text_window.render(NULL, COLOR_WHITE);
        app->m_text_header.render(NULL, COLOR_WHITE);

        
// display items to buy
         long  index = 0;
        
char  text[256];

        
for (sCharItem* char_item = char_ics.get_root_item(); char_item != NULL; char_item = char_item->next)
        {
            
// calculate color to draw based on mouse position
             long  color = ((index == sel) ? D3DCOLOR_RGBA(255, 255, 0, 255) : D3DCOLOR_RGBA(128, 128, 128, 255));

            
// display item name
             long  pos_y = index * BARTER_MENU_HEIGHT + BARTER_TOP_HEIGHT;
            draw_font(app->m_font, app->m_mil[char_item->item_index].name, 32, pos_y, 0, 0, color, D3DFMT_UNKNOWN);

            
// display item price
            sprintf(text, "$%lu", app->m_mil[char_item->item_index].price);
            draw_font(app->m_font, text, 300, pos_y, 0, 0, color, D3DFMT_UNKNOWN);

            index++;
        }

        
// display character's gold at top-right
        sprintf(text, "Money: $%lu", g_player->char_def.money);
        draw_font(app->m_font, text, 320, 32, 0, 0, COLOR_WHITE, D3DFMT_UNKNOWN);

        end_display_scene();
        present_display();
    }
}

你可能感兴趣的:(Putting Together a Full Game(12))