What I did is I changed the code so that you have two surfaces m_full and m_empty in the MapEditor class, then in the MapEditor constructor they are loaded with square_full.png and square_empty.png. These are passed to each tile so that all tiles also have m_full and m_empty, but it means I'm not loading the images each time a new tile is created, the tiles just point to the images I loaded in the MapEditor object.
One question I have is that I removed the destructor for the Tile class and then did SDL_FreeSurface( m_full ) and SDL_FreeSurface( m_empty ) in the MapEditor class. The way I see it is that SDL_FreeSurface frees the actual images themselves, so I only need to free them when the MapEditor object is destroyed - if I destroyed them in the Tile class then the first Tile object destroyed would free those surfaces, but all the other Tile objects destroyed after that would have no surfaces to free. Is that correct?
Here's the new code:
// map_editor.cpp#include "SDL/SDL.h"#include "SDL/SDL_image.h"#include <string>#include <vector>// *******************************// * Functions// *******************************SDL_Surface* load_image( std::string filename ){ SDL_Surface* A = IMG_Load( filename.c_str() ); SDL_Surface* B = SDL_DisplayFormat( A ); SDL_FreeSurface( A ); return B;}// *******************************// * Screen// *******************************class Screen{public: Screen(); void apply( int x, int y, SDL_Surface* surface ); void show();private: SDL_Surface* m_screenSurface;};Screen::Screen(){ m_screenSurface = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );}void Screen::apply( int x, int y, SDL_Surface* surface ){ SDL_Rect offset; offset.x = x; offset.y = y; SDL_BlitSurface( surface, NULL, m_screenSurface, &offset );}void Screen::show(){ SDL_Flip( m_screenSurface );}// *******************************// * Tile// *******************************class Tile{public: Tile( int x, int y , SDL_Surface* full, SDL_Surface* empty ); int get_x(); int get_y(); void click(); SDL_Surface* get_image();private: int m_x; int m_y; bool m_isFull; SDL_Surface* m_image; SDL_Surface* m_full; SDL_Surface* m_empty;};Tile::Tile( int x, int y, SDL_Surface* full, SDL_Surface* empty ){ m_x = x; m_y = y; m_full = full; m_empty = empty; m_image = m_empty; m_isFull = false;}int Tile::get_x(){ return m_x;}int Tile::get_y(){ return m_y;}void Tile::click(){ if( m_isFull == true ) { m_image = m_empty; m_isFull = false; } else { m_image = m_full; m_isFull = true; }}SDL_Surface* Tile::get_image(){ return m_image;}// *******************************// * MapEditor// *******************************class MapEditor{public: MapEditor(); ~MapEditor(); void start();private: std::vector<Tile> m_map; SDL_Surface* m_full; SDL_Surface* m_empty; Screen m_screen; SDL_Event m_event;};MapEditor::MapEditor(){ SDL_Init( SDL_INIT_EVERYTHING ); m_full = load_image( "square_full.png" ); m_empty = load_image( "square_empty.png" ); for( int x = 40; x <= 600; x += 40 ) { for( int y = 40; y <= 440; y += 40 ) { m_map.push_back( Tile( x, y, m_full, m_empty ) ); } }}MapEditor::~MapEditor(){ SDL_FreeSurface( m_full ); SDL_FreeSurface( m_empty ); SDL_Quit();}void MapEditor::start(){ bool quit = false; while( quit == false ) { while( SDL_PollEvent(&m_event) ) { switch( m_event.type ) { case SDL_MOUSEBUTTONDOWN: for( int tile = 0; tile < m_map.size(); ++tile ) { int x = m_map[tile].get_x(); int y = m_map[tile].get_y(); if( (x <= m_event.button.x < x + 40) && (y <= m_event.button.y < y + 40) ) { m_map[tile].click(); } } case SDL_QUIT: quit = true; } } for( int tile = 0; tile < m_map.size(); ++tile ) { int x = m_map[tile].get_x(); int y = m_map[tile].get_y(); SDL_Surface* image = m_map[tile].get_image(); m_screen.apply( x, y, image ); } m_screen.show(); }}// *******************************// * Main// *******************************int main( int argc, char* args[] ){ MapEditor editor; editor.start(); return 0;}