开发者

SDL - The object Oriented Way

开发者 https://www.devze.com 2023-03-31 15:25 出处:网络
Apologize if this is too long of a post. I\'m merely trying to get SDL to work in an object oriented fashion - there\'s no point in me moving on until I get past this point. Been spending a fair amoun

Apologize if this is too long of a post. I'm merely trying to get SDL to work in an object oriented fashion - there's no point in me moving on until I get past this point. Been spending a fair amount of time compiling this and getting errors. I'll post my header files and sources, along with my makefile and an output to see what's going on.

Here's 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

...and 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);

}

...and 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

...and 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);
        }

}

...and of course 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;
}

...my output:

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
开发者_JAVA百科

...my 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 

the nitty gritty:

My goal with this is to have ScreenWriter implemented as a singleton to setup allegro and flag everything as needed through initialization. The second objective relies on render to just render by specifying x and y coordinates, along with a path to the file to render to load on the map. This is easy to do procedurally, but I'm ready to experiment with OO design on this.

So, any thoughts?


You have two syntax errors which are clear from your errors:

ScreenWriter * instance = ScreenWriter::get_instance();

should be

ScreenWriter & instance = ScreenWriter::get_instance();

because get_instance returns a reference, not a pointer, and

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

should be

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

because new returns a pointer, not an object or reference.

Also,

delete instance();

should be

delete render;

because not only is the former completely wrong, but it's not being used on anything allocated by new. render is, however. So you have to delete it to avoid a memory leak.

I don't understand the "any thoughts" part of the question because it doesn't say about what. English isn't my first language though, so forgive me if I missed something.


Flip the screen after rendering the image. When you blit something, it's blitted on a buffer. SDL_Flip() just swaps those buffers so that your o/p can be seen. So you should be replacing those two lines, I guess.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号