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

📄 g19-02.cpp

📁 游戏开发数据结构-Data.Structures.for.Game.Programmers
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ============================================================================
//  GD19-02.cpp
//  DirectionMap Editor
// ============================================================================
#include "SDLGUI.h"
#include <stdlib.h>
#include <time.h>
#include "Array3D.h"
#include "Array2D.h"
#include "Array.h"


// ============================================================================
//  Global Constants
// ============================================================================
const char PROGRAM_NAME[]   = "DirectionEditor Demonstration";
const int WIDTH             = 800;
const int HEIGHT            = 600;
const int ITEMS             = 32;
const int ARIAL             = 0;
const int GROUPS            = 9;
const int DIRECTIONTABLE[4][2] = { { 0, -1 }, 
                                   { 1, 0 }, 
                                   { 0, 1 }, 
                                   { -1, 0 } };

// ============================================================================
//  Classes
// ============================================================================

// this class stores all of the information that will be stored in each
// entry on disk.
class MapEntry
{
public:
    int x;
    int y;
    int directions[4];
    int layers[4];
};


// ============================================================================
//  Global Variables
// ============================================================================
SDLGUI* g_gui;

// the map
Array3D<int> g_map( 64, 64, 4 );

// the current tile and layer indexes.
int g_currenttile = -1;
int g_currentlayer = 1;


// the group system is used to display your palette of tiles.
// each bunch of tiles will be associated with a "Group", such
// as grass, snow base layer, road, items, etc.
// there are a maximum of 8 groups, and 8 tiles per group.

// the index of the current group
int g_currentgroup = 0;

// the starting bitmap index of the groups
int g_groupstarts[GROUPS];

// the number of tiles in each group
int g_groupcounts[GROUPS];

// the layer that the group belongs to
int g_grouplayers[GROUPS];



// determine whether or not the "current" tile should be drawn in blue.
bool g_drawcurrenttile = false;


// is the mouse down?
bool g_mousedown = false;


// the bitmap graphics, organized into three categories 
// (tiles, items, persons), 64 total styles per category, 
// then a large and a small bitmap for each.
SDL_Surface* g_bmps[3][64][2];


// the filename for the current map
char g_filename[64] = "default.map";


// the filenames for the next map
char g_exits[3][64] = { "", "", "" } ;



// ============================================================================
//  Drawing
// ============================================================================
void DrawMap()
{
    int x;
    int y;
    int z;
    int tile;

    g_gui->Box( 0, 0, 512, 512, GREY );
    // draw the bottom two tile layers
    for( z = 0; z < 2; z++ )
    {
        for( y = 0; y < g_map.Height(); y++ )
        {
            for( x = 0; x < g_map.Width(); x++ )
            {
                // get the tile
                tile = g_map.Get( x, y, z );

                // if the tile is valid
                if( tile != -1 )
                {
                    // check to see if the tile should be "blue", if it is the
                    // current tile.
                    if( g_drawcurrenttile == true && 
                        g_currenttile == tile &&
                        g_currentlayer < 2 )
                    {
                        g_gui->Box( x * 8, y * 8, 8, 8, BLUE );
                    }
                    else
                    {
                        g_gui->Blit( g_bmps[0][tile][1], x * 8, y * 8 );
                    }
                }
            }
        }
    }

    // draw the items
    for( y = 0; y < g_map.Height(); y++ )
    {
        for( x = 0; x < g_map.Width(); x++ )
        {
            // get the item number
            tile = g_map.Get( x, y, 2 );

            if( tile != -1 )
            {
                if( g_drawcurrenttile == true && 
                    g_currenttile == tile &&
                    g_currentlayer == 2 )
                {
                    g_gui->Box( x * 8, y * 8, 8, 8, BLUE );
                }
                else
                {
                    g_gui->Blit( g_bmps[1][tile][1], x * 8, y * 8 );
                }
            }
        }
    }

    // draw the people
    for( y = 0; y < g_map.Height(); y++ )
    {
        for( x = 0; x < g_map.Width(); x++ )
        {
            // get the cell
            tile = g_map.Get( x, y, 3 );

            if( tile != -1 )
            {
                if( g_drawcurrenttile == true && 
                    g_currenttile == tile &&
                    g_currentlayer == 3 )
                {
                    g_gui->Box( x * 8, y * 8, 8, 8, BLUE );
                }
                else
                {
                    g_gui->Blit( g_bmps[2][tile][1], x * 8, y * 8 );
                }
            }
        }
    }
}



