• entries
    46
  • comments
    91
  • views
    64166

A Complete Graphics-less Game #5 - World Map Part 2

Sign in to follow this  
Squared'D

749 views

It's been a while since I've had a chance to update this. I've started working on another project with an old friend of mine and 3 others so I haven't had the time to really focus on this project, but I'll try to keep it up. I think this is a good project for me. As I dive deeper into it, I feel that I'll be able to explore some interesting concepts. So what have I been working on?

World Map Part 2


You don't have to be a genius to see that the game is very limited. I thought this was as good a time as any to try to load the world map from a file. In all of my recent programs, I haven't been using C++ streams to do any file loading. It's been years since I've done anything with it. Honestly, even using "std::cout" feel like weird to me. I grew up on printf and all it's derivatives, but I will try my best to use streams now. Remember, I'm making this program as a learning experience. I want to show that programmers don't have to jump into graphics programming from the beginning. They can instead test basic concepts and refine their skills using console applications.

Long story short, I'm going to build a loader to load the world map. As I said before, towns and the world map will use the same basic system as everything is really just locations connected by links. That's why do code uses the name AreaMap and not WorldMap. Here's a sample of the world map. I'm using text files for now as they are easy by hand."Washington" 1 3"Frederick" 0 2 3 "Pittsburgh" 1 4"Baltimore" 0 1 4 5"Philadelphia" 2 3 5"Camden" 3 4 6"Newark" 5 7"New York" 6 8"Boston" 7
I think this format is simple enough. It's merely the name of the location followed by a list of the links. The loader will perform minimal error checking so the file should be in the proper format.

Input File Streams in C++


Input file streams in C++ are quite simple. Just include the header. I'll use the std::ifstream type because this is only for input. There are two ways to open the file: specifying the file in the object constructor or by using the open() method. Here's an example:std::ifstream m_file_stream;m_file_stream.open("test.txt", std::ios::in);// orstd::ifstream m_file_stream("test.txt", std::ios::in);
After opening a basic text file, you can use it just like std::cin.

Loading the Area Map


For this loader, I decided to create a loader class that will handle loading the file. I decided to make it a class because to load the file in a clean way, I needed to use multiple function calls. Putting it in a single class made everything fit nicely. I also had to make some changes to the CAreaMap class so I can add links to a location after the location in the map has been created.

Here's the class definition:// forward declaration of for the CAreaMap classclass CAreaMap;/// \brief return values for the loaderenum LoaderResult{ LOAD_OK = 0, LOAD_EOF = 1, LOAD_FAIL = 2};/// \brief Class for loading an area map/// An Area map can represent all the places in a town or it can be used as a/// higher level world map.class CAreaMapLoader{ public: /// \brief Loads the Area Map from a file /// @param szFile the file name /// @param the_area_map the area map to load the data to /// @return the result of the load LoaderResult LoadFromFile(const char *szFile, CAreaMap &the_area_map); private: // Helper function to parse a line LoaderResult ReadLine(CAreaMap &the_area_map); // Helper function to search a string for a quoted sub-string LoaderResult GetNextStringToken(const std::string &inputline, size_t start, std::string &out, size_t &next); // Helper funtion to search a string for an int LoaderResult GetNextIntToken(const std::string &inputline, size_t start, int &out, size_t &next); // Helper funtion to search for the next numeric character size_t findNum(const std::string &in, size_t start); std::ifstream m_file_stream;};
I made some helper functions to help me parse the file. Here's the code from LoadFromFile() and ReadLine():LoaderResult CAreaMapLoader::LoadFromFile(const char *szFile, CAreaMap &the_area_map){ // create the stream and open the file m_file_stream.open(szFile, std::ios::in); // check for success if(m_file_stream.fail()) return LOAD_FAIL; // read the lines LoaderResult result; do { result = ReadLine(the_area_map); } while(result == LOAD_OK); if(result == LOAD_EOF) { // this isn't failue, we just processed all of the data result = LOAD_OK; } // close the file m_file_stream.close(); return result;}LoaderResult CAreaMapLoader::ReadLine(CAreaMap &the_area_map){ // read the first line, it should be the number of places std::string file_line; // check for eof before getting the line otherwise if the last line ends with eof, it won't be processed if(m_file_stream.eof()) return LOAD_EOF; // get the next line std::getline(m_file_stream, file_line); // check for blank lines if(file_line.size() < 1) return LOAD_OK; if(m_file_stream.fail()) return LOAD_FAIL; if(m_file_stream.bad()) return LOAD_FAIL; size_t cursor = 0; std::string location_name; // get the location name GetNextStringToken(file_line, cursor, location_name, cursor); // create the location without any links LocationIndex loc_index = the_area_map.AddLocation(location_name, 0); // get the links LoaderResult link_result = LOAD_OK; int link; do { link_result = GetNextIntToken(file_line, cursor, link, cursor); if(link_result == LOAD_FAIL) return LOAD_FAIL; else if (link_result == LOAD_OK) { // add the links the_area_map.AddLocationLink(loc_index, link); } } while(link_result == LOAD_OK); return LOAD_OK;}
The code is very simple. I read an entire line from the string and then scan the line for the information that I need. Since I broke the code up into smaller sections, it's not some big convoluted mess.

Loading the map is as simple as this:CAreaMapLoader map_loader;map_loader.LoadFromFile("testmap.txt", m_WorldMap);
That's it. You can check the full source to see it working and as always, let me know if you have any problems compiling it.
Sign in to follow this  


6 Comments


Recommended Comments

I think it's a good learning process and a way to explore other aspects of making games. I'm surprised more people don't try it.

Share this comment


Link to comment
I've made multiplayer games before, but I haven't decided how I will do this one yet as it's more of a side project. My main project is a multiplayer PC game that can use Direct X 9 or 11. I think for pbbg, the game needs to be browser based, but I haven't done any browser based work since college.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now