首页 > 解决方案 > 为什么我的 C++ 代码没有呈现 SDL 矩形?

问题描述

我是使用 SDL 和 C++ 的新手,并且试图创建一个小型 Pong 游戏作为一个项目,太糟糕了,我实际上无法渲染一个矩形!我试图找出问题所在,但我需要真正深入了解 SDL 的人来帮助我。这是我正在使用的代码:

系统管理器.h

#pragma once
#include <SDL.h>
#include <cstdio>

class SystemManager {
const int SCREEN_WIDTH = 1000;
const int SCREEN_HEIGHT = 800;

public:
SDL_Window* m_window = nullptr;
SDL_Renderer* m_window_renderer = nullptr;

bool running = true;



bool Initialize() {
    SDL_Init(SDL_INIT_VIDEO);

    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        printf("SDL could not initialize! SDL Error: %s \n", SDL_GetError());

        return false;
    }
    else {
        m_window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_BORDERLESS);
        m_window_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_PRESENTVSYNC);

        if (m_window == NULL) {
            printf("SDL Window could not be constructed! SDL Error: %s \n", SDL_GetError());

            return false;
        }
    }



    return true;
}


void Render() {
    SDL_SetRenderDrawColor(m_window_renderer, 0, 0, 0, 255);
    SDL_RenderPresent(m_window_renderer);
}
};

播放器.h

#pragma once

#include "SystemManager.h"



class Player : public SystemManager {
int y_axis = 400;

public:
void Player_Draw() {
    SDL_SetRenderDrawColor(m_window_renderer, 0, 0, 0, 255);
    SDL_RenderClear(m_window_renderer);



    SDL_Rect pong1;

    pong1.w = 30;
    pong1.h = 50;
    pong1.x = 970;
    pong1.y = 400;

    SDL_SetRenderDrawColor(m_window_renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(m_window_renderer, &pong1);
}



void Inputs() {

}
};

和 Main.cpp

#include <SDL.h>

#include "Player.h"



int main(int argc, char* argv[]) {
SystemManager System;
Player PlayerPong;

有人可以帮我解释一下我做错了什么吗?

System.Initialize();

if (System.Initialize() == false) {
    return -1;
}



while (System.running == true) {
    PlayerPong.Player_Draw();
    System.Render();
}



SDL_DestroyWindow(System.m_window);
SDL_DestroyRenderer(System.m_window_renderer);
SDL_Quit();

return 0;
}

标签: c++sdl

解决方案


首先,如果您不理解我的书面解释,我可以制作视频并逐行解释如何修复您的代码。

所以,你的代码有很多错误。在解释的第一部分,我将解释为什么它不起作用。在第二部分中,我将向您展示编写头文件的正确方法以及其他一些问题。在第三部分中,我将为您提供使其工作的代码。

第 1 部分:为什么您的代码不起作用

我注意到的第一件事是您意外调用了某些函数两次。如果您在条件中检查函数的返回值,则调用该函数。

SDL_Init(SDL_INIT_VIDEO);
if (SDL_Init(SDL_INIT_VIDEO) != 0) 

例如,在此代码中,您调用 SDL_Init(SDL_INIT_VIDEO) 两次。而是删除第一个并在条件中调用该函数。您也可以在这里执行此操作:

System.Initialize();
if (System.Initialize() == false)

请记住,到目前为止,如果您的代码要运行,您将无法退出窗口,因为您没有检查窗口是否应该关闭。

你还需要回去学习如何继承。当您绘制矩形时,您从继承的 SystemManager 传入窗口指针。问题是这是窗口指针的副本。相反,您应该在调用播放器渲染函数时传入渲染指针。如果您查看底部的示例代码,我会这样做。

像这样定义函数:

void Player_Draw(SDL_Renderer* render) {
    SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
    SDL_RenderFillRect(render, &pong1);
}

像这样调用函数:

SDL_RenderClear(System.m_window_renderer);

第 2 部分:您碰巧做错的其他事情

首先解决我之前描述的问题。

您以大多数人认为不应该的方式使用头文件。您正在标题内定义类函数。相反,您应该创建另一个扩展名为 .c 的文件来定义类函数。

这是一个链接,将向您展示编写标题文件的正确方法: https ://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/

此外,当您初始化 sdl 时,您应该检查返回值是否小于零而不是 !0。它有点挑剔,所以如果你愿意,你可以忽略它。

例子:

if (SDL_Init(SDL_INIT_VIDEO) < 0)

第 3 部分:固定代码

我修复了您的代码并将其全部放入一个 c 文件中。这是固定代码:

#include <iostream>
#include <SDL2/SDL.h>

class SystemManager {
    const int SCREEN_WIDTH = 1000;
    const int SCREEN_HEIGHT = 800;

    public:
    SDL_Window* m_window = nullptr;
    SDL_Renderer* m_window_renderer = nullptr;

    bool running = true;
    bool Initialize() {

        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            printf("SDL could not initialize! SDL Error: %s \n", SDL_GetError());

            return false;
        }
        else {
            m_window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
            m_window_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_PRESENTVSYNC);

            if (m_window == NULL) {
                printf("SDL Window could not be constructed! SDL Error: %s \n", SDL_GetError());
                return false;
            }
        }

        return true;
    }


    void Render() {
        SDL_SetRenderDrawColor(m_window_renderer, 0, 0, 0, 255);
        SDL_RenderPresent(m_window_renderer);
    }
};

class Player : public SystemManager {
    int y_axis = 400;
    SDL_Rect pong1;

    public:

    Player(){
        pong1.w = 100;
        pong1.h = 100;
        pong1.x = 100;
        pong1.y = 100;
    }

    void Player_Draw(SDL_Renderer* render) {
        SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
        SDL_RenderFillRect(render, &pong1);
    }



    void Inputs() {

    }
};

int main(int argc, char* argv[]) {
    SystemManager System;
    Player PlayerPong;

    if (System.Initialize() == false) {
        return -1;
    }



    while (System.running == true) {
        SDL_SetRenderDrawColor(System.m_window_renderer, 0, 0, 0, 255);
        SDL_RenderClear(System.m_window_renderer);
        PlayerPong.Player_Draw(System.m_window_renderer);
        System.Render();
    }

    SDL_DestroyWindow(System.m_window);
    SDL_DestroyRenderer(System.m_window_renderer);
    SDL_Quit();

    return 0;
}

如果您使用的是 linux,则可以使用以下命令进行编译:

g++ Main.cpp -lSDL2

推荐阅读