从零开发游戏需要学习的c#模块,第十九章(在游戏画面里显示文字 —— FontStashSharp)

本节课我们要学习的内容是

  1. 安装字体渲染库

  2. 加载系统字体文件

  3. 在游戏画面里直接显示分数、金币数等信息

第一步:安装 NuGet 包

  1. 在 Visual Studio 右侧"解决方案资源管理器"里,右键你的项目名(不是解决方案)

  2. 选择 "管理 NuGet 程序包"

  3. 点击 "浏览" 标签

  4. 搜索 FontStashSharp.MonoGame

  5. 找到后点击 安装

第二步:准备字体文件

  1. 打开 Windows 的文件资源管理器,地址栏输入 C:\Windows\Fonts,回车

  2. 找一个你喜欢的 .ttf 字体(比如 consola.ttfsimhei.ttf 黑体等)

  3. 复制这个文件

  4. 粘贴到你项目的 Content 文件夹里

  5. 在 VS 里,右键这个 .ttf 文件 → 属性

  6. "复制到输出目录" 改成 "如果较新则复制"

第三步:完整代码

Game1.cs 完整替换为:

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using System;

using System.Collections.Generic;

using System.IO;

using FontStashSharp;

namespace MY_FIRST_GAME

{

public class Game1 : Game

{

private GraphicsDeviceManager _graphics;

private SpriteBatch _spriteBatch;

// 玩家

private Texture2D playerTexture;

private Vector2 playerPosition;

private float playerSpeed = 200f;

// 金币

private Texture2D coinTexture;

private List<Vector2> coins;

private Random rng;

private int score;

// ★ 字体

private SpriteFontBase font;

public Game1()

{

_graphics = new GraphicsDeviceManager(this);

Content.RootDirectory = "Content";

IsMouseVisible = true;

}

protected override void Initialize()

{

_graphics.PreferredBackBufferWidth = 800;

_graphics.PreferredBackBufferHeight = 600;

_graphics.ApplyChanges();

playerPosition = new Vector2(400, 300);

rng = new Random();

coins = new List<Vector2>();

score = 0;

SpawnCoins(5);

base.Initialize();

}

protected override void LoadContent()

{

_spriteBatch = new SpriteBatch(GraphicsDevice);

// 加载玩家图片

using var stream = File.OpenRead("Content/player.png");

playerTexture = Texture2D.FromStream(GraphicsDevice, stream);

// 创建金币纹理

coinTexture = new Texture2D(GraphicsDevice, 32, 32);

Color\[\] data = new Color32 \* 32;

for (int i = 0; i < data.Length; i++)

datai = Color.Gold;

coinTexture.SetData(data);

// ★ 加载字体(直接用 .ttf 文件,不需要编译)

var fontSystem = new FontSystem();

fontSystem.AddFont(File.ReadAllBytes("Content/consola.ttf"));

font = fontSystem.GetFont(18);

}

private void SpawnCoins(int count)

{

for (int i = 0; i < count; i++)

{

float x = rng.Next(50, 750);

float y = rng.Next(50, 550);

coins.Add(new Vector2(x, y));

}

}

protected override void Update(GameTime gameTime)

{

KeyboardState keyboard = Keyboard.GetState();

float speed = playerSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

if (keyboard.IsKeyDown(Keys.W) || keyboard.IsKeyDown(Keys.Up))

playerPosition.Y -= speed;

if (keyboard.IsKeyDown(Keys.S) || keyboard.IsKeyDown(Keys.Down))

playerPosition.Y += speed;

if (keyboard.IsKeyDown(Keys.A) || keyboard.IsKeyDown(Keys.Left))

playerPosition.X -= speed;

if (keyboard.IsKeyDown(Keys.D) || keyboard.IsKeyDown(Keys.Right))

playerPosition.X += speed;

playerPosition.X = Math.Clamp(playerPosition.X, 32, 768);

playerPosition.Y = Math.Clamp(playerPosition.Y, 32, 568);

CheckCoinCollision();

if (coins.Count == 0)

SpawnCoins(5);

if (keyboard.IsKeyDown(Keys.Escape))

Exit();

base.Update(gameTime);

}

private void CheckCoinCollision()

{

Rectangle playerRect = new Rectangle(

(int)playerPosition.X - 32,

(int)playerPosition.Y - 32,

64, 64

);

for (int i = coins.Count - 1; i >= 0; i--)

{

Rectangle coinRect = new Rectangle((int)coinsi.X, (int)coinsi.Y, 32, 32);

if (playerRect.Intersects(coinRect))

{

coins.RemoveAt(i);

score += 10;

}

}

}

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue);

_spriteBatch.Begin();

// 画金币

foreach (Vector2 coinPos in coins)

{

_spriteBatch.Draw(coinTexture, coinPos, Color.White);

}

// 画玩家

_spriteBatch.Draw(

playerTexture,

playerPosition,

null,

Color.White,

0f,

new Vector2(playerTexture.Width / 2, playerTexture.Height / 2),

1f,

SpriteEffects.None,

0f

);

// ★ 画文字

_spriteBatch.DrawString(font, $"分数:{score}", new Vector2(10, 10), Color.White);

_spriteBatch.DrawString(font, $"金币:{coins.Count}", new Vector2(10, 35), Color.Gold);

_spriteBatch.DrawString(font, "WASD/方向键 移动 | ESC 退出", new Vector2(10, 570), Color.LightGray);

_spriteBatch.End();

base.Draw(gameTime);

}

}

}

本节课新内容

加载字体(FontStashSharp 方式):

cs 复制代码
var fontSystem = new FontSystem();
fontSystem.AddFont(File.ReadAllBytes("Content/consola.ttf"));
font = fontSystem.GetFont(18);
  • 只需要三行代码,直接读 .ttf 文件

  • 不需要 .spritefont 文件

  • 不需要 MGCB Editor

  • 字号 18 可以随便改

画文字

cs 复制代码
_spriteBatch.DrawString(font, "内容", new Vector2(X, Y), Color.White);

最后使用F5运行。

好了,这节课到此结束,我叫魔法阵维护师,关注我,下期更精彩

相关推荐
sensen_kiss28 分钟前
CPT304 SoftwareEngineeringII 软件工程 2 Pt.9 软件测试 (Software Testing)(下)
学习·软件工程
wu_ye_m36 分钟前
学习c语言第35天 函数声明和定义
c语言·开发语言·学习
njsgcs43 分钟前
c# solidworks 创建装配体工程图+bom
开发语言·c#·solidworks
清辞8531 小时前
Coze从入门到实战---第一、二章
大数据·人工智能·学习·语言模型
伊布拉西莫1 小时前
【流畅的Python】第20章:并发执行器 — 学习笔记
笔记·python·学习
njsgcs1 小时前
c# solidworks 工程图获得展开视图不在固定面螺纹特征的位置
开发语言·c#·solidworks
jinglong.zha2 小时前
LScript-从零基础到商业变现的AI自动化学习平台
运维·学习·自动化
闪闪发亮的小星星2 小时前
STK_00 学习方案路线
学习
一楼的猫3 小时前
茄子写作助手——品牌搜索突破9万后的技术型品牌认知与官网入口指南
人工智能·学习·机器学习·chatgpt·ai写作
AOwhisky3 小时前
学习自测与解析:MySQL第五、六、七期核心知识点详解
运维·数据库·笔记·学习·mysql·云计算