I got bored with the simple tic tac toe and rock paper scissors and decided I wanted to make a decently in-depth (but still REALLY simple) console RPG. Obviously it'll just have a linear story if any story at all and just some simple items and maybe basic skills besides attack. The part where I'm stuck in the thought process is just some concepts generally about items. I've got an items.h and items.cpp, but my question is where do I actually create all the items.. in items.cpp, or main.cpp and how does that work? I know most of the big games use databases, and get the info from there but that sounds a bit too complex. Would it be realistic to do something like that with a text file or .dat?
Also, in my items class, there's a variable, name. I originally had it as a char array but when using a function in the class to change the name, it tells me it must be a modifiable lvalue. I don't know what that means. When that happened I used strings instead but it seemed much more of a hassle than just trying to figure out the char arrays.
1 2 3 4 5 6 7 8
void Weapon::setInfo(int r, int p, int d, char n[], string de)
{
rare = r;
price = p;
damage = d;
name = n;
desc = de;
}
This is the class so far.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class Weapon
{
public:
void Weapon::setRarity(int);
void Weapon::getRarity();
void Weapon::getInfo();
void Weapon::setInfo(int, int, int, char[], std::string);
private:
int damage;
int rare;
char name[32];
int price;
std::string desc;
String is waaaaaaay better than using char arrays. You can organize your game like this:
Have a header file with the base classes in. For example, base class item would have stuff like price, rarity, name and so forth... Base classes would be stuff like class item and class monster.
Then create stuff like your weapon and armour classes by inheriting from this class item and monsters by inheritance from base class monster. You can read more about inheritance here: http://www.cplusplus.com/doc/tutorial/inheritance/
It's perfectly feasible to store and retrieve information from text files, in fact, some small games I have seen, do exactly this. To be honest, if I were doing this, I'd just declare everything in header files, but this is no necessarily the best or only approach.
If you need help with class inheritance or read/write from files then be sure to ask.
Pleeeeeeeeeeeeeeeeeeease finish the game because no-one ever finishes RPGs... :(
Good luck!
I'd just declare everything in header files, but this is no necessarily the best or only approach.
Right, this is the other option I thought would be better than just a list of the items in the .cpp file.. I just don't exactly understand what that means. I understood the concept of inheritance, creating the items was just where I was stuck. All I'm picturing is a list like
//Here is a quick, rudimentary example.
//Don't forget to make constructors and deconstructors.
class item
{
public:
int price; //It doesn't matter if every single item uses everything in here or not
int rarity; //Memory from unused ints is not going to be an issue.
string name;
};
class weapon: public item
{
public:
int damage;
};
//Pseudo code - Should be done with constructor
//But hopefully you get the idea.
weapon knife;
knife.damage = 3;
knife.cost = 5;
knife.rarity = 1;
knife.name = "knife";
weapon sword
sword.damage = 10;
sword.cost = 15;
sword.rarity = 3;
sword.name = "sword";
This is what the header file would look like.
As you can see, if we end up with 50 items inheriting from base class, it saves an awful lot of typing and confusion!
I'm learning so much from trying to do this, and I really appreciate your help. I got what you did there, and implemented it so far. When I tried using the constructor I ran into a couple errors. If I put it in the header file, I would get the object being multiply defined. Understandable, it would be defined in every file the .h was included in. When I put it in the .cpp I would get an error of it not being defined at all. The solution I found for this was to use
extern Weapon knife;
in the .h file, at the bottom but before the #endif, and put
Weapon knife(parameters);
in weapon's implementation file.
Is this the correct way to handle it?
Also, just a question about inheritance I couldn't find an answer to. Is a constructor inherited? If I have Weapon::Weapon(int stuff) in the base class weapon, and a Ranged::Ranged(int stuff) constructor in the inherited class Ranged, would they both function the same way? meaning I would just use Ranged bow(parameters);?
When I tried using the constructor I ran into a couple errors. If I put it in the header file, I would get the object being multiply defined. Understandable, it would be defined in every file the .h was included in.
hmm I've never seen this problem. I always make sure header files are only included once.
You can inherit constructors, although they are not by default. It's not something I've ever done, but so long as you're using an up to date compiler, it can be done. I'm not sure if it's recommendable or not tbh. You can see a neat example of it here though: http://en.wikipedia.org/wiki/C%2B%2B11#Object_construction_improvement
(scroll down just a little) ;)
I just included the header file in items.cpp and main.cpp, and that seemed to cause problem with multiply defining any objects created with constructors in the header file.
I mean, I got it to work with externing the objects.. but this seems like a bad way to do it. I'd have to do that for every single object (not really a big deal for a small project like this I guess) and I don't know how many objects I could have.
@Mats: The problem is not the include guards. The problem is, as TC said, that if he places global variables in a header file, then multiple source files are going to declare those variables which causes linker errors.
@TC: Using extern is the correct technique if you want to do this, but I would recommend the file idea over simply having a ton of globals as it is much more extensible.
@Mats No, the typo wasn't present in the file I just wrote that as I was typing out the reply.
@Zhuge Using the file idea, I was still going to have tons of globals.. the data for the globals would just be in the file the way I was planning it out. The constructor would get the info from the file based on an integer "id", and create an object with the data on that line of the file.
If items have an ID, you could make a map that associates an ID with an item record. That map could be filled out by reading a text file. It may be nontrivial if you are using inheritance to define your items, though. Depending on your system, it maybe be easier to just give all items the attributes of every kind of item (e.g. a cloak ay have a damage of 0 that isn't used because it is a piece of equipment, not a weapon).
On an unrelated note, I notice you have getters and setters for all the fields in your class. If those do nothing other than simply assign to/return the value of the variable, you may as well make them public.
I was planning to get rid basically all the get/sets and make the variables public, I just hadn't done it yet. Doing this as a learning experience, I was playing with the variables being private and protected.
For the ID's, I got it working with a text file of every item I have so far having an id at the beginning of its line and the constructor searching for the given ID in the text file, then reading the rest of that data on that line into the correct variables for the object. The ID is an argument for the constructor as a string type.
Absolutely. I'm learning as I go though, so it could take awhile. I came across something the other day, and would it be possible/a good idea to use a std::map for keeping track of the items?