zoukankan      html  css  js  c++  java
  • XNA之RPG游戏开发教程之四

    继续上一节,今天主要是要完成游戏中地图的绘制;这里将会用到tiling方法,通过拼图的方式绘制整幅地图。任务如下:搭建有关Tile engine的整体架构

    第一步就是把我们游戏中要用到的Tile下载下来,并添加到EyesOfTheDragonContent中去,下载地址: http://xnagpa.net/xna4/downloads/tilesets.zip

    我们这里使用的Tile引擎是最简单的一种,是分层拼图引擎,很好理解,将地图上的精灵分层绘制,不同层次有不同的精灵元素。在XRpgLibrary下添加一个新的文件夹TileEngine,添加Engine类如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    namespace XRpgLibrary.TileEngine
    {
    public class Engine
     {
     #region Field Region
    static int tileWidth;//屏幕宽度方向上tile的个数
    static int tileHeight;//屏幕高度方向上tile的个数 #endregion #region Property Region//这两个属性的对外接口 public static int TileWidth { get { return tileWidth; } } public static int TileHeight { get { return tileHeight; } } #endregion #region Constructors public Engine(int tileWidth, int tileHeight) { Engine.tileWidth = tileWidth; Engine.tileHeight = tileHeight; } #endregion #region Methods//获取一个向量在tile矩阵中的位置 public static Point VectorToCell(Vector2 position) { return new Point((int)position.X / tileWidth, (int)position.Y / tileHeight); } #endregion } }

    地图上的tile当然不是一个,我们要构建一个tileset类来对一个tile集合进行管理

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    namespace XRpgLibrary.TileEngine
    {
    public class Tileset
     {
     #region Fields and PropertiesTexture2D image;
    int tileWidthInPixels;//图片中一个tile的宽度(以像素作为计量)
    int tileHeightInPixels;
    int tilesWide;//图片宽度方向的tile个数
    int tilesHigh;
    Rectangle[] sourceRectangles;//图片中每个tile对应矩形的集合数组
     #endregion
     #region Property Region//对外接口
    public Texture2D Texture
     {
    get { return image; }
    private set { image = value; }
     }
    public int TileWidth
     {
    get { return tileWidthInPixels; }
    private set { tileWidthInPixels = value; }
     }
    public int TileHeight
     {
    get { return tileHeightInPixels; }
    private set { tileHeightInPixels = value; }
     }
    public int TilesWide
     {
    get { return tilesWide; }
    private set { tilesWide = value; }
     }
    public int TilesHigh
     {
    get { return tilesHigh; }
    private set { tilesHigh = value; }
     }
    public Rectangle[] SourceRectangles
     {
    get { return (Rectangle[])sourceRectangles.Clone(); }
     }
     #endregion
     #region Constructor Region
    public Tileset(Texture2D image, int tilesWide, int tilesHigh, int tileWidth, int
    tileHeight)
     {
     Texture = image;
     TileWidth = tileWidth;
     TileHeight = tileHeight;
     TilesWide = tilesWide;
     TilesHigh = tilesHigh;
    int tiles = tilesWide * tilesHigh;
     sourceRectangles = new Rectangle[tiles];
    int tile = 0;
    //初始化图片中tile所对应的矩形区域
    for (int y = 0; y < tilesHigh; y++) for (int x = 0; x < tilesWide; x++) { sourceRectangles[tile] = new Rectangle( x * tileWidth, y * tileHeight, tileWidth, tileHeight); tile++; } } #endregion #region Method Region #endregion } }

    以上代码可以看出,对于tile对象的管理是通过其在tileset中的索引来实现的,为了更好的管理tile,同时也为实现多层的map,构建以tile类来对其信息进行管理

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace XRpgLibrary.TileEngine{
    public class Tile
     {
     #region Field Region
     int tileIndex;//tile在当前集合中的索引
     int tileset;//tile所在集合的索引
     #endregion
     #region Property Region
    public int TileIndex
     {
      get { return tileIndex; }
      private set { tileIndex = value; }
     }
    public int Tileset
     {
      get { return tileset; }
      private set { tileset = value; }
     }
     #endregion
     #region Constructor Region
    public Tile(int tileIndex, int tileset)
     {
      TileIndex = tileIndex;
      Tileset = tileset;
     }
     #endregion
     }
    }

    下面构建一个地图层级类,来管理每一层地图的绘制,代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace XRpgLibrary.TileEngine
    {
    public class MapLayer
     {
     #region Field Region
     Tile[,] map;//Tile类型的数组,用于存储一层中所有Tile对象
     #endregion
     #region Property Region
    public int Width
     {
    get { return map.GetLength(1); }//获得地图的宽
     }
    public int Height
     {
    get { return map.GetLength(0); }//获得地图的高
     }
     #endregion
     #region Constructor Region//用tile数组对象来初始化地图层对象
    public MapLayer(Tile[,] map)
     {
    this.map = (Tile[,])map.Clone();
     }
    //用宽,高来初始化一层地图对象
    public MapLayer(int width, int height) { map = new Tile[height, width]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { map[y, x] = new Tile(0, 0);//地图中的每个对象都初始化为第0个tileset集合中的第0个tile } } } #endregion #region Method Region//对外接口 public Tile GetTile(int x, int y) { return map[y, x]; } public void SetTile(int x, int y, Tile tile) { map[y, x] = tile; } public void SetTile(int x, int y, int tileIndex, int tileset) { map[y, x] = new Tile(tileIndex, tileset); } #endregion } }

    紧接着就是构造TileMap类,这也是整个地图机制中的核心类,绘制地图的主要逻辑实现都在该类中,先看代码吧

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    namespace XRpgLibrary.TileEngine
    {
    public class TileMap
     {
     #region Field Region
    List<Tileset> tilesets;//tile集合队列
    List<MapLayer> mapLayers;//地图层级队列
     #endregion
     #region Property Region
     #endregion
     #region Constructor Region//构造函数
    public TileMap(List<Tileset> tilesets, List<MapLayer> layers)
     {
    this.tilesets = tilesets;
    this.mapLayers = layers;
     }public TileMap(Tileset tileset, MapLayer layer)
     {
     tilesets = new List<Tileset>();
     tilesets.Add(tileset);
     mapLayers = new List<MapLayer>();
     mapLayers.Add(layer);
     }
     #endregion
     #region Method Region
    //地图绘制 public void Draw(SpriteBatch spriteBatch) {
    //根据Engine对象初始化一个绘制矩形区域 Rectangle destination
    = new Rectangle(0, 0, Engine.TileWidth, Engine.TileHeight); Tile tile;
    //最外层的是地图层级的遍历
    foreach (MapLayer layer in mapLayers) {
    //对该层地图上的每个tile进行遍历,绘制
    for (int y = 0; y < layer.Height; y++) { destination.Y = y * Engine.TileHeight; for (int x = 0; x < layer.Width; x++) { tile = layer.GetTile(x, y); destination.X = x * Engine.TileWidth; spriteBatch.Draw( tilesets[tile.Tileset].Texture, destination, tilesets[tile.Tileset].SourceRectangles[tile.TileIndex], Color.White); } } } } #endregion } }

    最后一步就是要将地图的绘制到GamePlayScreen页面上,该页面代码更改如下

    #region Field Region
    Engine engine = new Engine(32, 32);
    Tileset tileset;
    TileMap map;
    #endregion

    先添加几个类级变量,接下来要在LoadContent方法中加载绘制地图要用的相关对象

    protected override void LoadContent()
    { 
     Texture2D tilesetTexture = Game.Content.Load<Texture2D>(@"Tilesets\tileset1");
     tileset = new Tileset(tilesetTexture, 8, 8, 32, 32);
     MapLayer layer = new MapLayer(40, 40);
    for (int y = 0; y < layer.Height; y++)
     {
    for (int x = 0; x < layer.Width; x++)
     {
     Tile tile = new Tile(0, 0);
     layer.SetTile(x, y, tile);
     }
     }
     map = new TileMap(tileset, layer);
    base.LoadContent();
    }

    最后是绘制地图

    public override void Draw(GameTime gameTime)
    {
     GameRef.SpriteBatch.Begin(
    SpriteSortMode.Immediate,
    BlendState.AlphaBlend,
    SamplerState.PointClamp,
    null,
    null,
    null,
    Matrix.Identity);
     map.Draw(GameRef.SpriteBatch);
    base.Draw(gameTime);
     GameRef.SpriteBatch.End();
    }

  • 相关阅读:
    cat n个文件 June
    promise 码农
    [Linux]加载iso文件,并绑定到FTP共享
    [Linux]解决一例多个硬盘Linux启动的问题
    [CentOS]创建yum本地源
    [Java]服务器端用 Axis1.4 返回复杂对象记录
    [chs]Axis2 Binary Distribution 安装指南
    [CentOS]开启yum缓存
    [转]CSS hack总结
    闭包匿名闭包
  • 原文地址:https://www.cnblogs.com/zcftech/p/2999359.html
Copyright © 2011-2022 走看看