📄 game.c
字号:
//
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 + -