C++ SDL——面向对象的方法
如果这篇文章太长,请道歉。我只是想让SDL以一种面向对象的方式工作——在我超越这一点之前,继续前进是没有意义的。我花了相当多的时间来编译这篇文章,结果出错了。我将发布我的头文件和源文件,以及我的makefile和一个输出,以查看发生了什么 这里是render.h:C++ SDL——面向对象的方法,c++,error-handling,sdl,render,C++,Error Handling,Sdl,Render,如果这篇文章太长,请道歉。我只是想让SDL以一种面向对象的方式工作——在我超越这一点之前,继续前进是没有意义的。我花了相当多的时间来编译这篇文章,结果出错了。我将发布我的头文件和源文件,以及我的makefile和一个输出,以查看发生了什么 这里是render.h: #ifndef RENDER_H #define RENDER_H #include <string> #include <SDL/SDL.h> using std::string; class Rend
#ifndef RENDER_H
#define RENDER_H
#include <string>
#include <SDL/SDL.h>
using std::string;
class Render
{
public:
Render(string filename, int x, int y, SDL_Surface * destination);
~Render();
private:
SDL_Surface * m_optimizedImage;
void load_image(string filename);
void apply_surface(int x, int y, SDL_Surface * source, SDL_Surface * destination);
};
#endif
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <string>
#include "render.h"
using std::string;
Render::Render(string filename, int x, int y, SDL_Surface * destination)
{
this->m_optimizedImage = NULL;
load_image(filename);
apply_surface(x, y, m_optimizedImage, destination);
}
Render::~Render()
{
delete m_optimizedImage;
}
void Render::load_image(string filename)
{
SDL_Surface * loadedImage = IMG_Load(filename.c_str());
if (loadedImage != NULL)
{
m_optimizedImage = SDL_DisplayFormat(loadedImage);
SDL_FreeSurface(loadedImage);
}
}
void Render::apply_surface(int x, int y, SDL_Surface * source, SDL_Surface * destination)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL, destination, &offset);
}
#include <iostream>
#include <SDL/SDL.h>
#ifndef SCREENWRITER_H
#define SCREENWRITER_H
class ScreenWriter
{
public:
~ScreenWriter();
bool flip_screen();
void delay_screen(int milliseconds);
bool get_screen_state() const;
static ScreenWriter& get_instance();
SDL_Surface * get_screen() const;
private:
ScreenWriter();
void initialize();
bool m_screenFailure;
SDL_Surface * m_screen;
};
#endif
#include <SDL/SDL.h>
#include "screenwriter.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 32
ScreenWriter::ScreenWriter()
{
this->m_screenFailure = false;
initialize();
}
ScreenWriter::~ScreenWriter()
{
SDL_Quit();
}
ScreenWriter& ScreenWriter::get_instance()
{
static ScreenWriter instance;
return instance;
}
SDL_Surface * ScreenWriter::get_screen() const
{
return m_screen;
}
bool ScreenWriter::get_screen_state() const
{
return this->m_screenFailure;
}
void ScreenWriter::delay_screen(int milliseconds)
{
SDL_Delay(milliseconds);
}
int ScreenWriter::flip_screen()
{
if (SDL_Flip(m_screen) == -1)
{
return 1;
}
else
{
SDL_Flip(m_screen);
return 0;
}
}
void ScreenWriter::initialize()
{
if (SDL_Init(SDL_INIT_EVERYTHING == -1))
{
std::cout << "SDL_Init has failed";
}
else
{
SDL_Init(SDL_INIT_EVERYTHING);
//initialize screen
this->m_screen = SDL_SetVideoMode(SCREEN_WIDTH,
SCREEN_HEIGHT,
SCREEN_BPP,
SDL_SWSURFACE);
if (m_screen == NULL)
{
this->m_screenFailure = true;
}
else
{
this->m_screenFailure = false;
}
//set caption header
SDL_WM_SetCaption("Hello WOrld", NULL);
}
}
#include <iostream>
#include <SDL/SDL.h>
#include "screenwriter.h"
#include "render.h"
int main(int argc, char * args[])
{
std::cout << "hello world!" << std::endl;
ScreenWriter * instance = ScreenWriter::get_instance();
instance->flip_screen();
Render render = new Render("look.png", 0, 0, instance->get_screen());
delete instance();
return 0;
}
g++ -c main.cpp render.h screenwriter.h -lSDL -lSDL_image
main.cpp: In function ‘int main(int, char**)’:
main.cpp:10:55: error: cannot convert ‘ScreenWriter’ to ‘ScreenWriter*’ in initialization
main.cpp:12:69: error: conversion from ‘Render*’ to non-scalar type ‘Render’ requested
make: *** [main.o] Error 1
…我的makefile
program : main.o render.o screenwriter.o
g++ -o program main.o render.o screenwriter.o -lSDL -lSDL_image
main.o : main.cpp render.h screenwriter.h
g++ -c main.cpp render.h screenwriter.h -lSDL -lSDL_image
render.o : render.h render.cpp
g++ -c render.h render.cpp -lSDL
screenwriter.o : screenwriter.h screenwriter.cpp
g++ -c screenwriter.h screenwriter.cpp -lSDL -lSDL_image
clean:
rm program main.o render.o screenwriter.o
本质
#ifndef RENDER_H
#define RENDER_H
#include <string>
#include <SDL/SDL.h>
using std::string;
class Render
{
public:
Render(string filename, int x, int y, SDL_Surface * destination);
~Render();
private:
SDL_Surface * m_optimizedImage;
void load_image(string filename);
void apply_surface(int x, int y, SDL_Surface * source, SDL_Surface * destination);
};
#endif
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <string>
#include "render.h"
using std::string;
Render::Render(string filename, int x, int y, SDL_Surface * destination)
{
this->m_optimizedImage = NULL;
load_image(filename);
apply_surface(x, y, m_optimizedImage, destination);
}
Render::~Render()
{
delete m_optimizedImage;
}
void Render::load_image(string filename)
{
SDL_Surface * loadedImage = IMG_Load(filename.c_str());
if (loadedImage != NULL)
{
m_optimizedImage = SDL_DisplayFormat(loadedImage);
SDL_FreeSurface(loadedImage);
}
}
void Render::apply_surface(int x, int y, SDL_Surface * source, SDL_Surface * destination)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL, destination, &offset);
}
#include <iostream>
#include <SDL/SDL.h>
#ifndef SCREENWRITER_H
#define SCREENWRITER_H
class ScreenWriter
{
public:
~ScreenWriter();
bool flip_screen();
void delay_screen(int milliseconds);
bool get_screen_state() const;
static ScreenWriter& get_instance();
SDL_Surface * get_screen() const;
private:
ScreenWriter();
void initialize();
bool m_screenFailure;
SDL_Surface * m_screen;
};
#endif
#include <SDL/SDL.h>
#include "screenwriter.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 32
ScreenWriter::ScreenWriter()
{
this->m_screenFailure = false;
initialize();
}
ScreenWriter::~ScreenWriter()
{
SDL_Quit();
}
ScreenWriter& ScreenWriter::get_instance()
{
static ScreenWriter instance;
return instance;
}
SDL_Surface * ScreenWriter::get_screen() const
{
return m_screen;
}
bool ScreenWriter::get_screen_state() const
{
return this->m_screenFailure;
}
void ScreenWriter::delay_screen(int milliseconds)
{
SDL_Delay(milliseconds);
}
int ScreenWriter::flip_screen()
{
if (SDL_Flip(m_screen) == -1)
{
return 1;
}
else
{
SDL_Flip(m_screen);
return 0;
}
}
void ScreenWriter::initialize()
{
if (SDL_Init(SDL_INIT_EVERYTHING == -1))
{
std::cout << "SDL_Init has failed";
}
else
{
SDL_Init(SDL_INIT_EVERYTHING);
//initialize screen
this->m_screen = SDL_SetVideoMode(SCREEN_WIDTH,
SCREEN_HEIGHT,
SCREEN_BPP,
SDL_SWSURFACE);
if (m_screen == NULL)
{
this->m_screenFailure = true;
}
else
{
this->m_screenFailure = false;
}
//set caption header
SDL_WM_SetCaption("Hello WOrld", NULL);
}
}
#include <iostream>
#include <SDL/SDL.h>
#include "screenwriter.h"
#include "render.h"
int main(int argc, char * args[])
{
std::cout << "hello world!" << std::endl;
ScreenWriter * instance = ScreenWriter::get_instance();
instance->flip_screen();
Render render = new Render("look.png", 0, 0, instance->get_screen());
delete instance();
return 0;
}
g++ -c main.cpp render.h screenwriter.h -lSDL -lSDL_image
main.cpp: In function ‘int main(int, char**)’:
main.cpp:10:55: error: cannot convert ‘ScreenWriter’ to ‘ScreenWriter*’ in initialization
main.cpp:12:69: error: conversion from ‘Render*’ to non-scalar type ‘Render’ requested
make: *** [main.o] Error 1
我的目标是将编剧作为一个单独的人来实现,通过初始化来设置allegro并标记所需的一切。第二个目标通过指定x和y坐标以及要在地图上加载的渲染文件的路径,依赖于“渲染到仅渲染”。这在程序上很容易做到,但我已经准备好在这方面进行OO设计实验
那么,你有什么想法吗?你有两个语法错误,从错误中可以看出:
ScreenWriter * instance = ScreenWriter::get_instance();
应该是
ScreenWriter & instance = ScreenWriter::get_instance();
Render * render = new Render("look.png", 0, 0, instance->get_screen());
delete render;
因为get\u instance
返回一个引用,而不是指针,并且
Render render = new Render("look.png", 0, 0, instance->get_screen());
应该是
ScreenWriter & instance = ScreenWriter::get_instance();
Render * render = new Render("look.png", 0, 0, instance->get_screen());
delete render;
因为new
返回指针,而不是对象或引用
而且
delete instance();
应该是
ScreenWriter & instance = ScreenWriter::get_instance();
Render * render = new Render("look.png", 0, 0, instance->get_screen());
delete render;
因为不仅前者是完全错误的,而且它没有用于new
分配的任何东西<但是,代码>渲染是。因此,您必须删除它以避免内存泄漏
我不理解问题的“任何想法”部分,因为它没有说明什么。英语不是我的第一语言,所以如果我错过了什么,请原谅。在渲染图像后翻转屏幕。当你点击某个东西时,它会在缓冲区中点击SDL\u Flip()
只需交换这些缓冲区,就可以看到您的o/p。因此,我想您应该替换这两行。等等,您正在使SDL面向对象?如果已经这样做了就好了。我决定用面向对象的方法来做这件事,这样我就可以学习了。另外,SDL是一个很好的图形库。是的,我只是指出SDL是用C写的,但是SFML是用C++编写的。另外,很多人说它比SDL设计得更好,速度更快。如果你真的想使用面向对象的游戏库,我绝对支持使用SFML。它更简单,我觉得它的界面比SDL更干净。真的吗?好的,那我就开始用了。谢谢。我修正了错误。但是,你能告诉我为什么我的对象不会渲染,为什么SDL不会初始化吗?程序编译并运行,但什么也没发生。@Holland您没有在我看到的任何地方调用Screenwriter::initialize
,因此SDL没有被初始化。也delete instance()代码>应该是删除渲染代码>(纠正了以前的错误)嗯,你看到另一个答案上的绿色复选框了吗?这意味着OP已经接受了答案,这帮助他解决了问题。一年前;)无论如何,谢谢你的努力。