SDL - 面向对象的方式

时间:2011-08-29 03:32:56

标签: 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 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);
        }

}

...当然还有 main.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

...我的 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 

细节

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

那么,有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您有两个语法错误,这些错误可从您的错误中清除:

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它以避免内存泄漏。

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

答案 1 :(得分:0)

渲染图像后翻转屏幕。当你搞什么东西时,它会在缓冲区上进行。 SDL_Flip()只需交换这些缓冲区,以便可以看到你的o / p。所以你应该更换这两行。