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

📄 game.c

📁 Stellaris Luminary Micro 系列之 EV-LM3S811 多个学习范例全都是基于 Keil 工程版的范例, 而范例内容列举如下: 1.BitBand 2.PWMgen3.GPI
💻 C
📖 第 1 页 / 共 3 页
字号:
            //
            g_pucFrame[ulCount + 100] ^= ulBits;
            if((g_pucFrame[ulCount + 100] & ulBits) != ulBits)
            {
                g_pucFrame[ulCount + 100] |= ulBits;
                bBoom = true;
            }
        }
    }

    //
    // See if an impact occurred.
    //
    if(bBoom)
    {
        //
        // Start the ship explosion.
        //
        g_pcExplosions[4][0] = 0;
        g_pcExplosions[4][1] = 6;
        g_pcExplosions[4][2] = ulPos + 1;

        //
        // Indicate that the ship has exploded.
        //
        return(true);
    }
    else
    {
        //
        // The ship survived, so increment the score by one.
        //
        g_ulScore++;

        //
        // Indicate that the ship is still alive.
        //
        return(false);
    }
}

//*****************************************************************************
//
// Draws any active explosions.
//
//*****************************************************************************
static void
DrawExplosions(void)
{
    unsigned long ulCount, ulIdx;

    //
    // Loop through the explosion list.
    //
    for(ulCount = 0; ulCount < 5; ulCount++)
    {
        //
        // Skip this entry if it is not in use.
        //
        if(g_pcExplosions[ulCount][0] == (char)-1)
        {
            continue;
        }

        //
        // Get the index to the explosion type to display.
        //
        ulIdx = g_pcExplosions[ulCount][0] >> 2;

        //
        // For all except the last explosion (i.e. the ship explosion), move
        // the explosion to the left to match the movement of the tunnel.
        //
        if(ulCount != 4)
        {
            g_pcExplosions[ulCount][1]--;
        }

        //
        // Draw the explosion image into the local frame buffer.
        //
        DrawImage(g_psExplosion[ulIdx].pucImage,
                  g_pcExplosions[ulCount][1] - g_psExplosion[ulIdx].ucAdjust,
                  g_pcExplosions[ulCount][2] - g_psExplosion[ulIdx].ucAdjust,
                  g_psExplosion[ulIdx].ucWidth);

        //
        // Increment the explosion type counter.
        //
        g_pcExplosions[ulCount][0]++;

        //
        // If the explosion has completed, then remove it from the list.
        //
        if(g_pcExplosions[ulCount][0] == 16)
        {
            g_pcExplosions[ulCount][0] = (char)-1;
        }
    }
}

//*****************************************************************************
//
// The main screen of the game which waits for the user to press the button to
// begin the game.  If the button is not pressed soon enough, the screen saver
// will be called instead.
//
//*****************************************************************************
tBoolean
MainScreen(void)
{
    unsigned long ulCount, ulIdx;

    //
    // Set the top and bottom cave positions to the top and bottom of the
    // display.
    //
    g_pucOffset[0] = 0;
    g_pucOffset[1] = 16;

    //
    // Clear out the background buffer.
    //
    for(ulIdx = 0; ulIdx < 192; ulIdx += 4)
    {
        *(unsigned long *)(g_pucBackground + ulIdx) = 0;
    }

    //
    // Loop through the number of updates to the main screen to be done before
    // the screen saver is called instead.
    //
    for(ulCount = 0; ulCount < (2 * 60 * CLOCK_RATE / 4); ulCount++)
    {
        //
        // Wait until an update has been requested.
        //
        while(HWREGBITW(&g_ulFlags, FLAG_UPDATE) == 0)
        {
        }

        //
        // Clear the update request flag.
        //
        HWREGBITW(&g_ulFlags, FLAG_UPDATE) = 0;

        //
        // See if the button has been pressed.
        //
        if(HWREGBITW(&g_ulFlags, FLAG_BUTTON_PRESS))
        {
            //
            // Clear the button press flag.
            //
            HWREGBITW(&g_ulFlags, FLAG_BUTTON_PRESS) = 0;

            //
            // Return to the caller, indicating that the game should be played.
            //
            return(true);
        }

        //
        // Update the tunnel background, making sure that there are at least
        // thirteen scan lines between the top and bottom walls (providing room
        // for the "Press Button To Play" text).
        //
        UpdateBackground(13);

        //
        // Display the "Press Button To Play" text for sixteen frames every
        // sixteen frames, causing it to flash with a 50% duty cycle.
        //
        if(ulCount & 16)
        {
            //
            // Loop over the columns of the "Press Button To Play" image.
            //
            for(ulIdx = 0; ulIdx < sizeof(g_pucPlay); ulIdx++)
            {
                //
                // Copy this column of the image to the middle of the local
                // frame buffer.
                //
                g_pucFrame[ulIdx + 4] |= g_pucPlay[ulIdx] << 4;
                g_pucFrame[ulIdx + 100] |= g_pucPlay[ulIdx] >> 4;
            }
        }

        //
        // Display the updated image on the display.
        //
        OSRAMImageDraw(g_pucFrame, 0, 0, 96, 2);
    }

    //
    // The button was not pressed so the screen saver should be invoked.
    //
    return(false);
}

