📄 game.c
字号:
//*****************************************************************************
//
// game.c - A "wander through a maze and shoot things" game.
//
// Copyright (c) 2006-2007 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. You may not combine
// this software with "viral" open-source software in order to form a larger
// program. Any use in violation of the foregoing restrictions may subject
// the user to criminal sanctions under applicable laws, as well as to civil
// liability for the breach of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 1952 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************
#include "../../../hw_memmap.h"
#include "../../../hw_types.h"
#include "../../../src/uart.h"
#include "../rit128x96x4.h"
#include "audio.h"
#include "enet.h"
#include "game.h"
#include "globals.h"
#include "images.h"
#include "random.h"
#include "sounds.h"
//*****************************************************************************
//
// The points accumulated during the game.
//
//*****************************************************************************
unsigned long g_ulScore;
//*****************************************************************************
//
// The position of the player within the maze. This is specified in pixel
// coordinates, where each cell of the maze is 12x12 pixels. Therefore, the
// range of the X coordinate is 0 to 1523, and the range of the Y coordinate is
// 0 to 1127. Each coordinate must be an even number to avoid having to shift
// the image data in the X direction; the Y coordinate is also required to be
// even so that movement along each axis is at the same rate.
//
//*****************************************************************************
unsigned short g_usPlayerX;
unsigned short g_usPlayerY;
//*****************************************************************************
//
// The position of the monsters within the maze. The positions are specified
// the same as the player position. A monster position of 0,0 indicates a dead
// monster (since it is not possible for a monster to be at that position since
// it is a wall).
//
//*****************************************************************************
unsigned short g_pusMonsterX[100];
unsigned short g_pusMonsterY[100];
//*****************************************************************************
//
// The monster animation count, indicating the index into the animation
// sequence for each monster.
//
//*****************************************************************************
static unsigned char g_pucMonsterCount[100];
//*****************************************************************************
//
// The position of the bullets within the maze. The positions are specified
// the same as the player position. A bullet position of 0,0 indicates an
// unfired bullet (since it is not possible for a bullet to be at that position
// since it is a wall).
//
//*****************************************************************************
static unsigned short g_pusBulletX[4];
static unsigned short g_pusBulletY[4];
//*****************************************************************************
//
// The direction of travel for each of the active bullets.
//
//*****************************************************************************
static unsigned char g_pucBulletDir[4];
//*****************************************************************************
//
// The position of the explosions within the maze. The positions are specified
// the same as the player position. An explosion position of 0,0 indicates the
// explosion is not active (since it is not possible for an explosion to be at
// that position since it is a wall).
//
//*****************************************************************************
static unsigned short g_pusExplosionX[4];
static unsigned short g_pusExplosionY[4];
//*****************************************************************************
//
// The explosion animation count, indicating the index into the animation
// sequence for each explosion.
//
//*****************************************************************************
static unsigned char g_pucExplosionCount[4];
//*****************************************************************************
//
// The direction the player is facing. When the lower nibble is non-zero, this
// indicates the direction that the player is walking. If the lower nibble is
// zero, then the upper nibble indicates the direction that the player is
// facing.
//
//*****************************************************************************
static unsigned char g_ucDirection = 0;
//*****************************************************************************
//
// The player animation count, indicating the index into the animation sequence
// for the current direction that the player is facing and/or moving.
//
//*****************************************************************************
static unsigned char g_ucCount = 0;
//*****************************************************************************
//
// An array that contains a grid describing the walls and corridors of the
// maze. Each entry contains the index of the glyph that is drawn in that cell
// of the maze.
//
//*****************************************************************************
char g_ppcMaze[94][127];
//*****************************************************************************
//
// An array containing the left grouping of cells, used to keep track of the
// cells that are connected via the current or previous row(s) of the maze.
//
//*****************************************************************************
static char g_pcLeft[43];
//*****************************************************************************
//
// An array containing the right grouping of cells, used to keep track of the
// cells that are connected via the current or previous row(s) of the maze.
//
//*****************************************************************************
static char g_pcRight[43];
//*****************************************************************************
//
// This function uses Eller's maze generation algorithm to generate a "perfect"
// maze. A perfect maze is one in which there are no loops and no isolations
// (i.e. any point in the maze can be reached from any other point, and there
// is only one path between any two points in the maze).
//
//*****************************************************************************
static void
GenerateMaze(void)
{
int iX, iY, iTemp;
//
// Choose a new random seed.
//
RandomSeed();
//
// Clear out the entire maze.
//
for(iY = 0; iY < 94; iY++)
{
for(iX = 0; iX < 127; iX++)
{
g_ppcMaze[iY][iX] = 0;
}
}
//
// Place walls along the top and bottom of the maze.
//
for(iX = 0; iX < 127; iX++)
{
g_ppcMaze[0][iX] = 1;
g_ppcMaze[93][iX] = 1;
}
//
// Place walls along the left and right of the maze.
//
for(iY = 0; iY < 94; iY++)
{
g_ppcMaze[iY][0] = 1;
g_ppcMaze[iY][126] = 1;
}
//
// Initialize the cell row data structure.
//
for(iX = 0; iX <= 42; iX++)
{
g_pcLeft[iX] = iX;
g_pcRight[iX] = iX;
}
g_pcLeft[0] = 1;
//
// Loop through the rows of the maze.
//
for(iY = 1; iY < 31; iY++)
{
//
// Loop through the cells of this row of the maze.
//
for(iX = 42; iX; iX--)
{
//
// See if this cell can be connected to the cell to the right, and
// if so, if it should be (i.e. based on randomness).
//
iTemp = g_pcLeft[iX - 1];
if((iX != iTemp) && (RandomNumber() > (6 << 27)))
{
//
// Update the row data structure to indicate that this cell is
// connected to the cell to the right.
//
g_pcRight[iTemp] = g_pcRight[iX];
g_pcLeft[(int)g_pcRight[iX]] = iTemp;
g_pcRight[iX] = iX - 1;
g_pcLeft[iX - 1] = iX;
}
else
{
//
// This cell is not connected to the cell to the right, so
// place a wall between the two cells.
//
g_ppcMaze[(iY * 3) - 0][(43 - iX) * 3] = 1;
g_ppcMaze[(iY * 3) - 1][(43 - iX) * 3] = 1;
g_ppcMaze[(iY * 3) - 2][(43 - iX) * 3] = 1;
g_ppcMaze[(iY * 3) - 3][(43 - iX) * 3] = 1;
}
//
// See if this cell can be connected to the cell below it, and if
// so, if it should be (i.e. based on randomness).
//
iTemp = g_pcLeft[iX];
if((iX != iTemp) && (RandomNumber() > (6 << 27)))
{
//
// Update the row data structure to indicate that this cell is
// connected to the cell below it.
//
g_pcRight[iTemp] = g_pcRight[iX];
g_pcLeft[(int)g_pcRight[iX]] = iTemp;
g_pcLeft[iX] = iX;
g_pcRight[iX] = iX;
//
// Place a wall below this cell.
//
g_ppcMaze[iY * 3][((43 - iX) * 3) - 0] = 1;
g_ppcMaze[iY * 3][((43 - iX) * 3) - 1] = 1;
g_ppcMaze[iY * 3][((43 - iX) * 3) - 2] = 1;
g_ppcMaze[iY * 3][((43 - iX) * 3) - 3] = 1;
}
}
}
//
// Loop through the cells of the last row of the maze.
//
for(iX = 42; iX; iX--)
{
//
// See if this cell can be connected to the cell to the right, and if
// so, if it should be (i.e. if it is required in order to maintain the
// connectedness of the maze or based on randomness).
//
iTemp = g_pcLeft[iX - 1];
if((iX != iTemp) &&
((iX == g_pcRight[iX]) || (RandomNumber() < (6 << 27))))
{
//
// Update the row data structure to indicate that this cell is
// connected to the cell to the right.
//
g_pcRight[iTemp] = g_pcRight[iX];
g_pcLeft[(int)g_pcRight[iX]] = iTemp;
g_pcRight[iX] = iX - 1;
g_pcLeft[iX - 1] = iX;
}
else
{
//
// This cell is not connected to the cell to the right, so place a
// wall between the two cells.
//
g_ppcMaze[(iY * 3) - 0][(43 - iX) * 3] = 1;
g_ppcMaze[(iY * 3) - 1][(43 - iX) * 3] = 1;
g_ppcMaze[(iY * 3) - 2][(43 - iX) * 3] = 1;
g_ppcMaze[(iY * 3) - 3][(43 - iX) * 3] = 1;
}
//
// Update the row data structure to indicate that this cell is not
// connected to the cell below it (since this is the last row).
//
iTemp = g_pcLeft[iX];
g_pcRight[iTemp] = g_pcRight[iX];
g_pcLeft[(int)g_pcRight[iX]] = iTemp;
g_pcLeft[iX] = iX;
g_pcRight[iX] = iX;
}
//
// Choose a random corner to remove from the maze to form the exit.
//
switch(RandomNumber() >> 30)
{
//
// Put the exit in the upper left corner.
//
case 0:
{
//
// Remove the wall from the top left corner of the maze.
//
if(RandomNumber() >> 31)
{
g_ppcMaze[0][1] = 0;
g_ppcMaze[0][2] = 0;
}
else
{
g_ppcMaze[1][0] = 0;
g_ppcMaze[2][0] = 0;
}
//
// Done adding the exit.
//
break;
}
//
// Put the exit in the upper right corner.
//
case 1:
{
//
// Remove the wall from the top right corner of the maze.
//
if(RandomNumber() >> 31)
{
g_ppcMaze[1][126] = 0;
g_ppcMaze[2][126] = 0;
}
else
{
g_ppcMaze[0][124] = 0;
g_ppcMaze[0][125] = 0;
}
//
// Done adding the exit.
//
break;
}
//
// Put the exit in the lower right corner.
//
case 2:
{
//
// Remove the wall from the bottom right corner of the maze.
//
if(RandomNumber() >> 31)
{
g_ppcMaze[93][124] = 0;
g_ppcMaze[93][125] = 0;
}
else
{
g_ppcMaze[91][126] = 0;
g_ppcMaze[92][126] = 0;
}
//
// Done adding the exit.
//
break;
}
//
// Put the exit in the lower left corner.
//
case 3:
default:
{
//
// Remove the wall from the bottom left corner of the maze.
//
if(RandomNumber() >> 31)
{
g_ppcMaze[91][0] = 0;
g_ppcMaze[92][0] = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -