小游戏和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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2777670.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Java并发基础:LinkedTransferQueue全面解析!

内容概要 LinkedTransferQueue类实现了高效的线程间数据传递&#xff0c;支持等待匹配的生产者-消费者模式&#xff0c;基于链表的无界设计使其在高并发场景下表现卓越&#xff0c;且无需担心队列溢出&#xff0c;丰富的方法和良好的可扩展性满足了各种复杂应用场景的需求。 …

2024牛客寒假算法基础集训营3部分题解

智乃与瞩目狸猫、幸运水母、月宫龙虾 链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 Ubuntu是一个以桌面应用为主的Linux发行版操作系统&#xff0c;其名称来自非洲南部祖鲁语或豪萨语的"ubuntu"一词&#xff0c;意思是"人性…

无心剑汉英双语诗《龙年大吉》

七绝龙年大吉 Great Luck in the Dragon Year 龙腾五岳九州圆 年吼佳音万里传 大漠苍鹰华夏梦 吉人天相铸奇缘 Dragon flies over five peaks watching the divine land so great and round, New Year’s call sends joyous tidal waves far across the world’s bound. The…

[office] 怎么在Excel2003菜单栏自定义一个选项卡 #其他#微信#知识分享

怎么在Excel2003菜单栏自定义一个选项卡 怎么在Excel2003菜单栏自定义一个选项卡 ①启动Excel2003&#xff0c;单击菜单栏--工具--自定义。 ②在自定义界面&#xff0c;我们单击命令标签&#xff0c;在类别中选择新菜单&#xff0c;鼠标左键按住新菜单&#xff0c;拖放到菜单栏…

SpringCloud-高级篇(十九)

我们已经学过使用 SpringAMQP去收和发消息&#xff0c;但是发和收消息是只是MQ最基本的功能了&#xff0c;在收发消息的过程中&#xff0c;会有很多的问题需要去解决&#xff0c;下面需要学习rabbitMQ的高级特性去解决 死信交换机&#xff1a;这个可以帮助我们实现消息的延迟的…

Git远程仓库的使用(Gitee)及相关指令

目录 1 远程仓库的创建和配置 1.1 创建远程仓库 1.2 设置SSH公钥 2 指令 2.1 git remote add 远端名称(一般为origin) 仓库路径 2.2 git remote 2.3 git push [-f] [--set-upstream] [远端名称 [本地分支名][:远端分支名]] 2.3 git clone url 2.4 git fetch 2.5 git p…

HCIA--NAT实验

1. 划分网段&#xff0c;配置接口IP地址&#xff0c;内网启用OSPF协议&#xff0c;并配置一对一的NAT&#xff1a; AR1配置&#xff1a; [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 10.1.1.1 24 [Huawei-GigabitEthernet0/0/0]int g0/0/1 [Huawei-GigabitEther…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏16(附项目源码)

本节最终效果演示 【独游开发记录】一个人开发的&#xff0c;类森林&#xff0c;七日杀生存游戏 文章目录 本节最终效果演示系列目录前言泛型单例添加声音脚步声鸭子动物音效人物各种操作音效砍树音效 效果源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#x…

[经验] 喉咙沙哑的原因及应对方法是什么 #学习方法#其他#媒体

喉咙沙哑的原因及应对方法是什么 生活中&#xff0c;喉咙不舒服是很常见的情况&#xff0c;尤其是喉咙沙哑&#xff0c;让人感到特别难受&#xff0c;影响睡眠和生活质量。那么喉咙沙哑怎么办呢&#xff1f;接下来我会分享一些简单易行的方法&#xff0c;帮助你缓解这种不适感…

政安晨:示例演绎机器学习中(深度学习)神经网络的数学基础——快速理解核心概念(一){两篇文章讲清楚}

进入人工智能领域免不了与算法打交道&#xff0c;算法依托数学基础&#xff0c;很多小伙伴可能新生畏惧&#xff0c;不用怕&#xff0c;算法没那么难&#xff0c;也没那么玄乎&#xff0c;未来人工智能时代说不得人人都要了解算法、应用算法。 本文试图以一篇文章&#xff0c;…