//*****************************************************************************
//
// Plays the game.
//
//*****************************************************************************
void
PlayGame(void)
{
    unsigned long ulIdx;
    tBoolean bFire, bDead;
    char pcScore[6];

    //
    // Initialize the top and bottom wall of the tunnel to the top and bottom
    // of the display.
    //
    g_pucOffset[0] = 0;
    g_pucOffset[1] = 16;

    //
    // Turn off all the mines.
    //
    for(ulIdx = 0; ulIdx < 5; ulIdx++)
    {
        g_pcMines[ulIdx][0] = (char)-1;
        g_pcMines[ulIdx][1] = (char)-1;
        g_pcMines[ulIdx][2] = (char)-1;
    }

    //
    // The missile has not been fired.
    //
    g_pcMissile[0] = (char)-1;
    g_pcMissile[1] = (char)-1;

    //
    // Turn off all the explosions.
    //
    for(ulIdx = 0; ulIdx < 5; ulIdx++)
    {
        g_pcExplosions[ulIdx][0] = (char)-1;
    }

    //
    // Reset the score to zero.
    //
    g_ulScore = 0;

    //
    // The player is not dead yet.
    //
    bDead = false;

    //
    // Clear out the background buffer.
    //
    for(ulIdx = 0; ulIdx < 192; ulIdx += 4)
    {
        *(unsigned long *)(g_pucBackground + ulIdx) = 0;
    }

    //
    // Loop until the game is over.
    //
    while(1)
    {
        //
        // Wait until an update has been requested.
        //
        while(HWREGBITW(&g_ulFlags, FLAG_UPDATE) == 0)
        {
        }

        //
        // Clear the update request flag.
        //
        HWREGBITW(&g_ulFlags, FLAG_UPDATE) = 0;

        //
        // See if the button has been pressed.
        //
        if(HWREGBITW(&g_ulFlags, FLAG_BUTTON_PRESS) == 1)
        {
            //
            // Clear the button press flag.
            //
            HWREGBITW(&g_ulFlags, FLAG_BUTTON_PRESS) = 0;

            //
            // Indicate that the missile should be fired if possible.
            //
            bFire = true;
        }
        else
        {
            //
            // Indicate that the missile should not be fired.
            //
            bFire = false;
        }

        //
        // Update the tunnel.  The tunnel gets smaller as the score goes up.
        //
        UpdateBackground(13 - (g_ulScore / 2000));

        //
        // Update the position of the mines.
        //
        UpdateMines();

        //
        // Update the position of the missile, possibly firing it.
        //
        UpdateMissile(bFire, bDead);

        //
        // See if the player is dead.
        //
        if(!bDead)
        {
            //
            // Draw the ship on the display.
            //
            bDead = DrawShip();

            //
            // See if the ship just hit somthing.
            //
            if(bDead)
            {
                //
                // Set the delay counter to zero.
                //
                ulIdx = 0;
            }
        }

        //
        // Draw the active explosions.
        //
        DrawExplosions();

        //
        // Display the updated image on the display.
        //
        OSRAMImageDraw(g_pucFrame, 0, 0, 96, 2);

        //
        // Write the current score to the UART.
        //
        UARTCharPut(UART0_BASE, '\r');
        UARTCharPut(UART0_BASE, '0' + ((g_ulScore / 10000) % 10));
        UARTCharPut(UART0_BASE, '0' + ((g_ulScore / 1000) % 10));
        UARTCharPut(UART0_BASE, '0' + ((g_ulScore / 100) % 10));
        UARTCharPut(UART0_BASE, '0' + ((g_ulScore / 10) % 10));
        UARTCharPut(UART0_BASE, '0' + (g_ulScore % 10));

        //
        // Check to see if the player is dead and the ship explosion has
        // completed.
        //
        if((g_pcExplosions[4][0] == (char)-1) && bDead)
        {
            //
            // Increment the delay counter.
            //
            ulIdx++;

            //
            // If a second has passed, then stop updating the tunnel and leave
            // the game.
            //
            if(ulIdx == (CLOCK_RATE / 4))
            {
                break;
            }
        }
    }

    //
    // Wait until an update has been requested.
    //
    while(HWREGBITW(&g_ulFlags, FLAG_UPDATE) == 0)
    {
    }

    //
    // Clear the update request flag.
    //
    HWREGBITW(&g_ulFlags, FLAG_UPDATE) = 0;

    //
    // Clear the display.
    //
    OSRAMClear();

    //
    // Display the user's score.
    //
    OSRAMStringDraw("Score: ", 12, 1);
    pcScore[0] = '0' + ((g_ulScore / 10000) % 10);
    pcScore[1] = '0' + ((g_ulScore / 1000) % 10);
    pcScore[2] = '0' + ((g_ulScore / 100) % 10);
    pcScore[3] = '0' + ((g_ulScore / 10) % 10);
    pcScore[4] = '0' + (g_ulScore % 10);
    pcScore[5] = '\0';
    OSRAMStringDraw(pcScore, 54, 1);

    //
    // Loop for five seconds.
    //
    for(ulIdx = 0; ulIdx < (5 * CLOCK_RATE / 4); ulIdx++)
    {
        //
        // At the start of every second, draw "Game Over" on the display.
        //
        if((ulIdx % (CLOCK_RATE / 4)) == 0)
        {
            OSRAMStringDraw("Game Over", 21, 0);
        }

        //
        // At the half way point of every second, clear the "Game Over" from
        // the display.
        //
        if((ulIdx % (CLOCK_RATE / 4)) == (CLOCK_RATE / 4 / 2))
        {
            OSRAMStringDraw("         ", 21, 0);
        }

        //
        // Wait until an update has been requested.
        //
        while(HWREGBITW(&g_ulFlags, FLAG_UPDATE) == 0)
        {
        }

        //
        // Clear the update request flag.
        //
        HWREGBITW(&g_ulFlags, FLAG_UPDATE) = 0;
    }
}

⌨️ 快捷键说明

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