⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g06-01.cpp

📁 游戏开发数据结构-Data.Structures.for.Game.Programmers
💻 CPP
字号:
// ============================================================================
// G06-01.cpp
// Linked List Inventory Demo
// ============================================================================
#include "SDL.h"
#include "SDLHelpers.h"
#include "DLinkedList.h"
#include <stdlib.h>

// ============================================================================
//  Global Constants
// ============================================================================
const char PROGRAM_NAME[]   = "Game Demo 06-01: Inventory Demo";
const int WIDTH             = 640;
const int HEIGHT            = 480;
const int ICONS             = 8;


// ============================================================================
//  Classes
// ============================================================================
class Item
{
public:
    int m_type;
    int m_weight;
};

class Player
{
public:
    int m_weightMax;
    int m_currentWeight;
    DLinkedList<Item> m_inventory;
};

enum States
{
    NOSTATE,
    LEFT,
    RIGHT
};



// ============================================================================
//  Global Variables
// ============================================================================

// this is the main window for the framework
SDL_Surface* g_window = 0;

// the text bitmaps
SDL_Surface* g_weight = 0;              // "Current Weight:"
SDL_Surface* g_playerWeight = 0;        // "Total Weight:"

// the bitmaps
SDL_Surface* g_icons[ICONS];

// the player
Player g_player;

// the iterator used to access the inventory.
DListIterator<Item> g_itr;

// the timer
int g_timer;

// the current state
States g_state = NOSTATE;

// the font
TTF_Font* g_font;


// ============================================================================
//  Functions
// ============================================================================
void AddItem( int p_type )
{
    // create a new item with 10-20 weight.
    Item item;
    item.m_type = p_type;
    item.m_weight = rand() % 11 + 10;

    // check if the weight is greater than the max weight.
    if( item.m_weight + g_player.m_currentWeight < g_player.m_weightMax )
    {
        // if not, add the item, and increase the current weight.
        g_player.m_inventory.Append( item );
        g_player.m_currentWeight += item.m_weight;
    }
}


void RemoveItem( DListIterator<Item>& p_itr )
{ 
    // if the current iterator is valid
    if( p_itr.Valid() )
    {
        // remove the weight of the item
        g_player.m_currentWeight -= p_itr.Item().m_weight;

        // remove the item
        g_player.m_inventory.Remove( p_itr );
    }
}


void CalculateText()
{
    if( g_weight )
        SDL_FreeSurface( g_weight );
    if( g_playerWeight )
        SDL_FreeSurface( g_playerWeight );

    static char text[80];


    if( g_itr.Valid() )
    {
        sprintf( text, "Weight: %d", g_itr.Item().m_weight );
    }
    else
    {
        sprintf( text, "Weight: None." );
    }
    g_weight = TTF_RenderText_Shaded( g_font, text, BLACK, WHITE );

    sprintf( text, "Total Weight: %d/%d", 
             g_player.m_currentWeight, g_player.m_weightMax );
    g_playerWeight = TTF_RenderText_Shaded( g_font, text, BLACK, WHITE );
}


void DrawIcons()
{
    int x = (WIDTH - (ICONS * 64)) / 2;
    int i;

    for( i = 0; i < ICONS; i++ )
    {
        SDLBlit( g_icons[i], g_window, x, 400 );
        x += 64;
    }
}


void DrawInventory()
{
    // in order to display the list with the current
    // item in the center, we need to find out
    // the index of the current item.
    int current = 0;
    
    // find the index of the current item.
    DListIterator<Item> itr = g_player.m_inventory.GetIterator();
    for( itr.Start(); itr.Valid(); itr.Forth() )
    {
        if( itr == g_itr )
            break;
        current++;
    }


    // now that we know the index of the current item, we can calculate
    // where to start drawing the list.
    int x = ((WIDTH / 2) - 32) - (64 * current);
    int d = ((SDL_GetTicks() - g_timer) * 64) / 500;

    // determine the direction of movement, if any.
    switch( g_state )
    {
    case NOSTATE:
        d = 0;
        break;
    case LEFT:
        d = -64 + d;
        break;
    case RIGHT:
        d = 64 - d;
        break;
    }

    for( itr.Start(); itr.Valid(); itr.Forth() )
    {
        SDLBlit( g_icons[itr.Item().m_type], 
                 g_window, x + d , 200 );
        x += 64;
    }

    SDLLine( g_window, (WIDTH / 2) - 32, 200, (WIDTH / 2) - 32, 264, BLACK );
    SDLLine( g_window, (WIDTH / 2) + 32, 200, (WIDTH / 2) + 32, 264, BLACK );
    SDLLine( g_window, (WIDTH / 2) - 32, 200, (WIDTH / 2) + 32, 200, BLACK );
    SDLLine( g_window, (WIDTH / 2) - 32, 264, (WIDTH / 2) + 32, 264, BLACK );

}