void DrawMiniMap()
{
    int x, y;           // coordinates of the mouse, then used to loop
    int gx, gy;         // coordinates of the tile
    int ox, oy;         // offset pixels

    static SDL_Rect rect = { 608, 0, 192, 192 };

    // get the mouse coordinates.
    SDL_GetMouseState( &x, &y );

    // the mouse is over the map, so draw the minimap.
    if( x < 512 && y < 512 )
    {
        // set the clipping rectangle, so that nothing is drawn
        // outside of the minimap viewer.
        SDL_SetClipRect( g_gui->GetScreen(), &rect );

        // figure out the coordinates of the tile in the map.
        gx = (x / 8);
        gy = (y / 8);

        // figure out the pixel offset of the minimap
        ox = (x - (gx * 8)) * 8;
        oy = (y - (gy * 8)) * 8;

        // figure out the coordinates of the tile that is left-up by 2 squares,
        // because this draws a 5x5 grid centered on the current cell
        gx -= 2;
        gy -= 2;

        for( y = gy; y < gy + 5; y++ )
        {
            for( x = gx; x < gx + 5; x++ )
            {
                if( x >= 0 && x < g_map.Width() && 
                    y >= 0 && y < g_map.Height() )
                {
                    if( g_map.Get( x, y, 0 ) != -1 )
                    {
                        g_gui->Blit( g_bmps[0][g_map.Get( x, y, 0 )][0], 
                                     (x - gx) * 64 + 544 - ox, 
                                     (y - gy) * 64 - 64 - oy );
                    }
                    if( g_map.Get( x, y, 1 ) != -1 )
                    {
                        g_gui->Blit( g_bmps[0][g_map.Get( x, y, 1 )][0], 
                                     (x - gx) * 64 + 544 - ox, 
                                     (y - gy) * 64 - 64 - oy );
                    }
                    if( g_map.Get( x, y, 2 ) != -1 )
                    {
                        g_gui->Blit( g_bmps[1][g_map.Get( x, y, 2 )][0], 
                                     (x - gx) * 64 + 544 - ox, 
                                     (y - gy) * 64 - 64 - oy );
                    }
                    if( g_map.Get( x, y, 3 ) != -1 )
                    {
                        g_gui->Blit( g_bmps[2][g_map.Get( x, y, 3 )][0], 
                                     (x - gx) * 64 + 544 - ox, 
                                     (y - gy) * 64 - 64 - oy );
                    }
                }
            }
        }

        // reset the clipping to the entire screen
        SDL_SetClipRect( g_gui->GetScreen(), 0 );
    }

    // draw the red box around the minimap
    g_gui->Line( 608, 0, 799, 0, RED );
    g_gui->Line( 608, 191, 799, 191, RED );
    g_gui->Line( 608, 0, 608, 191, RED );
    g_gui->Line( 799, 0, 799, 191, RED );

}


void DrawTile( int p_x, int p_y )
{
    int z;

    if( p_x < g_map.Width() && p_y < g_map.Height() )
    {
        // if the user isn't drawing a base tile, then
        // make sure that a base tile exists. You want to make it
        // impossible to draw onto a tile without it actually
        // existing first. If the tile being drawn isn't a base tile, 
        // and the base tile is invalid, then just return.
        if( (g_currentlayer > 0 && g_map.Get( p_x, p_y, 0 ) == -1) )
            return;

        // if the user is clearing the base tile, then all the other 
        // layers need to be cleared out as well.
        if( g_currentlayer == 0 && g_currenttile == -1 )
        {
            for( z = 0; z < 4; z++ )
            {
                g_map.Get( p_x, p_y, z ) = -1;
            }
        }
        else
        {
            // else, just draw the tile as normal.
            g_map.Get( p_x, p_y, g_currentlayer ) = g_currenttile;
        }
    }
}


