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

📄 directionmap.h

📁 游戏开发数据结构Data Structures for Game Programmers
💻 H
字号:
#ifndef DIRECTIONMAP_H
#define DIRECTIONMAP_H

#include "Map.h"
#include "SDLHelpers.h"



// ============================================================================
//  DirectionCell Class
// ============================================================================
class DirectionCell
{
public:
// =======================================================
//  Functions
// =======================================================

// -------------------------------------------------------
// Name:        DirectionCell
// Description: constructs the cell
// -------------------------------------------------------
    DirectionCell()
    {
        m_blocked = false;
        m_item = 0;
        m_person = 0;
        m_exits[0] = -1;
        m_exits[1] = -1;
        m_exits[2] = -1;
        m_exits[3] = -1;
        m_tiles[0] = -1;
        m_tiles[1] = -1;
        m_x = -1;
        m_y = -1;
    }



// =======================================================
//  Data
// =======================================================

// -------------------------------------------------------
// Name:        m_blocked
// Description: determines if the cell is blocked by
//              a feature of the geography, but not
//              by items or people.
// -------------------------------------------------------
    bool m_blocked;

// -------------------------------------------------------
// Name:        m_item
// Description: The item in the cell
// -------------------------------------------------------
    Item* m_item;

// -------------------------------------------------------
// Name:        m_person
// Description: The person in the cell
// -------------------------------------------------------
    Person* m_person;

// -------------------------------------------------------
// Name:        m_exits
// Description: the exits from the cell
// -------------------------------------------------------
    int m_exits[4];

// -------------------------------------------------------
// Name:        m_tiles
// Description: the tiles of the cell
// -------------------------------------------------------
    int m_tiles[2];

// -------------------------------------------------------
// Name:        m_x
// Description: x coordinate of the cell
// -------------------------------------------------------
    int m_x;

// -------------------------------------------------------
// Name:        m_y
// Description: y coordinate of the cell
// -------------------------------------------------------
    int m_y;

};


// this class is used to load data from the disk
class MapEntry
{
public:
    int x;
    int y;
    int directions[4];
    int layers[4];
};