int main( int argc, char* argv[] )
{
    // declare coordinates.
    int x, y, i, w;

    // declare event holder
    SDL_Event event;

    // initialize the video system.
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
    SDL_WM_SetCaption( PROGRAM_NAME, 0); 

    // set our at exit function
    atexit( SDL_Quit );

    // set the video mode.
    g_window = SDL_SetVideoMode( WIDTH, HEIGHT, 0, SDL_ANYFORMAT );

    TTF_Init();
    g_font = TTF_OpenFont( "arial.ttf", 20 );
    TTF_SetFontStyle( g_font, TTF_STYLE_NORMAL );


    // load the bmps
    g_icons[0] = SDL_LoadBMP( "wepicon-sword.bmp" );
    g_icons[1] = SDL_LoadBMP( "wepicon-axe.bmp" );
    g_icons[2] = SDL_LoadBMP( "wepicon-spear.bmp" );
    g_icons[3] = SDL_LoadBMP( "wepicon-dagger.bmp" );
    g_icons[4] = SDL_LoadBMP( "wepicon-mace.bmp" );
    g_icons[5] = SDL_LoadBMP( "wepicon-bow.bmp" );
    g_icons[6] = SDL_LoadBMP( "wepicon-shield.bmp" );
    g_icons[7] = SDL_LoadBMP( "wepicon-helm.bmp" );

    // set the color keys, so the clear pixels aren't drawn
    for( x = 0; x < ICONS; x++ )
    {
        SDL_SetColorKey( g_icons[x], SDL_SRCCOLORKEY, 
                         SDL_MapRGB( g_icons[x]->format, 0, 255, 255 ) );
    }


    // create initial inventory
    Item item;

    // add a sword as an initial item
    item.m_type = 0;
    item.m_weight = rand() % 11 + 10;
    g_player.m_inventory.Append( item );
    g_player.m_currentWeight = item.m_weight;
    g_player.m_weightMax = 100;

    // reset the iterator to point to the list.
    g_itr = g_player.m_inventory.GetIterator();

    g_timer = SDL_GetTicks();

    CalculateText();

    while( 1 )
    {
        //look for an event
        if( SDL_PollEvent( &event ) )
        {
            //an event was found
            if( event.type == SDL_QUIT ) 
                break;
            if( event.type == SDL_MOUSEBUTTONDOWN ) 
            {
                // get the mouse state.
                SDL_GetMouseState( &x, &y );
            }
            if( event.type == SDL_MOUSEBUTTONUP ) 
            {
                // get the mouse state.
                SDL_GetMouseState( &x, &y );

                // if y is between 400 and 464, then check to see if
                // an icon was clicked.
                if( y >= 400 && y <= 464 )
                {
                    w = (WIDTH - (ICONS * 64)) / 2;
                    i = (x - w) / 64;

                    // add a new item with a random weight from 10-20
                    if( i >= 0 && i < ICONS )
                    {
                        AddItem( i );
                        if( g_itr.Valid() == false )
                            g_itr.Start();
                        CalculateText();
                    }
                }

                // if y is between 200 and 264, then check to see if
                // the white box was clicked.
                if( y >= 200 && y <= 264 )
                {
                    if( x >= (WIDTH / 2) - 32 && x <= (WIDTH / 2) + 32 )
                    {
                        RemoveItem( g_itr );
                        CalculateText();
                    }
                }
            }
            if( event.type == SDL_KEYDOWN )
            {
                // a key was pressed.
                if( event.key.keysym.sym == SDLK_ESCAPE )
                {
                    // if ESC was pressed, quit the program.
                    SDL_Event quit;
                    quit.type = SDL_QUIT;
                    SDL_PushEvent( &quit );
                }

                if( event.key.keysym.sym == SDLK_LEFT && g_state == NOSTATE )
                {
                    // move the iterator backwards
                    g_timer = SDL_GetTicks();
                    g_state = LEFT;
                    g_itr.Back();

                    // if the iterator went past the end, reset it to the start
                    // again.
                    if( !g_itr.Valid() )
                    {
                        g_state = NOSTATE;
                        g_itr.Start();
                    }
                    CalculateText();
                }
                if( event.key.keysym.sym == SDLK_RIGHT && g_state == NOSTATE )
                {
                    // move the iterator forwards
                    g_timer = SDL_GetTicks();
                    g_state = RIGHT;
                    g_itr.Forth();


                    // if the iterator went past the end, reset it to the beginning
                    // again.
                    if( !g_itr.Valid() )
                    {
                        g_state = NOSTATE;
                        g_itr.End();
                    }
                    CalculateText();
                }
                if( event.key.keysym.sym == SDLK_UP )
                {
                    // increase the maximum weight
                    g_player.m_weightMax += 50;
                    CalculateText();
                }
                if( event.key.keysym.sym == SDLK_DOWN )
                {
                    // decrease the maximum weight
                    g_player.m_weightMax -= 50;
                    CalculateText();
                }
            }

        }   // end event loop.

        // it takes 500 milliseconds to move to the next item,
        // so if 500 ms have passed since the last timer reset, 
        // set the state to NOSTATE.
        if( (SDL_GetTicks() - g_timer) >= 500 )
            g_state = NOSTATE;
        
        // if the iterator isn't valid, move it to the start again.
        if( !g_itr.Valid() )
            g_itr.Start();

        // clear the screen to black.
        SDL_FillRect( g_window, NULL, SDL_MapRGB( g_window->format, 255, 255, 255 ) );

        DrawIcons();
        DrawInventory();
        SDLBlit( g_weight, g_window, 10, 30 );
        SDLBlit( g_playerWeight, g_window, 10, 0 );
        
        // update the entire window.
        SDL_UpdateRect( g_window, 0, 0, 0, 0 );
    }
  
    // done
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -