C++ 基于SDL库的 Visual Studio 2022 环境配置

news2024/12/28 13:28:43

系统:w10、编辑器:Visual Studio 2022、

下载地址

必要库:
SDL
https://github.com/libsdl-org/SDL
字体
https://github.com/libsdl-org/SDL_ttf
图片
https://github.com/libsdl-org/SDL_image
音频
https://github.com/libsdl-org/SDL_mixer
json
https://github.com/DaveGamble/cJSON
SDL的API说明
https://wiki.libsdl.org/SDL2/CategoryAPI
下载方式:
在这里插入图片描述

因为是vs,所以直接下载编译好的,注意选择合适的版本。
在这里插入图片描述

绘制图形(有问题,现在使用的:https://github.com/giroletm/SDL2_gfx/releases/tag/release-1.0.4 目前还不知道会不会出问题)
https://www.ferzkopp.net/wordpress/2016/01/02/sdl_gfx-sdl2_gfx/
在这里插入图片描述

开始配置

vs配置
创建空项目,创建main.cpp文件,设置Release、设置x64、
右键项目名,点击属性:C++ --> 代码生成 --> 运行库 --> 多线程/MT

在这里插入图片描述
将必要库下载后,我们只需要 lib、include(中的x64)、两个文件夹。(三大块:动态链接库.dll、库文件.lib、头文件.h).
VS添加库:右键选择项目的属性
1、C/C++ --> 常规 --> 附加包含目录,添加include路径
2、链接器 --> 常规 --> 附加库目录, 添加lib文件夹的路径
3、链接器 --> 输入 --> 附加依赖项,添加lib文件的路径
4、将.dll文件复制到项目根目录中

(1)添加时使用相对路径
在项目目录下新建了thirdparty的文件夹,放置所有库。

我把cjson其他文件删除了,只保留了cJSON.h、cJSON.c、两个文件
我新建了个include文件夹,将cJSON.h、放了进去,方便配置时格式统一。

其他差不多,只留include、lib、。
(2)cjson的添加
在VS中的源文件右键,–> 添加 --> 新建筛选器

C/C++ --> 常规 --> 附加包含目录,添加include路径
这里使用的相对路径
…\thirdparty\cJSON\include
…\thirdparty\SDL2_mixer\include
…\thirdparty\SDL2\include
…\thirdparty\SDL2_gfx\include
…\thirdparty\SDL2_image\include
…\thirdparty\SDL2_ttf\include

链接器 --> 常规 --> 附加库目录, 添加
这里使用的相对路径
…\thirdparty\SDL2\lib\x64
…\thirdparty\SDL2_gfx\lib\x64
…\thirdparty\SDL2_image\lib\x64
…\thirdparty\SDL2_ttf\lib\x64
…\thirdparty\SDL2_mixer\lib\x64

链接器 --> 输入 --> 附加依赖项,添加lib文件的路径
这里没有添加具体的路径,直接写lib的文件名即可。
SDL2.lib
SDL2main.lib
SDL2_image.lib
SDL2_mixer.lib
SDL2_ttf.lib
SDL2_gfx.lib

将.dll文件复制到项目根目录中
在这里插入图片描述

简单测试代码:

#define SDL_MAIN_HANDLED

#include <iostream>
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <SDL2_gfxPrimitives.h>


int main()
{
    std::cout << "Hello Demo" << std::endl;
    return 0;
}

请添加图片描述

功能测试代码

需要:图片jpg、mp3、字体ttf、csv文件、json文件、

#define SDL_MAIN_HANDLED

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

#include <cJSON.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <SDL2_gfxPrimitives.h>

void test_json()
{
    // json内容
    //{
    //    "name": "XiaoMing",
    //        "age" : 18,
    //        "pets" : ["dog", "cat", "bird"]
    //}

    std::ifstream file("test.json");
    if (!file.good())
    {
        std::cout << "无法打开文件" << std::endl;
        return;
    }

    // 创建
    std::stringstream str_stream;
    // 读取全部内容
    str_stream << file.rdbuf();
    // 关闭文件
    file.close();

    // 读取json文件的内容
    cJSON* json_root = cJSON_Parse(str_stream.str().c_str());

    cJSON* json_name = cJSON_GetObjectItem(json_root, "name");
    cJSON* json_age = cJSON_GetObjectItem(json_root, "age");
    cJSON* json_pets = cJSON_GetObjectItem(json_root, "pets");

    std::cout << json_name->string << ": " << json_name->valuestring << std::endl;
    std::cout << json_age->string << ": " << json_age->valueint << std::endl;

    std::cout << json_pets->string << ": " << std::endl;

    // 定义cjson指针
    cJSON* json_item = nullptr;
    // cJSON 的 for循环
    cJSON_ArrayForEach(json_item, json_pets)
    {
        std::cout << "\t" << json_item->valuestring << std::endl;
    }
}

void test_csv()
{
    // csv 内容
    //1, 2, 3
    //4, 5, 6
    //7, 8, 9

    std::ifstream file("test.csv");
    if (!file.good())
    {
        std::cout << "无法打开文件" << std::endl;
        return;
    }
    // 1行的文本内容
    std::string str_line;

    while (std::getline(file, str_line))
    {
        std::string str_grid;  // 分割后的

        std::stringstream str_stream(str_line);

        // 以逗号为分割,循环打印出来
        while (std::getline(str_stream, str_grid, ','))
        {
            std::cout << str_grid << " ";
        }

        std::cout << std::endl;
    }

    file.close();
}

int main()
{
    //std::cout << "Hello Demo" << std::endl;
    test_json();  // json 测试
    test_csv();   //  csv 测试

    // 初始化所有子系统
    SDL_Init(SDL_INIT_EVERYTHING);
    // 图像库初始化 jpg png
    IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
    // 音频库初始化 mp3
    Mix_Init(MIX_INIT_MP3);
    // 字体初始化
    TTF_Init();

    // 音频:采样率、解码的音频格式、声道数、音频缓冲区大小、
    Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);

    // 创建游戏窗口: u8标识后面就可以跟中文、位置居中、大小、显示、
    SDL_Window* Window = SDL_CreateWindow(u8"你好, 世界", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_SHOWN);

    // 渲染器GPU:窗口、自动选择索引、硬件加速
    SDL_Renderer* renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);

    // 加载图片
    SDL_Surface* suf_img = IMG_Load("avatar.jpg");
    // 内存传入到GPU
    SDL_Texture* tex_img = SDL_CreateTextureFromSurface(renderer, suf_img);

    // 加载字体对象:字体、字体大小
    TTF_Font* font = TTF_OpenFont("ipix.ttf", 32);
    // 字体颜色
    SDL_Color color = { 255, 255, 255, 255 };
    // 渲染字体内容:字体对象、内容、颜色、
    SDL_Surface* suf_text = TTF_RenderUTF8_Blended(font, u8"你好,世界", color);
    // 内存传入到GPU
    SDL_Texture* tex_text = SDL_CreateTextureFromSurface(renderer, suf_text);

    // 加载mp3
    Mix_Music* music = Mix_LoadMUS("music.mp3");
    // 淡入播放:文件对象、-1为循环播放、淡入效果维持时长、
    Mix_FadeInMusic(music, -1, 1500);

    int fps = 60;  // 固定60帧数 


    // 游戏主循环变量
    bool is_quit = false;
    SDL_Event event;  // 事件结构体对象
    SDL_Point pos_cursor = { 0, 0 };  // 记录鼠标位置
    SDL_Rect rect_img, rect_text;  // 描述一个矩形

    // 高精度SDL计时器
    // 当前计时
    Uint64 last_counter = SDL_GetPerformanceCounter();
    // 每秒跳几次
    Uint64 conter_freq = SDL_GetPerformanceFrequency();

    // 矩形的宽高是原图的宽高
    rect_img.w = suf_img->w;
    rect_img.h = suf_img->h;

    rect_text.w = suf_text->w;
    rect_text.h = suf_text->h;

    // 游戏主循环开始
    while (!is_quit) {
        // 拉取事件结构体对象 
        while (SDL_PollEvent(&event)) {   
            // 关闭
            if (event.type == SDL_QUIT) {
                is_quit = true;
            }
            // 检测到鼠标事件,更新鼠标位置
            if (event.type == SDL_MOUSEMOTION) {
                pos_cursor.x = event.motion.x;
                pos_cursor.y = event.motion.y;
            }
        }
        // 当前计数
        Uint64 current_counter = SDL_GetPerformanceCounter();
        // 当前计数与上次计数相减 除 每秒次数
        double delta = (double)(current_counter - last_counter) / conter_freq;
        // 更新计数
        last_counter = current_counter;
        // 转换毫秒后,若超出设定数
        if (delta * 1000 < 1000.0 / fps)
            // 舍弃
            SDL_Delay((Uint32)(1000.0 / fps - delta * 1000));

        // 处理数据
        // 将更新的坐标赋值给矩形
        rect_img.x = pos_cursor.x;   // 图片
        rect_img.y = pos_cursor.y;

        rect_text.x = pos_cursor.x;  // 字体
        rect_text.y = pos_cursor.y;


        // 渲染黑色背景
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        // 清屏
        SDL_RenderClear(renderer);
        
        // 渲染绘图: 渲染器、图片、原始图截取(当前为空)、贴到某处(自定义矩形xyhw)、
        SDL_RenderCopy(renderer, tex_img, nullptr, &rect_img);
        // 使用绘制库 绘制圆:半径50、透明度125、
        filledCircleRGBA(renderer, pos_cursor.x, pos_cursor.y, 50, 255, 0, 0, 125);
        // 绘制字体
        SDL_RenderCopy(renderer, tex_text, nullptr, &rect_text);


        // 更新
        SDL_RenderPresent(renderer);
    }

    
    return 0;
}




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

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

相关文章

连续点击三次用户

有用户点击日志记录表 t2_click_log&#xff0c;包含user_id(用户ID),click_time(点击时间)&#xff0c;请查询出连续点击三次的用户数&#xff0c; 连续点击三次&#xff1a;指点击记录中同一用户连续点击&#xff0c;中间无其他用户点击&#xff1b; CREATE TABLE t2_click…

两个div中间有缝隙

两个div中间有缝隙效果图&#xff1a; 这种是display:inline-block造成的 在父元素中加入font-size:0px;&#xff0c;再在相应的子div中加入font-size:12px;就可以了 调整后效果图&#xff1a;

Pandas和Seaborn数据可视化

Pandas数据可视化 学习目标 本章内容不需要理解和记忆&#xff0c;重在【查表】&#xff01; 知道数据可视化的重要性和必要性知道如何使用Matplotlib的常用图表API能够找到Seaborn的绘图API 1 Pandas数据可视化 一图胜千言&#xff0c;人是一个视觉敏感的动物&#xff0c;大…

数据库-分库分表

什么是分库分表 分库分表是一种数据库优化策略。 目的&#xff1a;为了解决由于单一的库表数据量过大而导致数据库性能降低的问题 分库&#xff1a;将原来独立的数据库拆分成若干数据库组成 分表&#xff1a;将原来的大表(存储近千万数据的表)拆分成若干个小表 什么时候考虑分…

Web 性能优化|了解 HTTP 协议后才能理解的预加载

作者&#xff1a;谦行 一、前言 在性能优化过程中&#xff0c;开发者通常会集中精力在以下几个方面&#xff1a;服务器响应时间&#xff08;RT&#xff09;优化、服务端渲染&#xff08;SSR&#xff09;与客户端渲染优化、以及静态资源体积的减少。然而&#xff0c;对于许多用…

C(十五)函数综合(一)--- 开公司吗?

在这篇文章中&#xff0c;杰哥将带大家 “开公司”。 主干内容部分&#xff08;你将收获&#xff09;&#xff1a;&#x1f449; 为什么要有函数&#xff1f;函数有哪些&#xff1f;怎么自定义函数以及获得函数的使用权&#xff1f;怎么对函数进行传参&#xff1f;函数中变量的…

[嵌入式Linux]—STM32MP1启动流程

STM32MP1启动流程 1.启动模式 STM32MP1等SOC支持从多种设备中启动&#xff0c;如EMMC、SD、NAND、NOR、USB、UART等。其中USB、UART是作为烧录进行启动的。 STM32MP1内部ROM中存储有一段出厂代码来进行判断从哪种设备中启动&#xff0c;上电后这段代码会被执行&#xff0c;这…

使用java函数逆序一个单链表

代码功能 定义了一个ListNode类&#xff0c;用于表示单链表的节点&#xff0c;每个节点包含一个整数值和一个指向下一个节点的引用。 在ReverseLinkedList类的main方法中&#xff0c;创建了一个包含从1到10的整数的单链表。 定义了一个printList方法&#xff0c;用于打印链表的…

基于JavaWeb开发的java springmvc+mybatis酒水商城管理系统设计和实现