// ============================================================================
//  DirectionMap Class
// ============================================================================
class DirectionMap : public Map
{

protected:
// =======================================================
//  Data
// =======================================================

// -------------------------------------------------------
// Name:        m_rooms
// Description: The array of the rooms in the map
// -------------------------------------------------------
    Array<DirectionCell> m_rooms;

// -------------------------------------------------------
// Name:        m_tilebmps
// Description: an array of bitmaps that the tiles will
//              be drawn from
// -------------------------------------------------------
    SDL_Surface** m_tilebmps;


// =======================================================
//  New Functions
// =======================================================
public:
// -------------------------------------------------------
// Name:        DirectionMap
// Description: Constructor, constructs the map with the
//              given tile set
// -------------------------------------------------------
    DirectionMap( SDL_Surface** p_tilebmps )
             : m_rooms( 0 )
    {
        m_tilebmps = p_tilebmps;
    }


// -------------------------------------------------------
// Name:        ~DirectionMap
// Description: destructor, deletes everything on the map
// -------------------------------------------------------
    ~DirectionMap()
    {
        int x;

        // go through all of the rooms and delete the items
        // and persons.
        for( x = 0; x < m_rooms.Size(); x++ )
        {
            if( m_rooms[x].m_item != 0 )
                delete m_rooms[x].m_item;
            if( m_rooms[x].m_person != 0 )
                delete m_rooms[x].m_person;
            m_rooms[x].m_item = 0;
            m_rooms[x].m_person = 0;
        }  
    }

 

// -------------------------------------------------------
// Name:        LoadFromFile
// Description: Loads the map from a file
// -------------------------------------------------------
    void LoadFromFile( char* p_filename )
    {
        int x;
        int maptype;
        int cells;
        MapEntry entry;

        // open the file
        FILE* f = fopen( p_filename, "rb" );

        // file cant be opened, return
        if( f == 0 )
            return;

        // read in the map type.
        fread( &maptype, 1, sizeof(int), f );

        // quit out if type isn't 1
        if( maptype != 1 )
        {
            fclose( f );
            return;
        }
        
        // read in the size of the map
        fread( &cells, 1, sizeof(int), f );

        // resize the map so that it fits
        m_rooms.Resize( cells );

        // read in the room data
        for( x = 0; x < cells; x++ )
        {
            // read in each room
            fread( &entry, 1, sizeof(MapEntry), f );

            // load in the tile numbers for the 2 layers
            m_rooms[x].m_tiles[0] = entry.layers[0];
            m_rooms[x].m_tiles[1] = entry.layers[1];

            // load in the coordinates
            m_rooms[x].m_x = entry.x;
            m_rooms[x].m_y = entry.y;

            // read in the item and person
            if( entry.layers[2] != -1 )
            {
                m_rooms[x].m_item = MakeItem( entry.layers[2],
                                              entry.x,
                                              entry.y,
                                              x );
            }
            if( entry.layers[3] != -1 )
            {
                m_rooms[x].m_person = MakePerson( entry.layers[3],
                                                  entry.x,
                                                  entry.y,
                                                  x );

                // check to see if the person is the player of the game
                if( entry.layers[3] == 0 )
                {
                    SetViewer( m_rooms[x].m_person );
                }
            }

            // load up the exits of the room.
            m_rooms[x].m_exits[0] = entry.directions[0];
            m_rooms[x].m_exits[1] = entry.directions[1];
            m_rooms[x].m_exits[2] = entry.directions[2];
            m_rooms[x].m_exits[3] = entry.directions[3];
        }


        // read the exits in
        fread( m_exits[0], 64, sizeof(char), f );
        fread( m_exits[1], 64, sizeof(char), f );
        fread( m_exits[2], 64, sizeof(char), f );

        // close the file
        fclose( f );
    }



// =======================================================
//  New Functions
// =======================================================

// -------------------------------------------------------
// Name:        Draw
// Description: Draws the map onto the given surface, 
//              using the viewers coordinates as the
//              midpoint of the screen.
// -------------------------------------------------------
    void Draw( SDL_Surface* p_surface, int p_midx, int p_midy )
    {
        int i, z;               // counting variables
        int px, py;             // pixel coordinates
        int ox, oy;             // offset coordinates
        int current;
        Item* item;
        Person* person;

        // calculate the offsetsfrom the viewer
        ox = (-m_viewer->GetX() * 64) + p_midx - 32;
        oy = (-m_viewer->GetY() * 64) + p_midy - 32;

        for( i = 0; i < m_rooms.Size(); i++ )
        {
            // calculate the coordinates of the current tile
            px = m_rooms[i].m_x * 64 + ox;
            py = m_rooms[i].m_y * 64 + oy;

            for( z = 0; z < 2; z++ )
            {
                current = m_rooms[i].m_tiles[z];
                if( current != -1 )
                {
                    // draw the tile
                    SDLBlit( m_tilebmps[current], p_surface, px, py );
                }
            }

            item = m_rooms[i].m_item;
            person = m_rooms[i].m_person;
            if( item != 0 )
                SDLBlit( item->GetGraphic(), p_surface, px, py );
            if( person != 0 )
                SDLBlit( person->GetGraphic(), p_surface, px, py );
        }
    }


// -------------------------------------------------------
// Name:        CanMove
// Description: Determines if the given person can move
//              in the given direction
// -------------------------------------------------------
    bool CanMove( Person* p_person, int p_direction )
    {
        int cell = GetCellNumber( p_person->GetCell(), p_direction );

        if( cell == -1 )
            return false;

        // check to see if the path is blocked or not.
        if( m_rooms[cell].m_blocked == true )
            return false;

        // check to see if there is a person blocking the way
        if( m_rooms[cell].m_person != 0 )
            return false;

        // check to see if there in an item blocking the way
        if( m_rooms[cell].m_item != 0 )
        {
            // some items can block, others can't
            if( m_rooms[cell].m_item->CanBlock() == true )
                return false;
        }

        return true;
    }


// -------------------------------------------------------
// Name:        Move
// Description: Moves the given person in the given
//              direction
// -------------------------------------------------------
    void Move( Person* p_person, int p_direction )
    {
        int newcell;

        // make sure the player can move
        if( CanMove( p_person, p_direction ) == true )
        {
            // get the number of the new cell
            newcell = GetCellNumber( p_person->GetCell(), p_direction );

            // move the person to the new cell
            m_rooms[newcell].m_person = p_person;

            // clear the person pointer in the old cell
            m_rooms[p_person->GetCell()].m_person = 0;

            // set the new x, y, and cell variables
            p_person->SetX( m_rooms[newcell].m_x );
            p_person->SetY( m_rooms[newcell].m_y );
            p_person->SetCell( newcell );
        }
    }


// -------------------------------------------------------
// Name:        GetItem
// Description: Gets a pointer to the item in the given
//              cell
// -------------------------------------------------------
    Item* GetItem( int p_cell )
    {
        // check to see if the cell is in bounds first
        if( p_cell >= GetNumberOfCells() || p_cell < 0 )
            return 0;

        return m_rooms[p_cell].m_item;
    }


// -------------------------------------------------------
// Name:        SetItem
// Description: Sets the item in the given cell.
// -------------------------------------------------------
    void SetItem( int p_cell, Item* p_item )
    {
        // check to see if the cell is in bounds first
        if( p_cell >= GetNumberOfCells() || p_cell < 0 )
            return;

        m_rooms[p_cell].m_item = p_item;
    }

    
// -------------------------------------------------------
// Name:        GetPerson
// Description: Gets a pointer to the person in the given
//              cell
// -------------------------------------------------------
    Person* GetPerson( int p_cell )
    {
        // check to see if the cell is in bounds first
        if( p_cell >= GetNumberOfCells() || p_cell < 0 )
            return 0;

        return m_rooms[p_cell].m_person;
    }


// -------------------------------------------------------
// Name:        SetPerson
// Description: sets the person in the given cell.
// -------------------------------------------------------
    void SetPerson( int p_cell, Person* p_person )
    {
        // check to see if the cell is in bounds first
        if( p_cell >= GetNumberOfCells() || p_cell < 0 )
            return;

        m_rooms[p_cell].m_person = p_person;
    }


// -------------------------------------------------------
// Name:        GetCellNumber
// Description: Gets the number of the cell in the
//              given direction
// -------------------------------------------------------
    int GetCellNumber( int p_cell, int p_direction )
    {
        return m_rooms[p_cell].m_exits[p_direction];
    }

    
// -------------------------------------------------------
// Name:        GetNumberOfCells
// Description: Gets the number of cells in the map
// -------------------------------------------------------
    int GetNumberOfCells()
    {
        return m_rooms.Size();
    }


// -------------------------------------------------------
// Name:        GetClosestDirection
// Description: Gets the direction that will move the
//              first person closer to the second person.
// -------------------------------------------------------
    int GetClosestDirection( Person* p_one, Person* p_two )
    {
        int direction = -1;

        // if person 1 is above person 2, then go north
        if( p_one->GetY() > p_two->GetY() )
            direction = 0;
        // if person 1 is left of person 2, then go east
        else if( p_one->GetX() < p_two->GetX() )
            direction = 1;
        // if person 1 is below person 2, then go south
        else if( p_one->GetY() < p_two->GetY() )
            direction = 2;
        // if person 1 is right of person 2, then go west
        else if( p_one->GetX() > p_two->GetX() )
            direction = 3;

        return direction;
    }

};







#endif

⌨️ 快捷键说明

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