小游戏和GUI编程(3) | 基于 SFML 的字符阵

2024-02-10 18:28
文章标签 编程 字符 gui 小游戏 sfml

本文主要是介绍小游戏和GUI编程(3) | 基于 SFML 的字符阵,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

小游戏和GUI编程(3) | 基于 SFML 的字符阵

1. 简介

使用 EasyX 图形库时, 官方第一个例子是字符阵。 EasyX 不开源, 也不能跨平台, API 陈旧, API 是 C 而不是 C++。 现在使用 SFML 来实现字符阵, 克服 EasyX 的这些问题。

SFML 的 API 不如 EasyX 那么简单, 稍微复杂是因为功能更强大。 主要关注这么几个功能点: 使用 SFML 时怎样渲染文字? 怎样更新屏幕来营造字符阵的效果?

SFML 版本为 2.6.1, 原始的 EasyX 代码在这里 char-matrix, 对应的 raylib 代码在这里.

2. SFML 绘制文字

2.1 加载字体

需要先加载字体, SFML 不会扫描系统字体, 传入的是字体文件的路径。

使用 sf::Font 类, 主要用它的 loadFromFile() 函数。

    sf::Font font;const std::string asset_dir = "../Resources";if (!font.loadFromFile(asset_dir + "/SourceHanSansCN-Regular.otf")){printf("Error: font not found\n");return 1;}

2.2 绘制文字

使用 sf::Text 类, 它继承自 Drawable 类和 Transformable 类, 因此可以使用

class SFML_GRAPHICS_API Text : public Drawable, public Transformable
{
public:void setFont(const Font& font); // 设置字体void setString(const String& string); // 设置文本内容void setCharacterSize(unsigned int size); // 设置字符大小void setFillColor(const Color& color); // 设置字体颜色...
};class SFML_GRAPHICS_API Transformable
{
public:void setPosition(float x, float y); // 设置位置...
};

根据上述 api, 能够创建 “Hello World” 的文本, 设置它为绿色, 在屏幕中央显示:

在这里插入图片描述

关键代码

        window.clear();// draw the matrix heresf::Text text;text.setFont(font);text.setString("Hello, World");text.setCharacterSize(42); // in pixelstext.setFillColor(sf::Color::Green);sf::FloatRect bbox = text.getGlobalBounds();text.setPosition(win_width / 2 - bbox.width/2, win_height / 2 - bbox.height/2);window.draw(text);window.display();

3. 字符阵列

这一小节, 分析字符阵列的原理, 然后在前一节的基础绘制代码基础上进行实现。

3.1 在随机位置显示三个随机字母

int x = (rand() % 80) * 8;  // [0, 640] 范围内的随机数, 间距是8
int y = (rand() % 20) * 24; // [0, 480] 范围内的随机数, 间距是24
int c = (rand() % 26) + 'a'; // [97, 122] 范围内的随机数, 也就是随机小写字母
sf::Text text;
text.setFont(font);
text.setString(std::string(1, c));
text.setCharacterSize(26); // in pixels
text.setFillColor(sf::Color::Green);
text.setPosition(x, y);
window.draw(text);

3.2 擦除一个像素行

通过绘制一个和背景颜色一样(黑色)的矩形来做到。

// 画线, 擦掉一个像素行
sf::RectangleShape line(sf::Vector2f(win_width, 2));
line.setFillColor(sf::Color::Black);
line.setPosition(0, line_index);
line_index = (line_index + 1) % win_height; // line_index 初始值为0
window.draw(line);

其中 RectangleShape 类继承自 Shape 类, 因此能调用 setFillColor(), setPosition() 等函数:

class SFML_GRAPHICS_API RectangleShape : public Shape
{...
};

3.3 确保擦除效果

和常规不一样的地方是, 需要保持前一帧的绘制内容。

因此需要去掉 window.clear() 的调用。

3.4 完整代码和效果

#include <SFML/Graphics.hpp>int main()
{constexpr int win_width = 640;constexpr int win_height = 480;sf::VideoMode videomode(win_width, win_height);const std::string title = "Char Matrix SFML";sf::RenderWindow window(videomode, title);window.setFramerateLimit(60);sf::Font font;const std::string asset_dir = "../Resources";if (!font.loadFromFile(asset_dir + "/Courier-12.ttf")){printf("Error: font not found\n");return 1;}int line_index = 0;srand((unsigned)time(NULL));while (window.isOpen()){sf::Event event;while (window.pollEvent(event)){if (event.type == sf::Event::Closed) { window.close(); }}// draw the matrix hereif (0){window.clear();sf::Text text;text.setFont(font);text.setString("Hello, World");text.setCharacterSize(42); // in pixelstext.setFillColor(sf::Color::Green);sf::FloatRect bbox = text.getGlobalBounds();text.setPosition(win_width / 2 - bbox.width/2, win_height / 2 - bbox.height/2);window.draw(text);}if (1){ for (int i = 0; i < 3; i++){int x = (rand() % 80) * 8;  // [0, 640] 范围内的随机数, 间距是8int y = (rand() % 20) * 24; // [0, 480] 范围内的随机数, 间距是24int c = (rand() % 26) + 'a'; // [97, 122] 范围内的随机数, 也就是随机小写字母sf::Text text;text.setFont(font);text.setString(std::string(1, c));text.setCharacterSize(26); // in pixelstext.setFillColor(sf::Color::Green);text.setPosition(x, y);window.draw(text);}// 画线, 擦掉一个像素行sf::RectangleShape line(sf::Vector2f(win_width, 2));line.setFillColor(sf::Color::Black);line.setPosition(0, line_index);line_index = (line_index + 1) % win_height;window.draw(line);}window.display();}return 0;
}

在这里插入图片描述

4. 总结

通过查看 SFML 文档, 把字符阵的代码翻译到了基于 SFML 的实现, 关键 API 如下:

  • sf::Font::loadFromFile("xxx.ttf") 加载字体
  • sf::Text 类, 用于设置字体
  • sf::RectangleShape 类, 用于绘制单行矩形
  • 临时移除了 window.clear() 的调用

References

  • https://www.sfml-dev.org/tutorials/2.6/graphics-text.php
  • https://docs.easyx.cn/zh-cn/char-matrix
  • https://www.cnblogs.com/zjutzz/p/17067313.html

这篇关于小游戏和GUI编程(3) | 基于 SFML 的字符阵的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/697786

相关文章

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow