📄 g16-01.cpp
字号:
// ============================================================================
// G16-01.cpp
// Adventure Game Demo v2
// ============================================================================
#include "SDL.h"
#include "SDLHelpers.h"
#include "Array.h"
#include "Array3D.h"
#include <stdlib.h>
// ============================================================================
// Global Constants
// ============================================================================
const char PROGRAM_NAME[] = "Adventure Game Demo v2";
const int WIDTH = 800;
const int HEIGHT = 600;
const int TILES = 24;
const int ITEMS = 17;
const int PEOPLE = 3;
const int MOVETIME = 750;
const int DIRECTIONS = 4;
const int FRAMES = 4;
#include "Object.h"
#include "Item.h"
#include "Person.h"
#include "Map.h"
#include "TileMap.h"
// ============================================================================
// Function Headers
// ============================================================================
void DrawStatus();
void AddPersonToArray( Person* p_person );
void AddPersonToMap( Person* p_person );
float Distance( Object* p_object1, Object* p_object2 );
void PerformAI( int p_time );
void Attack( Person* p_person );
void CheckForDeadPeople();
void Init();
Map* LoadMap( char* p_filename );
void SetNewMap( char* p_filename );
// ============================================================================
// Global Variables
// ============================================================================
// this is the main window for the framework
SDL_Surface* g_window = 0;
// the bitmaps
SDL_Surface* g_tiles[TILES];
SDL_Surface* g_items[ITEMS];
SDL_Surface* g_people[PEOPLE][DIRECTIONS][FRAMES];
SDL_Surface* g_statusbar;
SDL_Surface* g_verticalbar;
SDL_Surface* g_youlose;
// current map and player
Map* g_currentmap = 0;
Person* g_currentplayer = 0;
// array of people in the map.
Array<Person*> g_peoplearray( 128 );
int g_peoplecount;
// is the user dead?
bool g_dead = false;
// cheat mode on?
bool g_cheat = false;
// ============================================================================
// Drawing Functions
// ============================================================================
// this draws the players status
void DrawStatus()
{
int x;
int i;
// blit the status bar
SDLBlit( g_statusbar, g_window, 16, 488 );
// get an iterator pointing to the item 2 places before the current.
DListIterator<Item*> itr = g_currentplayer->GetItemIterator();
for( x = 2; x > 0; x-- )
{
// move the iterator backwards
itr.Back();
if( itr.Valid() == false )
{
// if the iterator is not valid, then the algorithm went past
// the beginning. So, make the iterator valid again
// and set x so that it exits the loop
itr.Start();
i = x;
x = -1;
}
else
{
i = x - 1;
}
}
// draw the inventory
for( x = i; x < 5; x++ )
{
SDLBlit( itr.Item()->GetGraphic(), g_window,
67 * x + 27, 511 );
// move the iterator forward
itr.Forth();
// if the iterator is invalid, then the end of the inventory
// has been reached, so set x so that the loop exits out
if( itr.Valid() == false )
x = 6;
}
// draw the health bar
SDLBox( g_window, 520, 503,
(248 * g_currentplayer->GetHealth()) / 100,
16, BLUE );
// draw the Armor bar
SDLBox( g_window, 520, 544,
(248 * g_currentplayer->GetArmor()) / 100,
16, GREEN );
// draw the attack bar background
SDLBlit( g_verticalbar, g_window, 736, 232 );
// get the weapon speed
x = g_currentplayer->GetCurrentWeapon()->GetSpeed();
// get the amount of time that has passed since the last time
// the player attacked
i = SDL_GetTicks() - g_currentplayer->GetAttackTime();
// now figure out the height of the attack bar
if( i >= x )
{
x = 235;
}
else
{
x = (235 * i) / x;
}
// finally, draw the actual bar
SDLBox( g_window, 746, 243 + (235 - x), 28, x, RED );
}
// ============================================================================
// Game Functions
// ============================================================================
void AddPersonToArray( Person* p_person )
{
// add the person to the array.
g_peoplearray[g_peoplecount] = p_person;
// increment the number of people in the array
g_peoplecount++;
// resize the people array if you ran out of room
if( g_peoplecount == g_peoplearray.Size() )
g_peoplearray.Resize( g_peoplecount + 128 );
}
float Distance( Object* p_object1, Object* p_object2 )
{
// perform the pythagorean theorem on the
// coordinates of the two objects.
int dx = p_object1->GetX() - p_object2->GetX();
int dy = p_object1->GetY() - p_object2->GetY();
return (float)sqrt( (float)(dx*dx + dy*dy) );
}
void PerformAI( int p_time )
{
int i;
float dist;
int x = g_currentplayer->GetX();
int y = g_currentplayer->GetY();
int direction;
// loop through each person
for( i = 0; i < g_peoplecount; i++ )
{
// if the person isn't the current player
if( g_peoplearray[i] != g_currentplayer )
{
// get the direction that the AI needs to
// face in order to look at the player
direction =
g_currentmap->GetClosestDirection( g_peoplearray[i],
g_currentplayer );
// get the distance from the player to the current AI.
dist = Distance( g_peoplearray[i], g_currentplayer );
// check to see if the person is within sight range, and
// the appropriate amount of time has passed
if( dist > 1.0f && dist <= 6.0f &&
p_time - g_peoplearray[i]->GetMoveTime() > MOVETIME )
{
// reset the movement timer
g_peoplearray[i]->SetMoveTime( p_time );
// set the new direction, and move the person closer
g_peoplearray[i]->SetDirection( direction );
g_currentmap->Move( g_peoplearray[i], direction );
}
if( dist <= 1.0f )
{
// turn the person towards the player, and attack
g_peoplearray[i]->SetDirection( direction );
Attack( g_peoplearray[i] );
}
}
}
}
void Attack( Person* p_person )
{
int time;
int difference;
int cell;
Item* weapon;
Person* person;
// get the current time.
time = SDL_GetTicks();
// get the time difference
difference = time - p_person->GetAttackTime();
// get the weapon index;
weapon = p_person->GetCurrentWeapon();
// if the player can attack...
if( difference >= weapon->GetSpeed() )
{
// get the cell number that the player is facing
cell = g_currentmap->GetCellNumber( p_person->GetCell(),
p_person->GetDirection() );
// get the person in that cell.
person = g_currentmap->GetPerson( cell );
// check to see if there is a person actually there
if( person != 0 )
{
// hit the object
p_person->Attack( person );
// reset the attack counter
p_person->SetAttackTime( time );
}
}
}
void PickUp( Person* p_person )
{
Item* i = g_currentmap->GetItem( p_person->GetCell() );
if( i != 0 )
{
// only get the item if it is pickupable
if( i->CanGet() == true )
{
p_person->PickUp( i );
g_currentmap->SetItem( p_person->GetCell(), 0 );
}
else if( i->IsExit() == true )
{
// person wants to enter a vortex.
// get the filename of the new map
char* filename = g_currentmap->GetExitName( i->GetExitNumber() );
// load the new map
SetNewMap( filename );
}
}
}
void CheckForDeadPeople()
{
int i;
Person* p;
// scan through the list of people
for( i = 0; i < g_peoplecount; i++ )
{
// if the person is dead, and not the current player,
// then remove the person
if( g_peoplearray[i]->IsDead() )
{
if( g_peoplearray[i] == g_currentplayer )
{
g_dead = true;
return;
}
// keep track of the dead player,
// and "Fast Remove" him from the array.
p = g_peoplearray[i];
g_peoplearray[i] = g_peoplearray[g_peoplecount - 1];
g_peoplecount--;
i--;
// remove him from the map
g_currentmap->SetPerson( p->GetCell(), 0 );
// finally, delete the player
delete p;
}
}
}
// ============================================================================
// Initialize the game
// ============================================================================
void Init()
{
int x;
int d, f;
// load the bmps
g_tiles[0] = SDL_LoadBMP( "grass1.bmp" );
g_tiles[1] = SDL_LoadBMP( "grass2.bmp" );
g_tiles[2] = SDL_LoadBMP( "grass3.bmp" );
g_tiles[3] = SDL_LoadBMP( "grass4.bmp" );
// snow1
g_tiles[4] = SDL_LoadBMP( "snow1.bmp" );
g_tiles[5] = SDL_LoadBMP( "snow2.bmp" );
// road1
g_tiles[6] = SDL_LoadBMP( "roadh.bmp" );
g_tiles[7] = SDL_LoadBMP( "roadv.bmp" );
g_tiles[8] = SDL_LoadBMP( "roadtopleft.bmp" );
g_tiles[9] = SDL_LoadBMP( "roadtopright.bmp" );
g_tiles[10] = SDL_LoadBMP( "roadbottomleft.bmp" );
g_tiles[11] = SDL_LoadBMP( "roadbottomright.bmp" );
// layer 1 bmps:
// snow2
g_tiles[12] = SDL_LoadBMP( "snowtop.bmp" );
g_tiles[13] = SDL_LoadBMP( "snowbottom.bmp" );
g_tiles[14] = SDL_LoadBMP( "snowleft.bmp" );
g_tiles[15] = SDL_LoadBMP( "snowright.bmp" );
// snow 3
g_tiles[16] = SDL_LoadBMP( "snowotl.bmp" );
g_tiles[17] = SDL_LoadBMP( "snowotr.bmp" );
g_tiles[18] = SDL_LoadBMP( "snowobl.bmp" );
g_tiles[19] = SDL_LoadBMP( "snowobr.bmp" );
g_tiles[20] = SDL_LoadBMP( "snowitl.bmp" );
g_tiles[21] = SDL_LoadBMP( "snowitr.bmp" );
g_tiles[22] = SDL_LoadBMP( "snowibl.bmp" );
g_tiles[23] = SDL_LoadBMP( "snowibr.bmp" );
// players
g_people[0][0][0] = SDL_LoadBMP( "hero1u1.bmp" );
g_people[0][0][1] = SDL_LoadBMP( "hero1u2.bmp" );
g_people[0][0][2] = SDL_LoadBMP( "hero1u3.bmp" );
g_people[0][0][3] = SDL_LoadBMP( "hero1u4.bmp" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -