为什么我的 C++ 代码不呈现 SDL 矩形?
Why isn't my C++ code rendering an SDL rectangle?
我不熟悉将 SDL 与 C++ 结合使用,并试图创建一个小 Pong 游戏作为一个项目,太糟糕了,我实际上无法渲染矩形!我试图找出问题所在,但我需要真正深入了解 SDL 的人帮助我。这是我正在使用的代码:
SystemManager.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
#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;
}
首先,如果您不理解我的书面解释,我可以创建视频并逐行解释如何修复您的代码。
所以,您的代码有很多错误。在解释的第一部分,我将解释为什么它不起作用。在第二部分中,我将向您展示编写 header 文件的正确方法以及其他一些问题。在第三部分中,我将提供使其工作的代码。
第 1 部分:为什么您的代码无法正常工作
我注意到的第一件事是您不小心调用了某些函数两次。如果您在条件语句中检查函数的 return 值,则会调用该函数。
SDL_Init(SDL_INIT_VIDEO);
if (SDL_Init(SDL_INIT_VIDEO) != 0)
例如,在此代码中,您调用了 SDL_Init(SDL_INIT_VIDEO) 两次。而是删除第一个并在条件中调用函数。您也可以在这里这样做:
System.Initialize();
if (System.Initialize() == false)
请记住,到目前为止,如果您的代码是 运行,您将无法退出 window,因为您没有检查 window 是否应该关闭。
你还需要回去学习如何继承。当您绘制矩形时,您从继承的 SystemManager 传入 window 指针。问题是这是 window 指针的副本。相反,您应该在调用播放器渲染函数时传入渲染指针。如果您查看底部的示例代码,我会这样做。
像这样定义函数:
void Player_Draw(SDL_Renderer* render) {
SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
SDL_RenderFillRect(render, &pong1);
}
像这样调用函数:
SDL_RenderClear(System.m_window_renderer);
第 2 部分:您碰巧做错的其他事情
首先修复我之前描述的问题。
您正在以大多数人认为不应该的方式使用 header 文件。您正在 header 中定义 class 函数。相反,您应该创建第二个扩展名为 .c 的文件来定义 class 函数。
这里有一个 link 将向您展示编写 header fies 的正确方法:
https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/
此外,当您初始化 sdl 时,您应该检查 return 值是否小于零而不是 !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
我不熟悉将 SDL 与 C++ 结合使用,并试图创建一个小 Pong 游戏作为一个项目,太糟糕了,我实际上无法渲染矩形!我试图找出问题所在,但我需要真正深入了解 SDL 的人帮助我。这是我正在使用的代码:
SystemManager.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
#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;
}
首先,如果您不理解我的书面解释,我可以创建视频并逐行解释如何修复您的代码。
所以,您的代码有很多错误。在解释的第一部分,我将解释为什么它不起作用。在第二部分中,我将向您展示编写 header 文件的正确方法以及其他一些问题。在第三部分中,我将提供使其工作的代码。
第 1 部分:为什么您的代码无法正常工作
我注意到的第一件事是您不小心调用了某些函数两次。如果您在条件语句中检查函数的 return 值,则会调用该函数。
SDL_Init(SDL_INIT_VIDEO);
if (SDL_Init(SDL_INIT_VIDEO) != 0)
例如,在此代码中,您调用了 SDL_Init(SDL_INIT_VIDEO) 两次。而是删除第一个并在条件中调用函数。您也可以在这里这样做:
System.Initialize();
if (System.Initialize() == false)
请记住,到目前为止,如果您的代码是 运行,您将无法退出 window,因为您没有检查 window 是否应该关闭。
你还需要回去学习如何继承。当您绘制矩形时,您从继承的 SystemManager 传入 window 指针。问题是这是 window 指针的副本。相反,您应该在调用播放器渲染函数时传入渲染指针。如果您查看底部的示例代码,我会这样做。
像这样定义函数:
void Player_Draw(SDL_Renderer* render) {
SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
SDL_RenderFillRect(render, &pong1);
}
像这样调用函数:
SDL_RenderClear(System.m_window_renderer);
第 2 部分:您碰巧做错的其他事情
首先修复我之前描述的问题。
您正在以大多数人认为不应该的方式使用 header 文件。您正在 header 中定义 class 函数。相反,您应该创建第二个扩展名为 .c 的文件来定义 class 函数。
这里有一个 link 将向您展示编写 header fies 的正确方法: https://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/
此外,当您初始化 sdl 时,您应该检查 return 值是否小于零而不是 !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