小游戏和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 here
        sf::Text text;
        text.setFont(font);
        text.setString("Hello, World");
        text.setCharacterSize(42); // in pixels
        text.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 here
        if (0)
        {
            window.clear();
            sf::Text text;
            text.setFont(font);
            text.setString("Hello, World");
            text.setCharacterSize(42); // in pixels
            text.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] 范围内的随机数, 间距是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);
            }

            // 画线, 擦掉一个像素行
            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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OCP使用CLI创建和构建应用

文章目录 环境登录创建project赋予查看权限部署第一个image创建route检查pod扩展应用 部署一个Python应用连接数据库创建secret加载数据并显示国家公园地图 清理参考 环境 RHEL 9.3Red Hat OpenShift Local 2.32 登录 通过 crc console --credentials 可以查看登录信息&…

动态内存管理(下)

1.常见的动态内存的错误 我们在学习动态内存的时候&#xff0c;常出现的一些错误我们来看一下。 1.对NULL指针的解引用操作 例如我们在使用malloc或者calloc开辟动态空间的时候&#xff0c;有时候没有判断是否开辟成功而直接对齐的返回指针进行解引用&#xff0c;此时如果开…

[论文总结] 深度学习在农业领域应用论文笔记12

文章目录 1. 3D-ZeF: A 3D Zebrafish Tracking Benchmark Dataset (CVPR, 2020)摘要背景相关研究所提出的数据集方法和结果个人总结 2. Automated flower classification over a large number of classes (Computer Vision, Graphics & Image Processing, 2008)摘要背景分割…

基于图像掩膜和深度学习的花生豆分拣(附源码)

目录 项目介绍 图像分类网络构建 处理花生豆图片完成预测 项目介绍 这是一个使用图像掩膜技术和深度学习技术实现的一个花生豆分拣系统 我们有大量的花生豆图片&#xff0c;并以及打好了标签&#xff0c;可以看一下目录结构和几张具体的图片 同时我们也有几张大的图片&…

Java强训day16(选择题编程题)

选择题 编程题 题目1 import java.util.Scanner;public class Main { public static boolean res(int m) {int sum 0;for(int i1;i<m;i) {if(i!m && m%i 0) {sumi;}}if(sum m)return true;elsereturn false;}public static void main(String[] args) {Scanne…

js手写Promise(上)

目录 构造函数resolve与reject状态改变状态改变后就无法再次改变 代码优化回调函数中抛出错误 thenonFulfilled和onRejected的调用时机异步then多个then 如果是不知道或者对Promise不熟悉的铁铁可以先看我这篇文章 Promise 构造函数 在最开始&#xff0c;我们先不去考虑Promi…

FFmpeg中的Color颜色参数解析、转码和HDR

前言 视频中帧的颜色信息非常重要&#xff0c;表示着编码时用到的标准&#xff0c;意味着解码时也要对应上&#xff0c;或者要使用正确的转换函数&#xff0c;否则就会带来色差问题。 关于FFmpeg中的颜色参数&#xff0c;有下边几个重要的结构体&#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…

巴尔加瓦算法图解:算法运用(上)

目录 树反向索引傅立叶变换 并行算法MapReduce函数 树 如果能将用户名插入到数组的正确位置就好了&#xff0c;这样就无需在插入后再排序。为此&#xff0c;有人设计了一种名为二叉查找树(binary search tree)的数据结构。 每个node的children 都不大于两个。对于其中的每个…

微信小程序上传代码教程

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 小程序上传代码到gogs上面来 整体架构流程 小程序也要远程连接仓库&#xff0c;实现代码上传 技术名词解释 微信开发者工具gogs 技术细节 连接gogs仓库地址 微信小程序需要head将本地代码和gogs代码同步 小结 …

java学习(多态)

一、多态 含义&#xff1a;方法或对象具有多种形态。是面向对象的第三大特征&#xff0c;多态是建立在封装和继承基础上的。 多态的具体体现&#xff1a; 1&#xff09;方法的多态 &#xff08;例如重写和重载&#xff09; 2&#xff09;对象的多态 多态注意事项&#xff1…

SpringCloud--Gateway解析

一、Gateway简介 Gateway是Spring Cloud官方推出的第二代微服务网关&#xff0c;它旨在提供统一的路由方式以及为微服务应用提供强大的负载均衡能力。与第一代Spring Cloud Netflix Zuul相比&#xff0c;Spring Cloud Gateway在性能、可扩展性、易用性等方面都有了显著的提升。…

python web 框架Django学习笔记

2018年5月 python web 框架Django学习笔记 Django 架站的16堂课 MVC架构设计师大部分框架或大型程序项目中一种软件工程的架构模式&#xff0c;把程序或者项目分为三个主要组成部分&#xff0c;Model数据模型、View视图、Controller控制器。 命令及设置相关 创建数据库及中间…

使用Launch4j将jar包转成.exe可执行文件

Launch4j官网:Launch4j - Cross-platform Java executable wrapper 然后点击上面按钮 随便写个文件名

分享66个相册特效,总有一款适合您

分享66个相册特效&#xff0c;总有一款适合您 66个相册特效下载链接&#xff1a;https://pan.baidu.com/s/1jqctaho4sL_iGSNExhWB6A?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不…

FastDFS安装并整合Openresty

FastDFS安装并整合Openresty 一、安装环境准备【CentOS7.9】二、FastDFS--tracker安装2.1.下载fastdfs2.2.FastDFS安装环境2.3.安装FastDFS依赖libevent库2.4.安装libfastcommon2.5.安装 libserverframe 网络框架2.6.tracker编译安装2.7.安装之后文件目录介绍2.8.错误处理2.9.配…

Android SystemConfig相关

SystemConfig在哪里初始化 它声明在PackageManagerService类的静态方法main()中。在该方法中间定义Injector类对象时&#xff0c;作为它的构造参数。它是调用的SystemConfig.getInstance()实现初始化&#xff0c;之后能通过Injector类对象的getSystemConfig()得到SystemConfig类…

Python贝尔多项式

文章目录 Bell数和Bell多项式第二类Bell多项式 Bell数和Bell多项式 Bell&#xff0c;即所有包含 n n n个对象的有限集合的子集数之和&#xff0c;可通过递推式进行定义 B n ∑ k 0 n − 1 ( n − 1 k ) B k , B 0 1 B_n\sum^{n-1}_{k0}\begin{pmatrix} n-1\\k \end{pmatrix…

Select 选择器 el-option 回显错误 value

离谱 回显的内容不是 label 而是 value 的值 返回官方看说明&#xff1a; v-model的值为当前被选中的el-option的 value 属性值 value / v-model 绑定值有3种类型 boolean / string / number 根据自身代码猜测是&#xff1a;tableData.bookId 与 item.id 类型不一致导致 &…

LabVIEW伺服阀性能参数测试

LabVIEW伺服阀性能参数测试 伺服阀作为电液伺服系统中的核心元件&#xff0c;其性能参数的准确测试对保证系统整体性能至关重要。开发了一种基于LabVIEW软件开发的伺服阀性能参数测试系统&#xff0c;提高测试的自动化程度和精确性&#xff0c;同时降低操作复杂度和成本。 传…