第四章:封装纹理类,以及Sprite类
这篇文章会有许多代码需要理解,这节课的部分代码是可以部分复制的,我推荐大家还是按顺序敲一次增加印象,当然了现在所有的代码都是为了之后开发那个史莱姆游戏做准备,此章的主要内容是:把纹理类封装起来实现一些其他功能,包括切割等,OK不多说我们正式开始此篇文章的内容
图集,以及2D游戏的精灵:
图集:在游戏开发中通常会遇到以下几种情况:美术为了节约存储,优化结构通常会通过将所有素材都集中地放在一张图片上,那么我们该怎么处理这个图片呢,在知名游戏引擎Unity中他的精灵类素材可以通过切割,分割得到,这个时候我们就需要封装一个图集类,通过配置文件切割出重要的内容了。
2D精灵 :首先精灵就是渲染在窗口上地结果,我们通常通过切割得到的图片来充当精灵,但是我们为了更加方便渲染都会在Sprite类中封装许多功能,包括Unity中里面封装的功能都是很完善很强大的功能,毕竟是称霸一方的超级游戏引擎
OK,介绍完两个东西我们试一下将两个东西全部实现出来,分别是图集类,和精灵类
图集类创建完整流程:
第一步:创建TextureRegion类
为什么创建这个类呢?很简单因为原先MonoGame封装的Texture2D的类功能不能满足我们的需求,我们需要写出一些重载的方法增加渲染的方式,以及得到图集类切割得到的材质,OK我们正式开始
分为以下三个大步、
- 创建文件夹:在项目根目录中创建Graphics文件夹
- 创建cs文件:在Graphics文件夹中创建TextureRegion.cs类
- 编写TextureRegion类
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace SlimeGame.Graphics;
public class TextureRegion
{
}
以上声明了纹理渲染类以及包含了必要的库,接下来书写必要的TextureRegion属性
/// <summary>
/// 取得所需的纹理文件
/// </summary>
public Texture2D texture { get; set; }
/// <summary>
/// 取得切割的长方形
/// </summary>
public Rectangle SourceRectangle { get; set; }
/// <summary>
/// 切割宽度
/// </summary>
public int Width => SourceRectangle.Width;
/// <summary>
/// 切割高度
/// </summary>
public int Height => SourceRectangle.Height;
/// <summary>
/// 获取该纹理区域的顶部标准化坐标.
/// </summary>
public float TopTextureCoordinate => SourceRectangle.Top / (float)texture.Height;
/// <summary>
/// 获取该纹理区域的底部标准化坐标.
/// </summary>
public float BottomTextureCoordinate => SourceRectangle.Bottom / (float)texture.Height;
/// <summary>
/// 获取该纹理区域的左侧标准化坐标.
/// </summary>
public float LeftTextureCoordinate => SourceRectangle.Left / (float)texture.Width;
/// <summary>
/// 获取该纹理区域的右侧标准化坐标.
/// </summary>
public float RightTextureCoordinate => SourceRectangle.Right / (float)texture.Width;
接下来书写构造函数
/// <summary>
/// 无参构造
/// </summary>
public TextureRegion() { }
/// <summary>
/// 有参构造
/// </summary>
/// <param name="texture">所需纹理</param>
/// <param name="x">矩形位置的X轴坐标</param>
/// <param name="y">矩形位置的Y轴坐标</param>
/// <param name="width">矩形切割的宽度</param>
/// <param name="height">矩形切割的高度</param>
public TextureRegion(Texture2D texture, int x, int y, int width, int height)
{
this.texture = texture;
SourceRectangle = new Rectangle(x, y, width, height);
}
接下来写出,渲染函数的重载方法,能够实现切割后的图片的渲染从简到繁都有重载
/// <summary>
/// 绘制函数重写,极简版本
/// </summary>
/// <param name="spriteBatch">绘制组件</param>
/// <param name="position">位置</param>
/// <param name="color">颜色</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color)
{
Draw(spriteBatch, position, color, 0.0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0.0f);
}
/// <summary>
/// 绘制函数的重写简单版本
/// </summary>
/// <param name="spriteBatch">绘制函数所需组件</param>
/// <param name="position">位置</param>
/// <param name="color">眼色</param>
/// <param name="rotation">旋转角度</param>
/// <param name="origin">中心偏移量</param>
/// <param name="scale">缩放比例</param>
/// <param name="effects">翻转效果</param>
/// <param name="layerDepth">深度效果</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
{
Draw(
spriteBatch,
position,
color,
rotation,
origin,
new Vector2(scale, scale),
effects,
layerDepth
);
}
/// <summary>
/// 绘制函数:所有详细参数
/// </summary>
/// <param name="spriteBatch">所需绘制精灵组件</param>
/// <param name="position">绘制位置</param>
/// <param name="color">颜色</param>
/// <param name="rotation">旋转角度</param>
/// <param name="origin">精灵中心偏移量</param>
/// <param name="scale">缩放比例</param>
/// <param name="effects">翻转效果</param>
/// <param name="layerDepth">图层深度</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
spriteBatch.Draw(
texture,
position,
SourceRectangle,
color,
rotation,
origin,
scale,
effects,
layerDepth
);
}
自此所有的Texture2D的代码就全部写完了
我们下面给出完整的代码:
完整代码:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace SlimeGame.Graphics;
/// <summary>
/// 表示纹理中的矩形区域.
/// </summary>
public class TextureRegion
{
/// <summary>
/// 取得所需的纹理文件
/// </summary>
public Texture2D texture { get; set; }
/// <summary>
/// 取得切割的长方形
/// </summary>
public Rectangle SourceRectangle { get; set; }
/// <summary>
/// 切割宽度
/// </summary>
public int Width => SourceRectangle.Width;
/// <summary>
/// 切割高度
/// </summary>
public int Height => SourceRectangle.Height;
/// <summary>
/// 获取该纹理区域的顶部标准化坐标.
/// </summary>
public float TopTextureCoordinate => SourceRectangle.Top / (float)texture.Height;
/// <summary>
/// 获取该纹理区域的底部标准化坐标.
/// </summary>
public float BottomTextureCoordinate => SourceRectangle.Bottom / (float)texture.Height;
/// <summary>
/// 获取该纹理区域的左侧标准化坐标.
/// </summary>
public float LeftTextureCoordinate => SourceRectangle.Left / (float)texture.Width;
/// <summary>
/// 获取该纹理区域的右侧标准化坐标.
/// </summary>
public float RightTextureCoordinate => SourceRectangle.Right / (float)texture.Width;
/// <summary>
/// 无参构造
/// </summary>
public TextureRegion() { }
/// <summary>
/// 有参构造
/// </summary>
/// <param name="texture">所需纹理</param>
/// <param name="x">矩形位置的X轴坐标</param>
/// <param name="y">矩形位置的Y轴坐标</param>
/// <param name="width">矩形切割的宽度</param>
/// <param name="height">矩形切割的高度</param>
public TextureRegion(Texture2D texture, int x, int y, int width, int height)
{
this.texture = texture;
SourceRectangle = new Rectangle(x, y, width, height);
}
/// <summary>
/// 绘制函数重写,极简版本
/// </summary>
/// <param name="spriteBatch">绘制组件</param>
/// <param name="position">位置</param>
/// <param name="color">颜色</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color)
{
Draw(spriteBatch, position, color, 0.0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0.0f);
}
/// <summary>
/// 绘制函数的重写简单版本
/// </summary>
/// <param name="spriteBatch">绘制函数所需组件</param>
/// <param name="position">位置</param>
/// <param name="color">眼色</param>
/// <param name="rotation">旋转角度</param>
/// <param name="origin">中心偏移量</param>
/// <param name="scale">缩放比例</param>
/// <param name="effects">翻转效果</param>
/// <param name="layerDepth">深度效果</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
{
Draw(
spriteBatch,
position,
color,
rotation,
origin,
new Vector2(scale, scale),
effects,
layerDepth
);
}
/// <summary>
/// 绘制函数:所有详细参数
/// </summary>
/// <param name="spriteBatch">所需绘制精灵组件</param>
/// <param name="position">绘制位置</param>
/// <param name="color">颜色</param>
/// <param name="rotation">旋转角度</param>
/// <param name="origin">精灵中心偏移量</param>
/// <param name="scale">缩放比例</param>
/// <param name="effects">翻转效果</param>
/// <param name="layerDepth">图层深度</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
spriteBatch.Draw(
texture,
position,
SourceRectangle,
color,
rotation,
origin,
scale,
effects,
layerDepth
);
}
}
第二步:创建TextureAtlas 类
OK,终于到重头戏了,这个是这篇文章最主要的功能代码实现切割代码,和返回切割玩的纹理
- 创建cs文件:在Graphics文件夹中创建TextureRegion.cs类
- 编写TextureRegion类
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace SlimeGame.Graphics;
public class TextureAtlas
{
}
包含必要的库,创建图集类
/// <summary>
/// 存储每个纹理的字典
/// </summary>
private Dictionary<string, TextureRegion> Regions;
/// <summary>
/// 所需总体的纹理图片
/// </summary>
public Texture2D TotalTexture { get; set; }
/// <summary>
/// 无参构造
/// </summary>
public TextureAtlas()
{
Regions = new Dictionary<string, TextureRegion>();
}
/// <summary>
/// 有参构造
/// </summary>
/// <param name="texture">所需总体纹理</param>
public TextureAtlas(Texture2D texture)
{
TotalTexture = texture;
Regions = new Dictionary<string, TextureRegion>();
}
构造函数
/// <summary>
/// 在图集里增加纹理
/// </summary>
/// <param name="name">纹理对应名称/键</param>
/// <param name="x">纹理切割X坐标</param>
/// <param name="y">纹理切割Y坐标</param>
/// <param name="width">纹理切割宽度</param>
/// <param name="height">纹理切割高度</param>
public void AddRegion(string name, int x, int y, int width, int height)
{
TextureRegion region = new TextureRegion(TotalTexture, x, y, width, height);
Regions.Add(name, region);
}
/// <summary>
/// 从字典中查询纹理
/// </summary>
/// <param name="name">对应字典名字/键</param>
/// <returns>纹理</returns>
public TextureRegion GetRegion(string name)
{
return Regions[name];
}
/// <summary>
/// 从字典中移除纹理
/// </summary>
/// <param name="name">对应字典名字/键</param>
/// <returns>是否删除</returns>
public bool RemoveRegion(string name)
{
return Regions.Remove(name);
}
/// <summary>
/// 清空此字典
/// </summary>
public void RegionsClear()
{
Regions.Clear();
}
/// <summary>
/// 从文件中加载纹理
/// </summary>
/// <param name="content">文件资源管理</param>
/// <param name="fileName">文件名称</param>
/// <returns></returns>
public static TextureAtlas FromFile(ContentManager content, string fileName)
{
TextureAtlas atlas = new TextureAtlas();
// 合并文件名成完整项目路径
string filePath = Path.Combine(content.RootDirectory, fileName);
//文件流式存储
using (Stream stream = TitleContainer.OpenStream(filePath))
{
// Xml读取器的获得
using (XmlReader reader = XmlReader.Create(stream))
{
// 读XMl的文件内容
XDocument doc = XDocument.Load(reader);
XElement root = doc.Root;
// <Texture> 该元素包含要加载的 Texture2D 的内容路径.
// 因此,我们将检索该值,然后使用内容管理器加载纹理.
string texturePath = root.Element("Texture").Value;
atlas.TotalTexture = content.Load<Texture2D>(texturePath);
// <Regions> 该元素包含单独的<Region>元素,每个元素描述
// 图集中的其他纹理区域.
//
// 例子:
// <Regions>
// <Region name="spriteOne" x="0" y="0" width="32" height="32" />
// <Region name="spriteTwo" x="32" y="0" width="32" height="32" />
// </Regions>
//
// 因此,我们检索所有<Region>元素,然后遍历每个元素,从中生成一个新的 TextureRegion 实例,并将其添加到此图集.
var regions = root.Element("Regions")?.Elements("Region");
if (regions != null)
{
foreach (var region in regions)
{
string name = region.Attribute("name")?.Value;
int x = int.Parse(region.Attribute("x")?.Value ?? "0");
int y = int.Parse(region.Attribute("y")?.Value ?? "0");
int width = int.Parse(region.Attribute("width")?.Value ?? "0");
int height = int.Parse(region.Attribute("height")?.Value ?? "0");
if (!string.IsNullOrEmpty(name))
{
atlas.AddRegion(name, x, y, width, height);
}
}
}
return atlas;
}
}
}
必要方法,OK我们atlas的代码就到这了,接下来我们声明以下完整代码:
完整代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace SlimeGame.Graphics;
public class TextureAtlas
{
/// <summary>
/// 存储每个纹理的字典
/// </summary>
private Dictionary<string, TextureRegion> Regions;
/// <summary>
/// 所需总体的纹理图片
/// </summary>
public Texture2D TotalTexture { get; set; }
/// <summary>
/// 无参构造
/// </summary>
public TextureAtlas()
{
Regions = new Dictionary<string, TextureRegion>();
}
/// <summary>
/// 有参构造
/// </summary>
/// <param name="texture">所需总体纹理</param>
public TextureAtlas(Texture2D texture)
{
TotalTexture = texture;
Regions = new Dictionary<string, TextureRegion>();
}
/// <summary>
/// 在图集里增加纹理
/// </summary>
/// <param name="name">纹理对应名称/键</param>
/// <param name="x">纹理切割X坐标</param>
/// <param name="y">纹理切割Y坐标</param>
/// <param name="width">纹理切割宽度</param>
/// <param name="height">纹理切割高度</param>
public void AddRegion(string name, int x, int y, int width, int height)
{
TextureRegion region = new TextureRegion(TotalTexture, x, y, width, height);
Regions.Add(name, region);
}
/// <summary>
/// 从字典中查询纹理
/// </summary>
/// <param name="name">对应字典名字/键</param>
/// <returns>纹理</returns>
public TextureRegion GetRegion(string name)
{
return Regions[name];
}
/// <summary>
/// 从字典中移除纹理
/// </summary>
/// <param name="name">对应字典名字/键</param>
/// <returns>是否删除</returns>
public bool RemoveRegion(string name)
{
return Regions.Remove(name);
}
/// <summary>
/// 清空此字典
/// </summary>
public void RegionsClear()
{
Regions.Clear();
}
/// <summary>
/// 从文件中加载纹理
/// </summary>
/// <param name="content">文件资源管理</param>
/// <param name="fileName">文件名称</param>
/// <returns></returns>
public static TextureAtlas FromFile(ContentManager content, string fileName)
{
TextureAtlas atlas = new TextureAtlas();
// 合并文件名成完整项目路径
string filePath = Path.Combine(content.RootDirectory, fileName);
//文件流式存储
using (Stream stream = TitleContainer.OpenStream(filePath))
{
// Xml读取器的获得
using (XmlReader reader = XmlReader.Create(stream))
{
// 读XMl的文件内容
XDocument doc = XDocument.Load(reader);
XElement root = doc.Root;
// <Texture> 该元素包含要加载的 Texture2D 的内容路径.
// 因此,我们将检索该值,然后使用内容管理器加载纹理.
string texturePath = root.Element("Texture").Value;
atlas.TotalTexture = content.Load<Texture2D>(texturePath);
// <Regions> 该元素包含单独的<Region>元素,每个元素描述
// 图集中的其他纹理区域.
//
// 例子:
// <Regions>
// <Region name="spriteOne" x="0" y="0" width="32" height="32" />
// <Region name="spriteTwo" x="32" y="0" width="32" height="32" />
// </Regions>
//
// 因此,我们检索所有<Region>元素,然后遍历每个元素,从中生成一个新的 TextureRegion 实例,并将其添加到此图集.
var regions = root.Element("Regions")?.Elements("Region");
if (regions != null)
{
foreach (var region in regions)
{
string name = region.Attribute("name")?.Value;
int x = int.Parse(region.Attribute("x")?.Value ?? "0");
int y = int.Parse(region.Attribute("y")?.Value ?? "0");
int width = int.Parse(region.Attribute("width")?.Value ?? "0");
int height = int.Parse(region.Attribute("height")?.Value ?? "0");
if (!string.IsNullOrEmpty(name))
{
atlas.AddRegion(name, x, y, width, height);
}
}
}
return atlas;
}
}
}
}
第三步:创建Sprite类:
OK,Sprite类是今天最后一步,渲染出来的关键代码
- 创建cs文件:在Graphics文件夹中创建Sprite.cs类
- 编写Sprite类
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace SlimeGame.Graphics;
/// <summary>
/// 精灵类,用于渲染2D精灵
/// </summary>
public class Sprite {}
包含必要库创建必须代码
/// <summary>
/// 该精灵类纹理
/// </summary>
public TextureRegion Region { get; set; }
/// <summary>
/// 颜色系以及透明度
/// </summary>
public Color Color { get; set; } = Color.White;
/// <summary>
/// 旋转角度
/// </summary>
public float Rotation { get; set; } = 0.0f;
/// <summary>
/// 缩放比例
/// </summary>
public Vector2 Scale { get; set; } = Vector2.One;
/// <summary>
/// 中心偏移量
/// </summary>
public Vector2 Origin { get; set; } = Vector2.Zero;
/// <summary>
/// 是否翻转
/// </summary>
public SpriteEffects Effects { get; set; } = SpriteEffects.None;
/// <summary>
/// 图层深度
/// </summary>
public float LayerDepth { get; set; } = 0.0f;
/// <summary>
/// 宽度
/// </summary>
public float Width => Region.Width * Scale.X;
/// <summary>
/// 高度
/// </summary>
public float Height => Region.Height * Scale.Y;
Sprite类的必要属性
/// <summary>
/// 无参构造
/// </summary>
public Sprite() { }
/// <summary>
/// 有参构造
/// </summary>
/// <param name="region">材质</param>
public Sprite(TextureRegion region)
{
Region = region;
}
构造函数
/// <summary>
/// 使得Origin为材质的中心
/// </summary>
public void CenterOrigin()
{
Origin = new Vector2(Region.Width, Region.Height) * 0.5f;
}
/// <summary>
/// 渲染函数,在窗口中绘制函数
/// </summary>
/// <param name="spriteBatch">精灵渲染组件</param>
/// <param name="position">渲染位置</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position)
{
Region.Draw(spriteBatch, position, Color, Rotation, Origin, Scale, Effects, LayerDepth);
}
功能函数 OK,Sprite类也编写完成了,我们接下来声明以下完整代码
完整代码
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace SlimeGame.Graphics;
/// <summary>
/// 精灵类,用于渲染2D精灵
/// </summary>
public class Sprite
{
/// <summary>
/// 该精灵类纹理
/// </summary>
public TextureRegion Region { get; set; }
/// <summary>
/// 颜色系以及透明度
/// </summary>
public Color Color { get; set; } = Color.White;
/// <summary>
/// 旋转角度
/// </summary>
public float Rotation { get; set; } = 0.0f;
/// <summary>
/// 缩放比例
/// </summary>
public Vector2 Scale { get; set; } = Vector2.One;
/// <summary>
/// 中心偏移量
/// </summary>
public Vector2 Origin { get; set; } = Vector2.Zero;
/// <summary>
/// 是否翻转
/// </summary>
public SpriteEffects Effects { get; set; } = SpriteEffects.None;
/// <summary>
/// 图层深度
/// </summary>
public float LayerDepth { get; set; } = 0.0f;
/// <summary>
/// 宽度
/// </summary>
public float Width => Region.Width * Scale.X;
/// <summary>
/// 高度
/// </summary>
public float Height => Region.Height * Scale.Y;
/// <summary>
/// 无参构造
/// </summary>
public Sprite() { }
/// <summary>
/// 有参构造
/// </summary>
/// <param name="region">材质</param>
public Sprite(TextureRegion region)
{
Region = region;
}
/// <summary>
/// 使得Origin为材质的中心
/// </summary>
public void CenterOrigin()
{
Origin = new Vector2(Region.Width, Region.Height) * 0.5f;
}
/// <summary>
/// 渲染函数,在窗口中绘制函数
/// </summary>
/// <param name="spriteBatch">精灵渲染组件</param>
/// <param name="position">渲染位置</param>
public void Draw(SpriteBatch spriteBatch, Vector2 position)
{
Region.Draw(spriteBatch, position, Color, Rotation, Origin, Scale, Effects, LayerDepth);
}
}
使用图集类,精灵类
到了这一步,我们就已经把所有代码全部创建好了,代码量很大,今天大家得多花一些时间来学习,我写的注释都已经标好所有函数,成员的功能了,大家记得要注意看注释,接下来我会教会大家如何使用
主要分为下面几步
- 创建文件夹
- 创建xml配置文件
- 修改配置文件属性
- 编写xml
- 编写MainGame代码
得到的效果应该是如上面的效果:
第一步:打开MonoGame内容管道
第二步:创建文件夹configs
第三步:创建新的item并确定为xml文件且取名为atlas_slice.xml(当然这个名字随便取自己记得就好)
第四步:修改xml构建方式改为Copy,当你点击xml文件后看Properties方框的时候就会发现BuildAction为Build,将他改为Copy
第五步:编写代码
此处我们需要打开VSCode进行编辑代码为什么?很简单因为MonoGame的内容管道并不支持直接编写,我们需要在Content/configs文件夹中找到文件并开始编写,OK我们开始直接编写,编写方法:我在编写Atlas类的时候注释已经明确说明了编写方法,不知道我接下来的xml配置文件啥意思的回去看看
完整代码:(直接覆盖原本自动生成的代码)
<?xml version="1.0" encoding="utf-8"?>
<TextureAtlas>
<Texture>images/atlas</Texture>
<Regions>
<Region name="slime-1" x="340" y="0" width="20" height="20" />
<Region name="slime-2" x="340" y="20" width="20" height="20" />
<Region name="bat-1" x="340" y="40" width="20" height="20" />
<Region name="bat-2" x="340" y="60" width="20" height="20" />
<Region name="bat-3" x="360" y="0" width="20" height="20" />
<Region name="unfocused-button" x="259" y="80" width="65" height="14" />
<Region name="focused-button-1" x="259" y="94" width="65" height="14" />
<Region name="focused-button-2" x="259" y="109" width="65" height="14" />
<Region name="panel-background" x="324" y="97" width="15" height="15" />
<Region name="slider-off-background" x="341" y="96" width="11" height="10" />
<Region name="slider-middle-background" x="345" y="81" width="3" height="3" />
<Region name="slider-max-background" x="354" y="96" width="11" height="10" />
</Regions>
</TextureAtlas>
这里有一点需要注意一下就是在代码第3行中的文件路径根据你前两章的时候定义的为准,不要以我的为准
OK 我们最后修改一下MainGame的代码,如果你前面都看懂了,那么MainGame部分的代码就一定看得懂我们直接上代码
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SlimeGame.Graphics;
using SlimeGameLibrary;
namespace SlimeGame;
public class GameMain : Core
{
// 声明Sprite类
private Sprite bat;
private Sprite slime;
public GameMain() : base("SlimeGame", 1280, 720, false)
{
}
protected override void Initialize()
{
// TODO: 增加你的初始化逻辑
base.Initialize();
}
protected override void LoadContent()
{
// 加载图集类,此处以自己的路径为准
TextureAtlas atlas = TextureAtlas.FromFile(Content, "configs/atlas_slice.xml");
// 此处的名称以自己xml文件中的名称为准
slime = atlas.CreateSprite("slime-1");
slime.Scale = new Vector2(4.0f, 4.0f);
// 此处的名称以自己xml文件中的名称为准
bat = atlas.CreateSprite("bat-1");
bat.Scale = new Vector2(4.0f, 4.0f);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit(); // 退出游戏:按下Esc键或是手柄上的一个啥键
// TODO: 在此处增加你的游戏主循环逻辑
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// 像素化渲染
SpriteBatch.Begin(samplerState: SamplerState.PointClamp);
// Sprite的渲染方式
slime.Draw(SpriteBatch, Vector2.One);
bat.Draw(SpriteBatch, new Vector2(slime.Width + 10, 0));
SpriteBatch.End();
base.Draw(gameTime);
}
}
OK。接下来的我们直接dotnet run 运行一下试试看,大家记得好好加油运行结果我再放一次吧!
结语
今天的文章就到此结束了,我又想要搞一个新项目了,我这边想开一个Unity类银河恶魔城游戏开发的教程,但是手头还有三四个项目还没搞完,又要考驾照,早上起来又要写文章写个三四个小时,这个教程我项目调Bug调了好久,才开始写,看一下吧,要是时间够的话我会在B站录视频,这个银河恶魔城项目主要是教大家编程模式的:主要是一些常用单例模式,有限状态机,行为树等,跑题了,大家今天的代码好好看看,就算复制也好好看看这些注释,MonoGame官方写的就是有东西
好现在我照例问大家几个问题: