简体   繁体   English

为什么我的 C++ 代码不呈现 SDL 矩形?

[英]Why isn't my C++ code rendering an SDL rectangle?

I'm new to using SDL with C++ and was trying to create a little Pong game as a project, too bad I can't actually render a rectangle, I have tried to figure out whats wrong.我不熟悉将 SDL 与 C++ 一起使用,并试图创建一个小 Pong 游戏作为一个项目,太糟糕了,我实际上无法渲染一个矩形,我试图找出问题所在。 but I need somebody who actually knows SDL in depth help me: This is the code I am working with:但我需要真正深入了解 SDL 的人帮助我:这是我正在使用的代码:

SystemManager.h系统管理器.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);
}
};

Player.h播放器.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() {

}
};

And Main.cpp和 Main.cpp

#include <SDL.h>

#include "Player.h"



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

Might somebody help explain to me what I'm doing wrong?有人可以帮我解释一下我做错了什么吗?

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;
}

First, if you do not understand my written explanation, I can create video and explain line by line how to fix your code.首先,如果您不理解我的书面解释,我可以创建视频并逐行解释如何修复您的代码。

So, there are many errors with your code.所以,你的代码有很多错误。 In the first part of the explanation I will explain why it does not work.在解释的第一部分,我将解释为什么它不起作用。 In the second part, I will show you the correct way of writing your header files as well as some other problems.在第二部分中,我将向您展示编写头文件的正确方法以及其他一些问题。 In the third part I will give you the code to make it work.在第三部分中,我将为您提供使其工作的代码。

PART 1: Why your code isn't working第 1 部分:为什么您的代码不起作用

The first thing I noticed is that you are calling some functions twice on accident.我注意到的第一件事是你不小心调用了一些函数两次。 If you check the return value of a function in a conditional, the function is called.如果您在条件语句中检查函数的返回值,则会调用该函数。

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

For instance in this code you call SDL_Init(SDL_INIT_VIDEO) twice.例如,在此代码中,您调用了 SDL_Init(SDL_INIT_VIDEO) 两次。 Instead delete the first and just call the function in the conditional.而是删除第一个并在条件中调用函数。 You also do that here:你也可以在这里这样做:

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

Keep in mind, as of now, if your code were to run you would not be able to exit the window, because you are not checking if the window should be closed.请记住,到目前为止,如果您的代码要运行,您将无法退出窗口,因为您没有检查窗口是否应该关闭。

You also need to go back and learn how inheritance.你还需要回去学习如何继承。 When you draw the rectangle you pass in the window pointer from the inherited SystemManager.当您绘制矩形时,您从继承的 SystemManager 传入窗口指针。 The problem is that this is a copy of the window pointer.问题是这是窗口指针的副本。 Instead you should pass in the render pointer when you call the player render function.相反,您应该在调用播放器渲染函数时传入渲染指针。 If you look at my example code at the bottom I do this.如果您查看底部的示例代码,我会这样做。

Define the function like this:像这样定义函数:

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

Call the function like this:像这样调用函数:

SDL_RenderClear(System.m_window_renderer);

PART 2: Other things you happen to be doing incorrectly第 2 部分:您碰巧做错的其他事情

First fix the issues I described previously.首先修复我之前描述的问题。

You are using header files in a way that most people say you shouldn't.您正在以大多数人认为不应该的方式使用头文件。 You are defining the class function inside the header.您正在标题内定义类函数。 Instead, you should create a second file with the.c extension that defines the class functions.相反,您应该创建第二个扩展名为 .c 的文件来定义类函数。

Here is a link that will show you the proper way to write header fies: https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/这是一个链接,它将向您展示编写标题文件的正确方法: https ://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/

Also, when you init sdl, you should check the if the return value is less than zero instead of.0.此外,当您初始化 sdl 时,您应该检查返回值是否小于零而不是 .0。 It's a little nit picky so you can ignore this if you want.这有点挑剔,所以如果你愿意,你可以忽略它。

Example:例子:

if (SDL_Init(SDL_INIT_VIDEO) < 0)

PART 3: The fixed code第 3 部分:固定代码

I fixed your code and put it all into one c file.我修复了你的代码并将其全部放入一个 c 文件中。 Here is the fixed code:这是固定代码:

#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;
}

If you are using linux, you can compile with:如果你使用的是 linux,你可以编译:

g++ Main.cpp -lSDL2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM