SDL - The object Oriented Way
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.
精彩评论