How to make the player fire bullets

Started by
10 comments, last by Daivuk 13 years, 4 months ago
Hello, I don't know where to actually make player fire bullet. I guess I should some function called fire() in player class, but I must create a bullet and register that to both renderer class and phys class. I think the player class shouldn't know about those "upper" classes. Maybe I can implement a callback, but I dont believe thats a good practice of doing things.
How should I solve this problem and where actually should I register that bullet to my world :)

Thanks.
Advertisement
Well what you can have, is a service that the player can know about.

ProjectileService->SpawnBullet(position, velocity, this);

And that service knows how to register into the renderer or physic.

I would personally use an EntityManager. And when an entity is created, it holds a pointer to that EntityManager in his base class Entity. So this way you don't have anything global, and stay in context.

Hope that help
Pretty much as Daivuk describes, I have a global function InitEvent(int eventType, D3DXVECTOR3 p, D3DXVECTOR3 n). That function knows about bullets, rockets, explosions, etc., which the caller need know nothing about.

All that's needed is something similar to:

#include "enumEventTypes.h" // just a list of event types
extern void InitEvent(..<your argument list>..);

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Sorry for hijacking but Daivuk, can you explain more about the technique? Maybe some example in code?
Edge cases will show your design flaws in your code!
Visit my site
Visit my FaceBook
Visit my github
Without entering into too deep details because I would have to write pages or code here, I would create an EntityManager that reside in your world class or level class. The EntityManager is responsible for handling entity stuff. Like updating all entities, creating/deleting them, getting entities inside a radius (For region damage like grenade), etc.

And when creating an entity, a pointer of the EntityManager is kept within that entity so he can manipulate things, and create other entities.

The base Entity class could look like this:
class Entity{public:    Entity() {}    virtual ~Entity() {}        SetEntityManager(EntityManager* in_pEntityManager)     {        m_pEntityManager = in_pEntityManager;    }    virtual void Update(float deltaTime) {}    virtual void Render() {}protected:    EntityManager* m_pEntityManager;};



And your bullet and player derive from Entity. Because everything in your scene should derive from it anyway. And in the player's OnShoot function (How ever you trigger the shoot action) you can create the bullet entity using the pointer on the EntityManager.


Player class:
class Player : public Entity{public:    .....    void OnShoot()    {        // Create a bullet! With what ever parameters it needs        // The bullet here keep the pointer on this entity, so it knows        // not to hit me. (Little trick ;))        Bullet* pBullet = new Bullet(position, velocity, this);        // Register it into our entity manager        m_pEntityManager->RegisterEntity(pBullet);    }};




And in EntityManager::RegisterEntity(Entity* in_pEntity) function, you simply do in_pEntity->SetEntityManager(this).


EDIT: Forgot to mention that you will certainly have cross include here. Use forward declaration.
Seeing all these "manager"s making me hungry for coding them :)
But I lose myself while building the class-hierarchy instead of the game. So I was only able to finish my first game. I didn't even know about pointers that time ^^

Your solution is nicer but I did something similar and created a projectileManager which knows about the World and all mobiles have a pointer to that. It doesn't handle effects etc but thats enough for now I guess, thanks :)
@Daivuk Thanks for the reply. Would you mind explaining why this is more beneficial over say just doing this without entity manager? Also is this some type of paradigm? I've seen people use this xxxManager but I'm not sure how it all ties into the whole program. Sorry, I'm still learning.
Edge cases will show your design flaws in your code!
Visit my site
Visit my FaceBook
Visit my github
Sorry for the n00b question here, but Daivuk, what language are you coding in? I only know C++ and a tiny bit of C#, so when breaking the code down, it'd probably help me to know the language, lol
Quote:Original post by BGrizzMayne
Sorry for the n00b question here, but Daivuk, what language are you coding in? I only know C++ and a tiny bit of C#, so when breaking the code down, it'd probably help me to know the language, lol
It's C++. In addition to the code being C++ style he mentions "includes" and "forward declarations" which are also C++ concepts.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Quote:Original post by Concentrate
@Daivuk Thanks for the reply. Would you mind explaining why this is more beneficial over say just doing this without entity manager? Also is this some type of paradigm? I've seen people use this xxxManager but I'm not sure how it all ties into the whole program. Sorry, I'm still learning.


I named one of the benefits already: Region damage.
Having all entities sitting in a global manager (Or not global as the example I gave) is very beneficial to gather informations on other entities.

Let say I explode a grenade, and I want all entities in the radius to receive 75 damage. I would do something like this:
class Grenade : public Entity{ ...    void OnExplode()    {       vector<Entity*> touchedEntities;       m_pEntityManager->GetEntitiesInRadius(position, radius, touchedEntities);       for (vector<Entity*>::iterator it = touchedEntities.begin();             it != touchedEntities.end(); ++it)       {            Entity* pEntity = *it;            if (pEntity != this)            {                pEntity->Damage(75);            }        }    } ...};


A manager is just a convenient way to access and manage entities like that. It doesn't have to be like that. Your bullets can just be a global array. I coded for long like that, and it worked fine. It's just not as easy to maintain and add new features.

This topic is closed to new replies.

Advertisement