SFML入门(这个就够了)

大家好,今天是用法系列(话说这跟用法有关系吗......)的第n+m期,今天我们初步了解一下sfml

1.介绍

sfml全名叫Simple and Fast Multimedia Library,是一个基于c++开发的2维多媒体库,用于开发简易游戏或多媒体应用程序,创于2007年8月9日,基于sfml团队开发,可以播放音频,绘制图片或图形。

2.导入库

要使用的话,要导入sfml库,因为有些这个库是第三方的,编译器不会自带,只能自行安装下载。

这里可以根据【快速解决】在vs2022中配置SFML图形库_vcpkg安装sfml-CSDN博客 这个帖子下载

3.初步认识

0.使用命名空间

sf是sfml的主要命名空间(好吧其实这个库就一个)这个可写可不写,但要在一些代码前加上"sf::",容易把我们类似,所以必须要加(

using namespace sf;

1.导入窗口

如果你成功导入了,创建一个窗口,可以先创建一个RenderWindow类的对象,并输入一些参数给类中的构造函数,就像这样

RenderWindow window(
    VideoMode(800, 600), 
    "My first Window", 
    Style::Resize
);

这个构造函数的原型是这样的:

sf::RenderWindow(
    sf::VideoMode mode, const std::string& title, 
    sf::Uint32 style = sf::Style::Default, 
    const sf::ContextSettings& settings = sf::ContextSettings()
)

第一个是模式,一般输入VideoMode函数编辑长和宽,第二个是标题,第三个是窗口样式,当然他会默认帮你调好样式,有一些其他的样式,比如Style::None是无标题,Style::Titlebar是只显示标题栏,Style::Resize是只能调节窗口大小等

注:如果要起中文名的话请在字符串前加"L",比如"L'标题'"

2.设置帧率

每个游戏都有一个帧率,也就是fps,如果不设置,容易导致运行速度太快而导致cpu使用率太高而容易闪退,那我们就该设置帧率,要设置帧率的话,可以使用RenderWindow::setFramerateLimit函数,就像这样

setFramerateLimit(60);

当然,这里的帧率也可以调整成80,100,120甚至144

3.关闭窗口信息

当然,只创建窗口是不够的,我们还要让他一直保持开启状态,就像这样

while (window.isOpen()){
}

其中的isOpen函数是一个bool类型函数,如果打开,就会返回true,否则会返回false

4.关闭事件

当我们点击关闭按钮时,会发现不会响应,只是因为你没有编辑关闭事件,就像这样

while(window.isOpen()){
	Event event;
	while(window.pollEvent(event)){
	    if(event.type == Event::Closed){
		    window.close();
	}
}

其中我们发现我们在程序中创建了Event类的对象,这个类用于获取信息,而pollEvent函数用于处理信息,如果状态是点击关闭按钮,就关闭窗口

这样整个程序代码是这样的

#include <SFML/Graphics.hpp>


int main() {
	RenderWindow window(
        VideoMode(800, 600), 
        "My first Window", 
        Style::Resize
    );
	window.setFramerateLimit(60);
	while (window.isOpen()) {
		Event event;
		while (window.pollEvent(event)) {
			if (event.type == Event::Closed) {
				window.close();
			}
		}
	}
	return 0;
}

5.设置背景颜色

黑色的窗口似乎不太好看,我们可以把窗口的颜色调成白色,比如

Color backgroundColor = Color::White;

其他颜色也可以,比如淡绿色(144, 238, 144),就可以这么写

  Color backgroundColor(144, 238, 144);

只需在后面加上用于刷新的两行就行了

window.clear(backgroundColor); //刷新背景
window.display();

5.绘制图形

我们可以绘制一些简单的图形,比如长方形

 RectangleShape square(Vector2f(200.0f, 250.0f)); //长和宽
 square.setPosition(Vector2f(100.0f, 100.0f)); //x和y
 square.setFillColor(Color::White); //颜色

三角形

 sf::ConvexShape triangle; //创建多边形
 triangle.setPointCount(3); //设置顶点为三
 triangle.setPoint(0, sf::Vector2f(330.0f, 100.0f)); //顶点1坐标
 triangle.setPoint(1, sf::Vector2f(530.0f, 100.0f)); //顶点2坐标
 triangle.setPoint(2, sf::Vector2f(430.0f, 300.0f)); //顶点3坐标
 triangle.setFillColor(Color::White); //设置颜色

圆形

 sf::CircleShape circle(60.0f); //半径
 circle.setPosition(Vector2f(500.0f,200.0f)); //坐标
 circle.setFillColor(Color::White); //颜色

线段

sf::VertexArray line(sf::Lines, 2); //设置线段点为二
line[0].position = Vector2f(100.0f, 100.0f); //线段1坐标
line[0].color = Color::Black; //线段1颜色
line[1].position = Vector2f(300.0f, 300.0f); //线段2坐标
line[1].color = Color::Black; //线段1颜色

顺便提一嘴,这里的坐标是从右下角为(0,0)为中心的

还有文字

sf::Font font; //创建文字对象
std::string fontPath = "comici.TTF"; //导入字体
if (!font.loadFromFile(fontPath))  //如果加载失败,报错
{
    std::cerr << "加载失败" << std::endl;
    return -1;
}
//创建文本
sf::Text text("安全", font, 40);  //设置文本,字体,字号
text.setFillColor(sf::Color::Black);  //颜色
text.setPosition(300, 250);  //位置

音乐

sf::Music music; //创建音乐对象
if (!music.openFromFile("music.mp3")) //判断加载失败,报错
{
    std::cerr << "加载失败!" << std::endl
    return -1; 
}
music.play(); //播放
music.setVolume(50); //音量
music.setLoop(flase); //是否单曲循环

图片

 sf::Texture texture; //图片对象
 if (!texture.loadFromFile("image.jpeg")) // 判断加载失败,报错
 {
     std::cerr << "加载错误" << std::endl;
     return -1;
 }
 sf::Sprite sprite(texture); //创建精灵对象
 sprite.setPosition(Vector2f(0, -5)); //位置

字体,图片,音频都需要自行复制到程序目录下 

精灵用于绘制图片,最后这些都均可用draw函数绘制,例如刚才的sprite,绘制的方法就是

window.draw(sprite);

6.例子

其实还有一些图形,但太小众,所以不讲,总之我们结合这些,写一个例子

代码:

#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf; //使用sf命名空间

const int WinWidth = 900; //高
const int WinHeight = 566; //宽

int main() //主函数
{
    RenderWindow window(
        VideoMode(800, 600), //长和宽
        "My first Window", //窗口名
        Style::Resize //样式
    );
    window.setFramerateLimit(60); //设置帧
    sf::Texture texture; //创建图片
    sf::Font font; //创建字体
    Music music;
    music.setVolume(50); //音量
    music.setLoop(flase); //是否单曲循环
    if (!font.loadFromFile("HarmonyOS_Sans_SC_Bold.ttf")) { //如果加载字体失败,报错
        std::cerr << "error!" << std::endl;
        return -1;
    }
    
    if (!texture.loadFromFile("image.jpeg")){ //如果加载图片失败,报错
        std::cerr << "加载失败!" << std::endl; 
        return -1;
    }
    if(!music.openFromFile("music.mp3")){ //如果加载音乐失败,报错
        std::cerr << "加载失败!" << std::endl; 
        return -1;
    }
    sf::Sprite sprite(texture); //设置精灵,并继承图片
        sprite.setPosition(Vector2f(0, -5)); //设置位置
        Text text(L"原来你也玩原神?", font, 50); //设置文本,字体,大小
        text.setFillColor(Color::Black); //设置颜色
        text.setPosition(Vector2f(20, 20)); //设置文字位置
        while (window.isOpen()) //关闭判断
        {
            Event event;
            while (window.pollEvent(event))
            {
                if (event.type == Event::Closed)
                {
                    window.close();
                }
            }

            window.clear(Color::White); //清除,并设定背景为白
            window.draw(sprite); //绘画图片
            window.draw(text); //绘制文字
            music.play();
            window.display(); //刷新
        }
    system("pause"); //等待
}

运行结果:

 (逃到这里应该就没有原批了吧( )

7.图片功能

sfml不仅能绘制图片,还能缩大背景,比如缩大两倍,代码就是这样的

View view;
view.zoom(0.5);
window.setView(view);

也可以移动

View view;
view.move(100, 100);
window.setView(view);

设置窗口大小

window.setSize(sf::Vector2u(1000, 800));

8.其他

我们还发现,代码中有Vector2f和Vector2u字样,这两个类型,一个是保存浮点数的,一个是保存整数,一个常用于坐标或大小,而另一个是测量尺寸,此外还有Vector2i,Vector3i,Vector2f,这个暂且不讲

sfml还可用于3d,需要用到OpenGL,这个也不讲

4.网络

1.服务器

没想到吧,这个库还能用于做服务器,比如实现一个tcp服务器的代码就是这样的

#include <SFML/Network.hpp>
#include <iostream>

int main()
{
    sf::TcpListener listener; //创建监听器
    if (listener.listen(53000)!= sf::Socket::Done) //如果监听失败,抱错
    {
        std::cerr << "无法监听端口" << std::endl;
        return -1;
    }
    sf::TcpSocket socket; //创建客户端
    if (listener.accept(socket)!= sf::Socket::Done) //如果客户端连接失败,报错
    {
        std::cerr << "无法接受客户端连接" << std::endl;
        return -1;
    }
    char data[100]; //数据
    std::size_t received; //信息大小
    if (socket.receive(data, sizeof(data), received)!= sf::Socket::Done) //如果接受数据失败,报错
    {
        std::cerr << "无法接收数据" << std::endl;
        return -1;
    }
    data[received] = '\0'; //字符串处理
    std::cout << "收到客户端消息: " << data << std::endl; 
    const char response[] = "已收到你的消息"; 
    if (socket.send(response, sizeof(response))!= sf::Socket::Done) //发送信息失败,报错
    {
        std::cerr << "无法发送响应" << std::endl;
        return -1;
    }
    return 0;
}

2.蓝牙

它还可以连接手柄,比如

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "游戏手柄测试"); //创建窗口
    if (sf::Joystick::isConnected(0)) //如果第一个手柄(下标)链接
    {
        std::cout << "游戏手柄已连接" << std::endl; //输出连接信息
        while (window.isOpen()) //关闭判断
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    window.close();
            }
            if (sf::Joystick::isButtonPressed(0, 0)) //如果第一个手柄按下0按钮
            {
                std::cout << "手柄按钮0被按下" << std::endl; //输出信息
            }
            window.clear();
            window.display();
        }
    }
    else
    {
        std::cout << "未连接游戏手柄" << std::endl; //否则连接失败
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值