void DrawPalette()
{
    int x;
    int current = g_groupstarts[g_currentgroup];
    SDL_Color c;
    int layer = g_grouplayers[g_currentgroup] - 1;
    if( layer == -1 )
        layer = 0;

    // for each tile in the grup
    for( x = 0; x < g_groupcounts[g_currentgroup]; x++ )
    {
        // blit its image
        g_gui->Blit( g_bmps[layer][current][0], x * 64, 536 );

        // figure out if the outline should be black or red,
        // depending on if the tile is the current tile or not.
        if( current == g_currenttile && 
            g_grouplayers[g_currentgroup] == g_currentlayer )
        {
            c = RED;
        }
        else
        {
            c = BLACK;
        }

        // draw the black or red outline
        g_gui->Line( x * 64, 536, x * 64 + 63, 536, c );
        g_gui->Line( x * 64, 599, x * 64 + 63, 599, c );
        g_gui->Line( x * 64, 536, x * 64, 599, c );
        g_gui->Line( x * 64 + 63, 536, x * 64 + 63, 599, c );

        current++;
    }
}


// ============================================================================
//  Button Callbacks
// ============================================================================
void Highlight()
{
    g_drawcurrenttile = !g_drawcurrenttile;
}


void Save()
{
    // this is a single entry, which will be used to save
    // the data to disk
    MapEntry entry;

    // this array is used to store the cell numbers of all
    // of the tiles in the map
    Array2D<int> cellnumbers( g_map.Width(), g_map.Height() );

    // this stores the number of tiles in the map.
    int tilecount = 0;

    int x, y, z;
    int ax, ay;
    int d;

    // open the file
    FILE* f = fopen( g_filename, "wb" );
    
    // return if the file could not be opened
    if( f == 0 )
        return;

    // count the number of tiles in the map, and calculate the tile
    // numbers.
    for( y = 0; y < g_map.Height(); y++ )
    {
        for( x = 0; x < g_map.Width(); x++ )
        {
            if( g_map.Get( x, y, 0 ) != -1 )
            {
                cellnumbers.Get( x, y ) = tilecount;
                tilecount++;
            }
        }
    }


    // write the file type "1", which means "direction table map"
    x = 1;
    fwrite( &x, 1, sizeof(int), f );

    // write the number of rooms
    fwrite( &tilecount, 1, sizeof(int), f );

    // now go through every tile in the map, and write it to disk.
    for( y = 0; y < g_map.Height(); y++ )
    {
        for( x = 0; x < g_map.Width(); x++ )
        {
           
            // if the tile is valid...
            if( g_map.Get( x, y, 0 ) != -1 )
            {
                entry.x = x;
                entry.y = y;

                // loop through each direction
                for( d = 0; d < 4; d++ )
                {
                    // calculate the coordinates of the cell
                    // in that direction
                    ax = DIRECTIONTABLE[d][0] + x;
                    ay = DIRECTIONTABLE[d][1] + y;

                    // set the direction entry to -1 by default,
                    // which means there is no exit.
                    entry.directions[d] = -1;

                    // if that cell is valid...
                    if( ax >= 0 && ax < g_map.Width() && 
                        ay >= 0 && ay < g_map.Height() )
                    {
                        // make sure there is a cell there.
                        if( g_map.Get( ax, ay, 0 ) != -1 )
                        {
                            // set the entry of that cell in the
                            // current direction.
                            entry.directions[d] = 
                                cellnumbers.Get( ax, ay );
                        }
                    }
                }

⌨️ 快捷键说明

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