【问题标题】:SDL - The object Oriented WaySDL - 面向对象的方式
【发布时间】:2011-11-05 18:00:44
【问题描述】:

如果帖子太长,请见谅。我只是想让 SDL 以面向对象的方式工作——在我超越这一点之前,我继续前进是没有意义的。花了相当多的时间编译这个并得到错误。我将发布我的头文件和源代码,以及我的 makefile 和输出以查看发生了什么。

这里是 render.h

#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

...和 ​​render.cpp

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

}

...和 ​​screenwriter.h

#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

...和 ​​screenwriter.cpp

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

}

...当然还有 ma​​in.cpp

#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

...我的 ma​​kefile

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 

细节

我的目标是让 ScreenWriter 实现为单例来设置 allegro 并通过初始化根据需要标记所有内容。第二个目标依赖于渲染,通过指定 x 和 y 坐标以及要渲染以加载到地图上的文件的路径来进行渲染。这在程序上很容易做到,但我已准备好在这方面尝试 OO 设计。

那么,有什么想法吗?

【问题讨论】:

  • 等等,您正在使 SDL 面向对象? Hasn't someone already done that?
  • 如果已经完成了,那很好。我决定以面向对象的方式来做这件事,这样我就可以学习了。另外,SDL 是一个很好的图形库。
  • 是的,我只是指出 SDL 是用 C 编写的,而 SFML 是用 C++ 编写的。此外,许多人说它比 SDL 设计得更好、速度更快。
  • 如果你真的想使用面向对象的游戏库,我肯定会选择使用 SFML。它更简单,我觉得它的界面比 SDL 更干净。
  • 真的吗?好的,那我就开始用吧。

标签: c++ error-handling sdl render


【解决方案1】:

渲染图像后翻转屏幕。当你对某个东西进行 blit 时,它会在缓冲区上进行 blit。 SDL_Flip() 只是交换这些缓冲区,以便可以看到您的 o/p。所以你应该替换这两行,我猜。

【讨论】:

  • 嗯,你看到另一个答案的绿色勾号了吗?这意味着OP已经接受了答案,它帮助他解决了问题。一年前 ;) 无论如何,感谢您的努力。
【解决方案2】:

您的错误中有两个语法错误:

ScreenWriter * instance = ScreenWriter::get_instance();

应该是

ScreenWriter & instance = ScreenWriter::get_instance();

因为get_instance 返回的是引用,而不是指针,并且

Render render = new Render("look.png", 0, 0, instance->get_screen());

应该是

Render * render = new Render("look.png", 0, 0, instance->get_screen());

因为new 返回的是指针,而不是对象或引用。

还有,

delete instance();

应该是

delete render;

因为前者不仅完全错误,而且它没有被用于new 分配的任何东西。但是,render 是。所以你必须delete它以避免内存泄漏。

我不明白问题的“任何想法”部分,因为它没有说明什么。不过英语不是我的第一语言,如果我遗漏了什么,请原谅我。

【讨论】:

  • 谢谢。我修复了错误。但是,你能告诉我为什么我的对象不会渲染以及为什么 SDL 不会初始化吗?程序编译并运行,但没有任何反应。
  • @Holland 你没有在我看到的任何地方打电话给Screenwriter::initialize,所以SDL 没有被初始化。还有delete instance(); 应该是delete render;(更正之前的错误)
猜你喜欢
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 2012-06-17
  • 2014-08-24
  • 2015-04-28
  • 2014-12-15
相关资源
最近更新 更多