This is one way of reading the contents of the file once and using the contents in the loop.
Function to read the contents
void getCharList(std::string const& filename,
std::vector<char>& charList)
{
std::ifstream infile(filename);
char ch;
while ( infile >> std::noskipws >> ch )
{
charList.push_back(ch);
}
}
Updated main
int main(int argc, char* argv[]) {
std::string filename = "Map00.txt";
int charStartX = 300, charStartY = 200; //Character starting position, the rest of the below variables are self-explanatory
bool game = true;
std::string direction;
int frame = 0;//Used for measuring FPS
bool will_cap = true;
Timer fps;
initialize();//Loads SDL and Co. into memory
user User(charStartX, charStartY); //Creates user object
Display display; //Creates display object, used for handling keyboard input/display updates
load_files();//loads the images into memory
std::vector<char> charList;
getCharList(filename, charList);
draw_map(charList, filename, User); //Scans file, displaying it onto the screen as it goes
while (game) { //Main Game Loop
fps.start(); //Starts fps timer
display.processInput(direction, game, will_cap);//Checks for keyboard input
display.updateEverything(charList, filename, User, direction);//updates and displays all images on screen
frame++;
if ((will_cap) && (fps.get_ticks() < 1000 / FRAMES_PER_SECONDS)) { //Makes sure the framerate stays at the prescribed number
SDL_Delay( ( 1000 / FRAMES_PER_SECONDS ) - fps.get_ticks());
}
}
clean_up(); //Removes all surfaces from memory
}
Updated draw_map
void draw_map(std::vector<char> const& charList, std::string filename, user User) {
int tileX = User.offsetX;//Sets initial drawing values to the offset(which will be zero for first draw)
int tileY = User.offsetY;
blit_surface(tileX, tileY, tile0, screen);//Displays first tile
for ( auto ch : charList ) {//Changes draw cursor based on height/width
if (ch == '0') {
tileX += tile0->w;
}
else if (Map.peek() == '\n') {
tileX = User.offsetX;
tileY += tile0->h;
}
blit_surface(tileX, tileY, tile0, screen);//Displays the rest of the tiles
}
}
Updated updateEverything
void updateEverything(std::vector<char> const& charList, std::string filename, user &User, std::string direction) { //Handles all updates/display flipping
draw_map(charList, filename, User);
User.update(direction);
SDL_Flip(screen);
}
Other suggestions
There is too much codde in one file. In addition to many helper functions, you have the following classes:
user
Display
Timer
For the sake of naming consistency, I would change the class user to User. I would put the declarations of the classes in three header files - User.h, Display.h, and Timer.h. I would move the implementations to User.cpp, Display.cpp, and Timer.cpp, respectively.
I would put the declarations of all the helper functions in a .h file (call it tileFunctions.h, for example), and put the definitions of the helper functions in a corresponding .cpp file (call it tileFunctions.cpp, for example).
Reduce objects in global scope
You have
SDL_Event event;
which is used only in Display::processInput. I would move the global object to an to be local variable in the function scope.
You also have:
SDL_Surface *tile0 = 0;
SDL_Surface *screen = 0;
SDL_Surface *userTile = 0;
in the global scope. I would create a struct that holds these together and pass the struct around, starting from main. That would remove the need for them to be in global scope.
Use an enum instead of strings for direction
Instead of using strings "UP", "DOWN", "LEFT", and "RIGHT" for directions, use an enum.
enum Direction { UP, DOWN, LEFT, RIGHT };