基于JavaWeb开发的java springmvcmybatis酒水商城管理系统设计和实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承…

【JAVA基础】集合类之HashSet的原理及应用

近期几期内容都是围绕该体系进行知识讲解&#xff0c;以便于同学们学习Java集合篇知识能够系统化而不零散。 本文将介绍HashSet的基本概念&#xff0c;功能特点&#xff0c;使用方法&#xff0c;以及优缺点分析和应用场景案例。 一、概念 HashSet是 Java 集合框架中的一个重…

Spring Boot实现License生成与校验详解

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 在软件开发领域&#xff0c;License&#xff08;许可证&#xff09;机制是保护软件版权、控制软件使用范围的重要手段。通过为软件生成唯一的License&#xff0c;开发者可以确保只有合法用户才能使用软件&…

右键菜单添加 Open Tabby here

如果安装了Tabby&#xff0c;为了提高效率在鼠标右键菜单中添加Open Tabby here&#xff0c;可以通过按 win R&#xff0c;并输入regedit 回车打开注册表编辑器 计算机\HKEY_CLASSES_ROOT\Directory\Background\shell 然后在Shell下面新建项&#xff0c;名称为Tabby&#xf…

企业架构理论TOGAF从理论到实践:引领企业数字化转型的实践指南

在现代企业面临的数字化转型浪潮中&#xff0c;如何从战略层面实现技术与业务的全面融合&#xff0c;成为了众多企业的核心挑战。TOGAF&#xff08;The Open Group Architecture Framework&#xff09;不仅为企业提供了强大的理论框架&#xff0c;还通过实践验证了其在推动企业…

力扣 中等 39.组合总和

文章目录 题目介绍解法 题目介绍 解法 是216组合总和III链接的扩展 class Solution {List<List<Integer>> res new ArrayList<>();List<Integer> path new ArrayList<>();public List<List<Integer>> combinationSum(int[] can…

Windows 下安装mamba_ssm 记录,包括causal-conv1d和mamba-ssm

Windows 下安装mamba_ssm 记录 1 重要参考文献2 具体安装步骤3 一些提醒事项4 安装causal-conv1d5 安装mamba-ssm6 结果展示 1 重要参考文献 Window 下Mamba 环境安装踩坑问题汇总及解决方法 2 具体安装步骤 重点看的是这篇 Window 下Mamba 环境安装踩坑问题汇总及解决方法 …

【Redis】持久化(下)-- AOF

文章目录 AOF概念如何使用AOFAOF工作流程命令写入演示文件同步策略 AOF的重写机制概念触发重写机制AOF重写流程 启动时数据恢复混合持久化总结 AOF 概念 AOF持久化:以独立日志的方式记录每次的写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的.AOF的主要作用是解决…

工行企业网银U盾展期后有两个证书问题的解决方法

工行企业网银U盾证书快到期后&#xff0c;可以自助展期&#xff0c;流程可以根据企业网银提示页面操作。操作后&#xff0c;可能存在两个新旧两个证书并存的情况&#xff0c;致使网银转账等操作失败&#xff0c;如图&#xff1a; 其原因是新证书生成后&#xff0c;旧证书没有删…

wsl配置图形显示环境 no $display environment variable

wsl运行fsl&#xff0c;安装好之后&#xff0c;可以使用bet&#xff0c;等命令行进行操作&#xff0c;但是不能使用fsl呼出窗口。 因为 wsl并不像原生linux具有destop桌面&#xff0c;它只有命令行。所以当运行fsl的时候会报错&#xff0c; application-specific initializat…

裁掉数千人、把工作外包给 AI!一年多后,这家巨头的 CEO恳求无人搭理

“对&#xff0c;裁掉几千名员工。” “好的&#xff0c;头儿。” “很好&#xff0c;那么这个人工智能可以做那些前雇员能做的一切事情&#xff1f;” “不&#xff0c;不全是。” “等等&#xff0c;什么&#xff1f;” “你刚刚裁掉的几百人都是硬件工程师&#xff0c;…

k8s的pod的管理和优化

资源管理介绍 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0c;用户需要通过操作资源来管理kubernetes。 kubernetes的本质上就是一个集群系统&#xff0c;用户可以在集群中部署各种服务 所谓的部署服务&#xff0c;其实就是在kubernetes集群中运行一个个的容器…