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

📄 gd06-02.cpp

📁 游戏开发数据结构-Data.Structures.for.Game.Programmers
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ============================================================================
//  GD06-02.cpp
//  Doubly Linked List Graphical Demonstration
// ============================================================================
#include "SDLGUI.h"
#include "DLinkedList.h"
#include <stdlib.h>
#include <time.h>


// ============================================================================
//  Global Constants
// ============================================================================
const char PROGRAM_NAME[]   = "Doubly Linked List Graphical Demonstration";
const int WIDTH             = 800;
const int HEIGHT            = 600;
const int ITEMS             = 32;

const int ARIAL             = 0;
const int BIGARIAL          = 1;




// ============================================================================
//  Demo States
// ============================================================================
enum LinkedListState
{
    // nothing happening.
    NOSTATE,

        // insert after:
        INSERTMOVE,     // the nodes are moving apart
        INSERTNEWNODE,  // new node is displayed
        INSERTPOINT,    // pointer is re-arranged
        INSERTDONE,

        // insert before:
        BINSERTMOVE,     // the nodes are moving apart
        BINSERTNEWNODE,  // new node is displayed
        BINSERTPOINT,    // pointer is re-arranged
        BINSERTDONE,

        // remove:
        REMOVEMOVEDOWN, // move the node down
        REMOVEPOINT,    // change the pointers
        REMOVEMOVE,     // delete the node and move the nodes together.
        REMOVEDONE
};




// ============================================================================
//  Global Variables
// ============================================================================
SDLGUI* g_gui;

// the state
LinkedListState g_state = NOSTATE;

// holds the last marked time.
Uint32 g_time;

// Circles
SDL_Surface* g_blackcircle;
SDL_Surface* g_redcircle;

DLinkedList<int> g_list;
DListIterator<int> g_itr;
int g_current = 0;


// ============================================================================
//  Draw Algorithms
// ============================================================================

void DrawNode( int p_value,
               int p_x,
               int p_y,
               bool p_current )
{
    static SDL_Surface* text;
    static char number[] = "00";

    // draw the contents of the circle.
    if( p_value < 0 || p_value > 99 )
    {
        text = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), "x", RED, WHITE );
    }
    else
    {
        sprintf( number, "%d", p_value );
        text = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), number, BLACK, WHITE );
    }
    g_gui->Blit( text, (g_blackcircle->w - text->w) / 2 + p_x, 
                       (g_blackcircle->h - text->h) / 2 + p_y );
    SDL_FreeSurface( text );


    // draw the circle
    if( !p_current )
        g_gui->Blit( g_blackcircle, p_x, p_y );
    else
        g_gui->Blit( g_redcircle, p_x, p_y );
}



void DrawList( DLinkedList<int>& p_list,            // the list to draw
               int p_x,                            // x and y coords.
               int p_y,
               int p_current )                     // the current index.
                
