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

📄 g16-01.cpp

📁 游戏开发数据结构Data Structures for Game Programmers
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ============================================================================
// 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 + -