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

📄 g12-01.cpp

📁 游戏开发数据结构Data Structures for Game Programmers
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    case LPAREN:
        p_queue.Dequeue();
        left = ParseArithmetic( p_queue );
        // if( p_queue.Front().m_type != RPAREN )
            // this is where you would throw an error;
            // the string is unparsable with our language.
        p_queue.Dequeue();
        break;

    // if the token is either a variable or number, then set the left node
    // to point to the token, and deque the token.
    case VARIABLE:
    case NUMBER:
        left = new BinaryTree<Token>;
        left->m_data = p_queue.Front();
        p_queue.Dequeue();
        break;

    // case OPERATOR:
        // this is where you would throw an error;
        // the string is unparsable with our language.
    }

    // if there is nothing left in the queue, then return the left node; the 
    // string is parsed.
    if( p_queue.Count() == 0 )
        return left;

    // if the front of the queue is a right parenthesis, then we've reached
    // the end of parsing an expression inside parenthesis. return the
    // left node.
    if( p_queue.Front().m_type == RPAREN )
        return left;

    // if( p_queue.Front().m_type != OPERATOR )
        // this is where you would throw an error;
        // the string is unparsable with our language.

    // the next token MUST be an operator.

    // create the center node to point to the operator token.
    center = new BinaryTree<Token>;
    center->m_data = p_queue.Front();
    p_queue.Dequeue();

    // make sure the queue has something in it. If not, then the string
    // is invalid, so return 0.
    if( p_queue.Count() == 0 )
        return 0;

    // take off the third token, and determine what it is
    switch( p_queue.Front().m_type )
    {
    case LPAREN:
        p_queue.Dequeue();
        right = ParseArithmetic( p_queue );
        // if( p_queue.Front().m_type != RPAREN )
            // this is where you would throw an error;
            // the string is unparsable with our language.
        p_queue.Dequeue();
        break;

    case VARIABLE:
    case NUMBER:
        right = new BinaryTree<Token>;
        right->m_data = p_queue.Front();
        p_queue.Dequeue();
        break;

    // case OPERATOR:
        // this is where you would throw an error;
        // the string is unparsable with our language.
    }

    // make center point to the left and right nodes, and return it.
    center->m_left = left;
    center->m_right = right;
    return center;
}


// perform a post-order traversal on the tree to evaluate a number
float Evaluate( BinaryTree<Token>* p_tree )
{
    // if the tree node is invalid, return 0.
    if( p_tree == 0 )
        return 0.0f;

    float left = 0.0f;
    float right = 0.0f;

    switch( p_tree->m_data.m_type )
    {
    case VARIABLE:
        // if a variable, return the value of the variable
        return g_vars[p_tree->m_data.m_variable];
        break;
    case NUMBER:
        // if a number, return the number
        return p_tree->m_data.m_number;
        break;
    case OPERATOR:
        // if an operator, evaluate the left and right children, then
        // perform the operation on them.
        left = Evaluate( p_tree->m_left );
        right = Evaluate( p_tree->m_right );
        switch( p_tree->m_data.m_operator )
        {
        case 0:
            return left + right;
            break;
        case 1:
            return left - right;
            break;
        case 2:
            return left * right;
            break;
        case 3:
            return left / right;
            break;
        }
    }
    return 0.0f;
}


void Health()
{
    g_vars[3] = atof( g_life );
}


void Parse()
{
    // empty the queue.
    while( g_queue.Count() != 0 )
        g_queue.Dequeue();

    // scan the x string into the queue.
    Scan( g_xstring, g_queue );

    // if a previous tree exists, delete it.
    if( g_xtree != 0 )
        delete g_xtree;

    // parse the new tree
    g_xtree = ParseArithmetic( g_queue );

    // empty the queue.
    while( g_queue.Count() != 0 )
        g_queue.Dequeue();

    // scan the y string into the queue. 
    Scan( g_ystring, g_queue );

    // if a previous tree exists, delete it
    if( g_ytree != 0 )
        delete g_ytree;

    // parse the new tree
    g_ytree = ParseArithmetic( g_queue );
}


void Execute()
{
    if( g_running == true )
    {
        // stop execution if it is already running
        g_running = false;
    }
    else
    {
        // restart the simulation
        g_running = true;
        g_currenttime = 0;
        g_timer = SDL_GetTicks();
    }
        
}


void ShowTree()
{
    g_showtree = !g_showtree;
}


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

    // declare event holder
    SDL_Event event;

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

    //initialize systems
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
    TTF_Init();
    SDL_EnableUNICODE( 1 );

    // create the GUI and set the caption.
    g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
    SDL_WM_SetCaption( PROGRAM_NAME, 0); 
    g_gui->SetFont( "arial.ttf", ARIAL, 20, TTF_STYLE_NORMAL );


    // add the labels
    g_gui->AddLabel( 0, 468, "L =", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 500, "T =", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 532, "X =", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 564, "Y =", ARIAL, BLACK, WHITE );

    // add the text boxes
    g_gui->AddTextBox( 40, 468, 192, TTF_FontHeight( g_gui->GetFont(ARIAL)),
                       g_life, 63, ARIAL, BLACK, WHITE, true, Health );
    g_gui->AddTextBox( 40, 500, 192, TTF_FontHeight( g_gui->GetFont(ARIAL)),
                       g_time, 63, ARIAL, BLACK, WHITE, false, 0 );
    g_gui->AddTextBox( 40, 532, 192, TTF_FontHeight( g_gui->GetFont(ARIAL)),
                       g_xstring, 63, ARIAL, BLACK, WHITE, true, Parse );
    g_gui->AddTextBox( 40, 564, 192, TTF_FontHeight( g_gui->GetFont(ARIAL)),
                       g_ystring, 63, ARIAL, BLACK, WHITE, true, Parse );

    // the buttons
    g_gui->AddButton( 256, 532, "gbup.bmp", "gbdown.bmp", "Parse", ARIAL, 
                      BLACK, WHITE, Parse );
    g_gui->AddButton( 256, 468, "gbup.bmp", "gbdown.bmp", "Execute", ARIAL, 
                      BLACK, WHITE, Execute );

    g_gui->AddCheckbox( 384, 564, "checkboxup.bmp", "checkboxdown.bmp",
                        "Show Parse Trees", ARIAL, BLACK, WHITE, ShowTree );


    g_playerbmp = SDL_LoadBMP( "ufo.bmp" );

    // set the color keys of the BMPs
    SDL_SetColorKey( g_playerbmp, SDL_SRCCOLORKEY, 
                     SDL_MapRGB( g_playerbmp->format, 0, 0, 0 ));
    // main message loop.
    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 );

                // tell the GUI that a button has been pressed
                g_gui->MouseDown( x, y );
            }
            if( event.type == SDL_MOUSEBUTTONUP ) 
            {
                // get the mouse state.
                SDL_GetMouseState( &x, &y );

                // tell the GUI that a button has been released
                g_gui->MouseUp( x, y );
            }
            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 );
                }


                // tell the GUI that a key was pressed.
                g_gui->KeyDown( event.key.keysym.sym, 
                                event.key.keysym.mod,
                                event.key.keysym.unicode );
            }
        }   // end event loop.


        // tell the GUI to redraw itself
        g_gui->Draw();

        if( g_showtree == true )
        {
            DrawTree( g_xtree, 0, 0, 400 );
            DrawTree( g_ytree, 400, 0, 400 );
        }

        if( g_running == true )
        {
            // calculate the new current time.
            g_currenttime += (SDL_GetTicks() - g_timer);
            g_timer = SDL_GetTicks();


            // put the time, cosine of the time, and sine of the time
            // into the global variable table
            g_vars[2] = (float)g_currenttime / 1000.0f;
            g_vars[0] = cos( g_vars[2] * 6.283185f );
            g_vars[1] = sin( g_vars[2] * 6.283185f );


            // print the time variable into the g_time string
            sprintf( g_time, "%f", g_vars[2] );

            // calculate the new position by evaluating the trees.
            g_x = Evaluate( g_xtree );
            g_y = Evaluate( g_ytree );

            g_gui->Blit( g_playerbmp, g_x, g_y );
        }

        // tell the GUI to update itself
        g_gui->Update();

    }
  
    // done
    return 0;
}

⌨️ 快捷键说明

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