MapSquare以及它们的使用方式

时间:2013-11-13 13:55:03

标签: c# xna

在我的Gemstone Hunter项目中,我使用了多个MapSquare,并对它们的使用方式感到困惑。首先,他们在做什么? (static private MapSquare[,] mapCells = new MapSquare[MapWidth, MapHeight];)是否正在制作mapCells,然后为了给它实际形状,它使用int的MapWidthMapHeight?另外,mapCells[x, y] = new MapSquare(skyTile, 0, 0, "", true);当它只能容纳x时,y,更不用说一个字符串和5个变量了?

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Tile_Engine
{
public static class TileMap
{
    #region Declarations
    //TileWidth, and TileHeight are the size that each tile will be when playing and editing the game.
    public const int TileWidth = 48;
    public const int TileHeight = 48;
    //MapWidth and MapHeight create the world size
    public const int MapWidth = 160;
    public const int MapHeight = 12;
    //MapLyaers represent the three back grounds in the MapSquare class.
    public const int MapLayers = 3;
    //skyTile is the blue tile that will be on the background, or the 
    private const int skyTile = 2;

    //MapSquare organizes the tile sheet into map cells by width and height. 
    static private MapSquare[,] mapCells =
        new MapSquare[MapWidth, MapHeight];

    //Tells the the game if its playing or editing the maps.
    public static bool EditorMode = true;

    public static SpriteFont spriteFont;
    static private Texture2D tileSheet;
    #endregion

    #region Initialization
    //The Initialize() method establishes all of the MapCells as MapSquares with empty tiles on each layer.
    //On back ground skyTile (2) will be the blue background, 0 will be transparent.
    static public void Initialize(Texture2D tileTexture)
    {
        tileSheet = tileTexture;

        for (int x = 0; x < MapWidth; x++)//How long the map is.
        {
            for (int y = 0; y < MapHeight; y++)//How high is the map.
            {
                for (int z = 0; z < MapLayers; z++)//In this case z is 3, for background, interactive, and forground.
                {
                    mapCells[x, y] = new MapSquare(skyTile, 0, 0, "", true);
                }
            }
        }
    }
    #endregion

    #region Tile and Tile Sheet Handling
    //TilesPerRow calls on a get to do the math to use latter in TileSourceRectangle()
    public static int TilesPerRow
    {
        get { return tileSheet.Width / TileWidth; }
    }

    public static Rectangle TileSourceRectangle(int tileIndex)
    {
        return new Rectangle(
            (tileIndex % TilesPerRow) * TileWidth,
            (tileIndex / TilesPerRow) * TileHeight,
            TileWidth,
            TileHeight);
    }
    #endregion

    #region Information about Map Cells
    static public int GetCellByPixelX(int pixelX)
    {
        return pixelX / TileWidth;
    }

    static public int GetCellByPixelY(int pixelY)
    {
        return pixelY / TileHeight;
    }

    static public Vector2 GetCellByPixel(Vector2 pixelLocation)
    {
        return new Vector2(
            GetCellByPixelX((int)pixelLocation.X),
            GetCellByPixelY((int)pixelLocation.Y));
    }

    static public Vector2 GetCellCenter(int cellX, int cellY)
    {
        return new Vector2(
            (cellX * TileWidth) + (TileWidth / 2),
            (cellY * TileHeight) + (TileHeight / 2));
    }

    static public Vector2 GetCellCenter(Vector2 cell)
    {
        return GetCellCenter(
            (int)cell.X,
            (int)cell.Y);
    }

    static public Rectangle CellWorldRectangle(int cellX, int cellY)
    {
        return new Rectangle(
            cellX * TileWidth,
            cellY * TileHeight,
            TileWidth,
            TileHeight);
    }

    static public Rectangle CellWorldRectangle(Vector2 cell)
    {
        return CellWorldRectangle(
            (int)cell.X,
            (int)cell.Y);
    }

    static public Rectangle CellScreenRectangle(int cellX, int cellY)
    {
        return Camera.WorldToScreen(CellWorldRectangle(cellX, cellY));
    }

    static public Rectangle CellSreenRectangle(Vector2 cell)
    {
        return CellScreenRectangle((int)cell.X, (int)cell.Y);
    }

    static public bool CellIsPassable(int cellX, int cellY)
    {
        MapSquare square = GetMapSquareAtCell(cellX, cellY);
        if (square == null)
            return false;
        else
            return square.Passable;
    }

    static public bool CellIsPassable(Vector2 cell)
    {
        return CellIsPassable((int)cell.X, (int)cell.Y);
    }

    static public bool CellIsPassableByPixel(Vector2 pixelLocation)
    {
        return CellIsPassable(
            GetCellByPixelX((int)pixelLocation.X),
            GetCellByPixelY((int)pixelLocation.Y));
    }

    static public string CellCodeValue(int cellX, int cellY)
    {
        MapSquare square = GetMapSquareAtCell(cellX, cellY);
        if (square == null)
            return "";
        else
            return square.CodeValue;
    }

    static public string CellCodeValue(Vector2 cell)
    {
        return CellCodeValue((int)cell.X, (int)cell.Y);
    }
    #endregion

    #region Information about MapSquare objects
    static public MapSquare GetMapSquareAtCell(int tileX, int tileY)
    {
        if ((tileX >= 0) && (tileX < MapWidth) &&
            (tileY >= 0) && (tileY < MapHeight))
        {
            return mapCells[tileX, tileY];
        }
        else
        {
            return null;
        }
    }
    static public void SetMapSquareAtCell(
        int tileX,
        int tileY,
        MapSquare tile)
    {
        if ((tileX >= 0) && (tileX < MapWidth) &&
            (tileY >= 0) && (tileY < MapHeight))
        {
            mapCells[tileX, tileY] = tile;
        }
    }
    //SetTileAtCell()'s prupose is to provide a way to change the tile index of a single layer in a cell without repackaging the cell's entire MapSquare object.
    //By passing SetTileAtCell() a cell location, layer number, and tile index, we can change the content of a single layer--exactly what we will need to do when
    //building the map editor.
    static public void SetTileAtCell(
        int tileX,
        int tileY,
        int layer,
        int tileIndex)
    {
        if ((tileX >= 0) && (tileX < MapWidth) &&
            (tileY >= 0) && (tileY < MapHeight))
        {
            mapCells[tileX, tileY].LayerTiles[layer] = tileIndex;
        }
    }

    static public MapSquare GetMapSquareAtPixel(int pixelX, int pixelY)
    {
        return GetMapSquareAtCell(
            GetCellByPixelX(pixelX),
            GetCellByPixelY(pixelY));
    }

    static public MapSquare GetMapSquareAtPixel(Vector2 pixelLocation)
    {
        return GetMapSquareAtPixel(
            (int)pixelLocation.X,
            (int)pixelLocation.Y);
    }
    #endregion

    #region Drawing
    static public void Draw(SpriteBatch spriteBatch)
    {
        int startX = GetCellByPixelX((int)Camera.Position.X);
        int endX = GetCellByPixelX((int)Camera.Position.X +
            Camera.ViewPortWidth);

        int startY = GetCellByPixelY((int)Camera.Position.Y);
        int endY = GetCellByPixelY((int)Camera.Position.Y +
            Camera.ViewPortHeight);

        for (int x = startX; x <= endX; x++)
            for (int y = startY; y <= endY; y++)
            {
                for (int z = 0; z < MapLayers; z++)
                {
                    if ((x >= 0) && (y >= 0) &&
                        (x < MapWidth) && (y < MapHeight))
                    {
                        spriteBatch.Draw(
                            tileSheet,
                            CellScreenRectangle(x, y),
                            TileSourceRectangle(
                            mapCells[x, y].LayerTiles[z]),
                            Color.White,
                            0.0f,
                            Vector2.Zero,
                            SpriteEffects.None,
                            1f - ((float)z * 0.1f));
                    }
                }

                if (EditorMode)
                {
                    DrawEditModeItems(spriteBatch, x, y);
                }
            }
    }

    public static void DrawEditModeItems(
        SpriteBatch spriteBatch,
        int x,
        int y)
    {
        if ((x < 0) || (x >= MapWidth) ||
            (y < 0) || (y >= MapHeight))
            return;

        if (!CellIsPassable(x, y))
        {
            spriteBatch.Draw(
                tileSheet,
                CellScreenRectangle(x, y),
                TileSourceRectangle(1),
                new Color(255, 0, 0, 80),
                0.0f,
                Vector2.Zero,
                SpriteEffects.None,
                0.0f);
        }
        if (mapCells[x, y].CodeValue != "")
        {
            Rectangle screenRect = CellScreenRectangle(x, y);

            spriteBatch.DrawString(
                spriteFont,
                mapCells[x, y].CodeValue,
                new Vector2(screenRect.X, screenRect.Y),
                Color.White,
                0.0f,
                Vector2.Zero,
                1.0f,
                SpriteEffects.None,
                0.0f);
        }
    }
    #endregion

    #region Loading and Saving Maps
    public static void SaveMap(FileStream fileStream)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(fileStream, mapCells);
        fileStream.Close();
    }

    public static void LoadMap(FileStream fileStream)
    {
        try
        {
            BinaryFormatter formatter = new BinaryFormatter();
            mapCells =
                (MapSquare[,])formatter.Deserialize(fileStream);
            fileStream.Close();
        }
        catch
        {
            ClearMap();
        }
    }

    public static void ClearMap()
    {
        for (int x = 0; x < MapWidth; x++)
            for (int y = 0; y < MapHeight; y++)
                for (int z = 0; z < MapLayers; z++)
                {
                    mapCells[x, y] = new MapSquare(2, 0, 0, "", true);
                }
    }
    #endregion

}
}

1 个答案:

答案 0 :(得分:1)

static private MapSquare[,] mapCells = new MapSquare[MapWidth, MapHeight];

这里,我们实例化一个名为mapCells的静态数组。此特定数组是二维的,因此您可以将其视为可以使用x,y坐标访问的网格。此网格中的每个“单元格”都是MapSquare类型的对象。

MapWidth和MapHeight是网格将包含的单元格数。

mapCells[x, y] = new MapSquare(skyTile, 0, 0, "", true);

上面,我们正在初始化其中一个单元格。请注意,它是MapSquare类型,因此,它使用与MapSquare对象关联的构造函数(这将是项目中的另一个类)。

看看MapSquare类,您将能够看到这些参数的用途。