Thread: Design suggestions: interacting with game items

  1. #1
    The larch
    Join Date
    May 2006
    Posts
    3,573

    Design suggestions: interacting with game items

    I wonder if anyone can suggest a good idea how to model a player picking up or interacting with map items in a game.

    Some items would only affect the player (e.g make it faster, give it an amount of gold), others might affect something else in the game regardless of the player that collided into it (e.g make all enemies slower), others might affect the game world but with respect to the player (e.g place more gold around the player that picked up the item).

    Below is a small example what I tried but it doesn't seem to make much sense, or be extensible to allow arbitrary additional parameters (e.g how much gold) easily.

    (You choose the Item to interact with by entering 0, 1 or 2. Two players take turns.)

    Code:
    #include <iostream>
    #include <vector>
    #include <boost/shared_ptr.hpp>
    #include <boost/function.hpp>
    
    struct Player
    {
        void bar() { std::cout << "Player(" << n << ")::bar()\n"; }
        int n;
    };
    
    struct World
    {
        void foo() { std::cout << "World::foo()\n"; }
        void foobar(Player& p) { std::cout << "World::foobar()\n"; p.bar(); }
    };
    
    //overloads to select the first or the second of two different arguments
    template <class TargetT, class OtherT>
    TargetT& selector(TargetT& target, OtherT&)
    {
        return target;
    }
    
    template <class TargetT, class OtherT>
    TargetT& selector(OtherT&, TargetT& target)
    {
        return target;
    }
    
    class Item
    {
        public:
            virtual ~Item() {}
            virtual void on_pick(World& w, Player& b) = 0;
    };
    
    //Items store a suitable call-back function that is executed when "picked up"
    //ItemTargeting lets specify through template parameter whether the Item affects only World or Player.
    template <class TargetT>
    class ItemTargeting : public Item
    {
        public:
            ItemTargeting(boost::function<void (TargetT*)> fun): fun(fun) {}
            virtual void on_pick(World& w, Player& p)
            {
                fun(&selector<TargetT>(w, p));
            }
        private:
            boost::function<void (TargetT*)> fun;
    };
    
    class ItemTargetingWorldWithRespectToPlayer : public Item
    {
        public:
            ItemTargetingWorldWithRespectToPlayer(boost::function<void (World*, Player&)> fun): fun(fun) {}
            virtual void on_pick(World& w, Player& p)
            {
                fun(&w, p);
            }
        private:
            boost::function<void (World*, Player&)> fun;
    };
    
    
    int main()
    {
        typedef boost::shared_ptr<Item> PItem;
        std::vector<PItem> items;
        items.push_back(PItem(new ItemTargeting<World>(&World::foo)));
        items.push_back(PItem(new ItemTargeting<Player>(&Player::bar)));
        items.push_back(PItem(new ItemTargetingWorldWithRespectToPlayer(&World::foobar)));
        World w;
        Player p[2] = {1, 2};
        unsigned turn = 0;
        unsigned index;
        while (std::cin >> index && index < items.size()) {
            items[index]->on_pick(w, p[turn]);
            turn ^= 1;
        }
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Well a good design might be to assume that if the player collides with an item, he interacts with it, even if the resulting events doesn't involve the player. I assume that items would only do something after the player discovered them, anyway. In this way it is the world's responsibility to evoke the right action from the player.

    So however you decide to design the map really affects where the collisions are and what events are triggered afterward.

    Group items by their function rather than their relation to the player. You might have healing items that effect player's attributes, or items that award gold (treasure chests) for example, and need similar methods.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by anon View Post
    I wonder if anyone can suggest a good idea how to model a player picking up or interacting with map items in a game.

    Some items would only affect the player (e.g make it faster, give it an amount of gold), others might affect something else in the game regardless of the player that collided into it (e.g make all enemies slower), others might affect the game world but with respect to the player (e.g place more gold around the player that picked up the item).
    Have you considered using the Visitor Pattern?

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Quote Originally Posted by citizen View Post
    Well a good design might be to assume that if the player collides with an item, he interacts with it, even if the resulting events doesn't involve the player. I assume that items would only do something after the player discovered them, anyway. In this way it is the world's responsibility to evoke the right action from the player.
    So you are saying that items should interact with World (or Player only) which in turn would call the right functions in the Player (or World) rather than try to reach the correct receiver "automatically"?

    Group items by their function rather than their relation to the player. You might have healing items that effect player's attributes, or items that award gold (treasure chests) for example, and need similar methods.
    What I'm hoping to do is to keep the number of classes low and not have a separate class for each game item: for example, a TreasureChest and a HealingPotion would function in so similar ways that they could be differentiated by data only (call-back function, amount, different sprite etc) rather than as separate classes. (If anything more specific is needed, it might be added as an Item subclass.)

    Have you considered using the Visitor Pattern?
    Do you mean that the game items might be designed as visitors or do you have something different in mind?

    As I understand it, Visitor and double dispatch are useful if there are two unknowns involved (who picked up what), but as long as the Player is the only thing that is going to pick up items and there are no other actors who would do it and respond differently to the event, I don't see a need for double dispatch.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how do the game engine and the api interact?
    By Shadow12345 in forum Game Programming
    Replies: 9
    Last Post: 12-08-2010, 12:08 AM
  2. Open-source Game Project
    By Glorfindel in forum Projects and Job Recruitment
    Replies: 0
    Last Post: 03-24-2009, 01:12 AM
  3. game design from the non programming side
    By Scourfish in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 01-29-2002, 01:07 AM
  4. Anyone heard of FULL SAIL GAME DESIGN DEGREE?
    By marCplusplus in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 11-30-2001, 10:06 PM
  5. Im a Newbie with a graphics design problem for my simple game
    By Robert_Ingleby in forum C++ Programming
    Replies: 1
    Last Post: 11-23-2001, 06:41 PM