{
    DListIterator<int> itr = p_list.GetIterator();

    int index;
    int y;
    int lastx = -1, 
        lasty = -1;

    // draw the list.
    for( index = 0; index < p_list.Size(); index++, itr.Forth() )
    {

        if( g_state == INSERTMOVE && index == (p_current + 1) )
        {
            // skip over the node that was inserted, we don't want to draw it yet.
            p_x += ( (SDL_GetTicks() - g_time) * g_blackcircle->w * 2 ) / 1000;
        }
        else if( g_state == INSERTNEWNODE && index == (p_current + 1) )
        {
            DrawNode( itr.Item(), p_x, p_y + 64, false );
            // draw an arrow to the next node if it exists.
            if( index < (p_list.Size() - 1) )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + 64,
                                  p_x + (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2), 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  false, true, BLACK );
            }
            // draw an arrow to the previous node if it exists.
            if( index > 0 )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + 64,
                                  p_x - (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2), 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  false, true, BLACK );
            }
            p_x += (g_blackcircle->w * 2);
        }
        else if( g_state == INSERTPOINT && index == (p_current + 1) )
        {
            // calculate the current y position.
            y = ( (SDL_GetTicks() - g_time) * 64 ) / 1000;
            y = 64 - y;

            DrawNode( itr.Item(), p_x, p_y + y, false );
            // draw an arrow to the last node.
            g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                              p_y + (g_blackcircle->h / 2) + y,
                              lastx, lasty, 
                              (g_blackcircle->w / 2),
                              (g_blackcircle->w / 2),
                              true, true, BLACK );

            lastx = p_x + (g_blackcircle->w / 2);
            lasty = p_y + (g_blackcircle->h / 2) + y;
            p_x += (g_blackcircle->w * 2);
        }
        else if( g_state == BINSERTMOVE && index == (p_current - 1) )
        {
            // skip over the node that was inserted, we don't want to draw it yet.
            p_x += ( (SDL_GetTicks() - g_time) * g_blackcircle->w * 2 ) / 1000;
        }
        else if( g_state == BINSERTNEWNODE && index == (p_current - 1) )
        {
            DrawNode( itr.Item(), p_x, p_y + 64, false );
            // draw an arrow to the next node if it exists.
            if( index < (p_list.Size() - 1) )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + 64,
                                  p_x + (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2), 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  false, true, BLACK );
            }
            // draw an arrow to the previous node if it exists.
            if( index > 0 )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + 64,
                                  p_x - (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2), 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  false, true, BLACK );
            }
            p_x += (g_blackcircle->w * 2);
        }
        else if( g_state == BINSERTPOINT && index == (p_current - 1) )
        {
            // calculate the current y position.
            y = ( (SDL_GetTicks() - g_time) * 64 ) / 1000;
            y = 64 - y;

            DrawNode( itr.Item(), p_x, p_y + y, false );
            // draw an arrow to the last node if it exists.

            if( index != 0 )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + y,
                                  lastx, lasty, 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  true, true, BLACK );
            }

            lastx = p_x + (g_blackcircle->w / 2);
            lasty = p_y + (g_blackcircle->h / 2) + y;
            p_x += (g_blackcircle->w * 2);
        }
        else if( g_state == REMOVEMOVEDOWN && index == p_current )
        {
            // calculate the current y position.
            y = ( (SDL_GetTicks() - g_time) * 64 ) / 1000;

            DrawNode( itr.Item(), p_x, p_y + y, false );
            // draw an arrow to the last node if it exists.
            if( index != 0 )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + y,
                                  lastx, lasty, 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  true, true, BLACK );
            }
            lastx = p_x + (g_blackcircle->w / 2);
            lasty = p_y + (g_blackcircle->h / 2) + y;
            p_x += (g_blackcircle->w * 2);
        }
        else if( g_state == REMOVEPOINT && index == p_current )
        {
            DrawNode( itr.Item(), p_x, p_y + 64, false );
            // draw an arrow to the next node if it exists.
            if( index < (p_list.Size() - 1) )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + 64,
                                  p_x + (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2), 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  false, true, BLACK );
            }
            // draw an arrow to the previous node if it exists.
            if( index > 0 )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2) + 64,
                                  p_x - (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2), 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  false, true, BLACK );
            }
            p_x += (g_blackcircle->w * 2);
        }
        else if( g_state == REMOVEMOVE && index == p_current )
        {
            // skip over the node that was inserted, we don't want to draw it yet.
            p_x += ( (g_blackcircle->w * 2) - 
                     ( (SDL_GetTicks() - g_time) * g_blackcircle->w * 2 ) / 1000 );
        }
        else
        {
            // draw the current node
            DrawNode( itr.Item(), p_x, p_y, g_itr == itr );

            if( lastx != -1 && lasty != -1 )
            {
                g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
                                  p_y + (g_blackcircle->h / 2),
                                  lastx, lasty, 
                                  (g_blackcircle->w / 2),
                                  (g_blackcircle->w / 2),
                                  true, true, BLACK );
            }

            // keep track of the center coords of this node
            // for the next iteration, so it can draw an arrow-line.
            lastx = p_x + (g_blackcircle->w / 2);
            lasty = p_y + (g_blackcircle->h / 2);
            p_x += (g_blackcircle->w * 2);
        }
    }

}



// ============================================================================
//  Callbacks
// ============================================================================

void Start()
{
    g_itr.Start();
    g_current = 0;
}

void End()
{
    g_itr.End();
    g_current = g_list.Size() - 1;
}


void Forth()
{
    g_itr.Forth();
    g_current++;
}


void Back()
{
    g_itr.Back();
    g_current--;
}

void InsertBefore()
{
    if( g_list.Size() < 8 && g_itr.Valid() )
    {
        // insert new data.
        g_list.InsertBefore( g_itr, rand() % 100 );

⌨️ 快捷键说明

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