Page 1 of 1

Make a text combat game in C++ plays like pokémon/final fantasy where you fight a monster Rate Topic: -----

#1 crazyjugglerdrummer  Icon User is offline

  • GAME OVER. NERD WINS.
  • member icon

Reputation: 119
  • View blog
  • Posts: 690
  • Joined: 07-January 09

Posted 18 March 2009 - 12:29 PM

Greetings Earthlies, this is crazyjugglerdrummer with the first in a hopefully long series of game tutorials. As mentioned in the title, this game plays something like pokémon, final fantasy, and many others I’m sure, making a combat system. This is all text based, but could later be adapted to run with fancier visual input/output. This is the beating heart of the program, the eyes, ears, and skin can be worked out later.

This game was my first real C++ project and I’ve been at it for a while. The first rewrite added object oriented techniques and the second rewrite fixed most of the object mistakes I’d make previously. The rewrites were horribly annoying as I had to completely reorganize the code and build it up almost from scratch again each time. I’m going to try to design these tutorials with as little of that as possible and a logical learning progression, so once code gets written, it shouldn’t have to be reorganized too much.

Every feature I wanted to add to the game required me to look in a new chapter of my C++ book, so this tutorial will compose of the apex of those efforts. I gradually added functions, then objects, then inheritance one after another. So to spare you the rewrites we are going to start with object-oriented code from the very beginning. These tutorials will use loops, functions, objects, inheritance, and vectors thoroughly (though this first tutorial will be simpler and not use all of them). Don’t let any of those scare you off! If you don’t understand any of them at all, look through some of the other tutorials here in this forum and come back to this when you have. This program is a good example of those and how to use them.


So, without further adieu, on to the actual program. We are going to make a combat system in which you fight a monster. Other tutorials will gradually add on to this, stuffing more features into the game. We need to have classes for monsters, characters, and the combat. These classes overlap profusely, so proper header files and implementations are essential. We are going to start with the Monster class as its the easiest.

So lets think of how to make a monster: What are the its properties? What does it do? How does it interact with other objects in the game? First we’ll need some variables for our monster to store our monster’s health, name, and damage. Name will be a string, and the other two will be integers. We need a method for the monster to attack a character, and a constructor that will set the instance variables. So know we have:

//monster.h
#ifndef Monster_h //header guards
#define Monster_h

#include <iostream>
using namespace std;

#include "Character.h" //we’ll make this in a second
#include “main.h”      //to be explained later
class Monster
    {
    public:
        string name;
        short health;
        short damage;

        Monster(string newName, int newHealth, int newDamage);
   
        void attack(Character&);
    };
#endif


Now we have a header file for our monster class with a constructor and an attack method.

Next we have to make the Character.h that we mentioned. This is going to look pretty much like the Monster class, except with a few extra features for the character.

//Character.h
#ifndef Character_h
#define Character_h

#include "Monster.h" //we just made this
#include "main.h"    //I’ll get to this (I promise)

#include <iostream>
using namespace std;

class Character
    {
    public:
        string name;
        short health;
        short damage;
        short arrows;

        Character(string newName);

        void attack(Monster& target);
       
        void rangedAttack(Monster& target);
    };
#endif


The extra method rangedAttack and variable arrows are to allow our character to attack in multiple ways, making the game more interesting.

Now we’re going to make a combat class, which will primarily serve to house all of our combat related methods and members. We need to contain the monster the character is fighting, while passing the character as a parameter (we’re going to pass the Character around the functions a lot). We have a combat1 function to contain the cycle of the combat and a combatChoice to display the options the character has available to them.

//Combat.h
#ifndef Combat_h
#define Combat_h

#include <iostream>
using namespace std;

#include "Character.h"
#include "Monster.h"

class Combat
    {public:
        Monster& M;
       
        Combat(Character& C);
       
        void combatChoice(Character& C);
       
        void combat1(Character& C);
    };
#endif


This class is going to be a little more complex than the others as it has a Monster address as an instance variable. We also have a constructor to implement which will initialize the Monster variable.


So now onto that main.h thing I mentioned. Since our Monster class includes the Character class and vice versa, one can’t be defined without the other. The compiler tries to define the first one, which can’t be defined because the first one hasn’t been defined. This leads to general confusion and a few “NOT DEFINED” errors. So we need to tell the compiler what they classes are so its header files can live happily ever after. So we make a simple header file, that will be implemented by the other header files.

#ifndef main_h
#define main_h

class Monster;
class Character;

#endif


Monster and Character are the only classes we really need here, as they are the only classes that include the file. The rest of the inclusions are normal.


So, now we can actually implement some stuff. Lets start with the Monster and its attack method. We need to subtract the monster’s damage from the Character’s health that we passed by reference, and display some information about what happened in the attack. We make a very simple constructor, that merely sets the instance variables to the arguments passed to it. So we have:

#include “Monster.h”

void Monster::attack(Character& target)
{
    target.health-=damage;
    cout << name << " attacks " << target.name << " doing " << damage << " damage!" << endl;
    cout << name << " health: " << health << endl;
}

Monster::Monster(string newname, int newHealth, int newDamage)
{
    name=newname;
    health=newHealth;
    damage=newDamage;
}


This should all be contained in a .cpp file, as it is the implementation for the monster.

Next, we create Character.cpp, with similar methods. We have an attack method, a similar ranged attack method, a display, and a constructor. The rangedAttack method will subtract its damage from the Monster’s health, then decrement the number of arrows the Character has. If the Character’s out of arrows, we display a message.

#include "Character.h"

void Character::attack(Monster& target)
{
    target.health-=damage;
    cout << name << " attacks the " << target.name << " doing " << damage << " damage!" << endl;
    cout << name << " health: " << health << endl;
}

void Character::rangedAttack(Monster& target)
{
    if (arrows == 0 )
        cout << name << " is out of arrows!" << endl;
    else
    {
        short rangedDamaged=3;
        target.health-=rangedDamaged;
        arrows--;
        cout << name << " shoots " << target.name << " doing " << rangedDamaged << " damage!" << endl;
    }
}

Character::Character(string newname)
{
    name=newname;
    health=100;
    damage=3;
    arrows=5;
}

void Character::display()
{
    cout << name << "  health: " << health << "  arrows: " << arrows << endl;
}


Notice that all the display statements that involve variables have a space before the next strings that is displayed, so the line doesn’t just show up as one big word.

Now we can implement the Combat class, which serves as the container for our combat members and functions. The combat constructor will simply initialize the Character’s opponent. Combat1 is just a loop that repeatedly has the monster attack the character, then gives the Character the chance to choose what to do next, by means of the combatchoice function. CombatChoice just uses a menu switch with two different options. We loop as long as one of the members of the combat is alive, and when one “dies” we display what occurred.

#include "Combat.h"
#include "Monster.h"
#include "Character.h"

Combat::Combat(Monster& newM) : M(newM)
{
}

void Combat::combatChoice(Character& C)
{
   
    C.display();
    cout << "What do you do? 1 attack, 2 fire arrow" << endl;
    short choice;
    cin >> choice;
    switch (choice)
    {
        case 1:
            C.attack(M);
            break;
           
        case 2:
            C.rangedAttack(M);
            break;
    }
}


void Combat::combat1(Character& C)
{
   
    while  (M.health>0 && C.health>0 )
    {
       
        M->attack©;
       
        combatChoice©;
       
    }
    if (M.health<0) //use -> for pointer
        cout << "Congratulations! You killed the monster!" << endl;
    if (C.health<0) //and use a dot for reference
        cout << "YOU HAVE DIED! GAME OVER" << endl;;
   
}


The Combat’s constructor may look a little weird, as it doesn’t have a body. All the constructor does is set the M instance variable to the address that gets passed to it. This is done in the style of an initializer list.

Last, but not least we have main, which is very simple as it makes a monster, constructs a combat from that monster, makes a character, and calls combat1 on that Character. (it doesn’t actually implement main.h)

#include <iostream>
using namespace std;

#include "Monster.h"
#include "Character.h"
#include "Combat.h"


Monster goblin("goblin",50,2);//declare Monster type outside of main


int main (int argc, char * const argv[]) {
   
    Character C("George"); //variable name C doesn’t matter as we pass by ref
   
    Combat combat(goblin);

    combat.combat1©;
   
    cout << “thanks for playing!” << endl;

    return 0;
}


We don’t really need iostream or the Monster.h and Character.h as they are included elsewhere and passed on to main, but we’ll include them anyway as some will be used anyway and its easier to keep track of what is used where when they are included specifically.

You can create the combat outside of main if you want, but in future tutorials we’ll be making specific combats and have more than one, so we create them inside main.

So there you have it, the basics of a simple combat game! I hope this you’ve enjoyed this tutorial and that is has been helpful! If it hasn’t (and you have constructive criticism to make) or any other comments, questions, concerns, please post them here. Thanks for reading!

Happy Coding! :)

Stay tuned for the next tutorial where we add random numbers to the combat system. Later, we will design an item system with weapons, spells, and healing items. We will add inheritance, inheriting both Character and Monster from a Being class. There will also be extensive uses of vectors, so brush up on those for the next part!

Note: Future tutorials may be posted in Game Programming forum

*** MOD EDIT: Per request of crazyjugglerdrummer

This post has been edited by JackOfAllTrades: 31 March 2009 - 05:52 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Make a text combat game in C++

#2 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3106
  • View blog
  • Posts: 19,145
  • Joined: 14-September 07

Posted 31 March 2009 - 02:53 PM

Maybe this should go into the Games Programming section since it's a planned series? I like it!
Was This Post Helpful? 0
  • +
  • -

#3 crazyjugglerdrummer  Icon User is offline

  • GAME OVER. NERD WINS.
  • member icon

Reputation: 119
  • View blog
  • Posts: 690
  • Joined: 07-January 09

Posted 31 March 2009 - 05:13 PM

Thanks KYA! I will probably post this as well as future tutorials in the Game Programming section, I was hovering between the two as it was both game programming, and C++. :)
Was This Post Helpful? 0
  • +
  • -

#4 crazyjugglerdrummer  Icon User is offline

  • GAME OVER. NERD WINS.
  • member icon

Reputation: 119
  • View blog
  • Posts: 690
  • Joined: 07-January 09

Posted 10 June 2009 - 08:19 AM

Part 2 Link
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1