《CSS 简易速速上手小册》第2章:CSS 布局与定位(2024 最新版)

文章目录 2.1 Flexbox&#xff1a;灵活的布局解决方案2.1.1 基础知识2.1.2 重点案例&#xff1a;创建一个响应式导航菜单2.1.3 拓展案例 1&#xff1a;卡片布局2.1.4 拓展案例 2&#xff1a;中心对齐的登录表单 2.2 Grid 布局&#xff1a;网格系统的魔力2.2.1 基础知识2.2.2 重…

数字孪生:构建未来智慧社区的关键技术

随着科技的快速发展&#xff0c;数字孪生技术作为构建未来智慧社区的关键技术&#xff0c;正逐渐受到广泛关注。数字孪生技术能够实现物理世界与数字世界的交互映射&#xff0c;为智慧社区的建设提供强有力的支持。本文将探讨数字孪生技术在构建未来智慧社区中的作用和意义&…

枚举(Java)

一、概念 枚举是一种特殊的类。 格式&#xff1a; 修饰符 enum 枚举类名{ 对象名称1&#xff0c;对象名称2&#xff0c;....; 其他成员... } 二、枚举类的特点 1.枚举类的第一行只能罗列一些名称&#xff0c;并且这些名称都是常量&#xff0c;每个常量记住一个枚举类对象…

vue3 之 Pinia数据持久化

持久化用户数据说明 1️⃣用户数据中有一个关键的数据叫做token&#xff08;用来标识当前用户是否登陆&#xff09;&#xff0c;而token持续一段时间才会过期 2️⃣Pinia的存储是基于内存&#xff0c;刷新就丢失&#xff0c;为了保持登陆状态就要做到刷新不丢失&#xff0c;需要…

【芯片设计- RTL 数字逻辑设计入门 番外篇 9 -- SOC 中PL端与PS端详细介绍】

文章目录 Programmable Logic and Processing SystemPL&#xff08;Programmable Logic&#xff09;特点PS和PL之间的协同设计和开发工具 Programmable Logic and Processing System 在系统级芯片&#xff08;SoC&#xff09;的上下文中&#xff0c;“PL” 通常指的是可编程逻…

Qt可视化大屏布局

科技大屏现在非常流行&#xff0c;这里分享一下某个项目的大屏布局&#xff08;忘了源码是哪个博主的了&#xff09; 展示 这个界面整体是垂直布局&#xff0c;分为两个部分&#xff0c;标题是一个部分&#xff0c;然后下面的整体是一个layout布局&#xff0c;为另外一部分。 l…

学习Android的第五天

目录 Android ConstraintLayout 约束布局 简介 ConstraintLayout 约束布局分类 1、相对定位 (Relative positioning) 2、边距 ( Margins ) 3、居中定位和偏向 ( Centering positioning and bias ) 4、环形定位 ( Circular positioning ) 5、对可见性的处理 ( Visibilit…

利用知识图谱构建医疗问答

1、准备数据集 数据集下载地址&#xff1a;https://github.com/wangle1218/QASystemOnMedicalKG/blob/master/data/medical.json 2、导入相关包 from py2neo import Graph,Node,Relationship # 在cmd中&#xff0c;输入neo4j.bat console并回车 import pandas as pd3、连接N…

Rust基础拾遗--核心功能

Rust基础拾遗 前言1.所有权与移动1.1 所有权 2.引用3.特型与泛型4.实用工具特型5.闭包 前言 通过Rust程序设计-第二版笔记的形式对Rust相关重点知识进行汇总&#xff0c;读者通读此系列文章就可以轻松的把该语言基础捡起来。 1.所有权与移动 谈及内存管理&#xff0c;我们希望…

力扣hot100 -- 双指针

目录 &#x1f382;移动零 &#x1f319;盛最多水的容器 &#x1f33c;三数之和 &#x1f33c;接雨水 前缀和 辅助数组 双指针 单调栈 &#x1f382;移动零 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 关于swap #include <iostream> #include <vec…