SDL - объектно-ориентированный путь - PullRequest
1 голос
/ 29 августа 2011

Извинитесь, если это слишком длинный пост. Я просто пытаюсь заставить SDL работать объектно-ориентированным образом - нет смысла двигаться дальше, пока я не достигну этой точки. Потратил немало времени на компиляцию и получение ошибок. Я опубликую свои заголовочные файлы и исходники, вместе с моим make-файлом и выводом, чтобы увидеть, что происходит.

Вот 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, а также путь к файлу, который будет отображаться для загрузки на карту. Это легко сделать процедурно, но я готов поэкспериментировать с дизайном ОО на этом.

Итак, есть мысли?

Ответы [ 2 ]

3 голосов
/ 29 августа 2011

У вас есть две синтаксические ошибки, которые понятны из ваших ошибок:

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, чтобы избежать утечки памяти.

Я не понимаю часть вопроса "какие-либо мысли", потому что она не говорит о чем. Хотя английский не мой родной язык, так что прости меня, если я что-то пропустил.

0 голосов
/ 17 сентября 2012

Переверните экран после рендеринга изображения . Когда вы что-то копируете, оно помещается в буфер. SDL_Flip() просто меняет эти буферы, чтобы можно было увидеть ваш o / p. Я полагаю, вам следует заменить эти две строки.

...