Thread: Bullet start locations on a sprite after rotation

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    54

    Bullet start locations on a sprite after rotation

    I am having trouble keeping my two start locations for bullets out of my sprite after it turns in any given direction.

    I just cant seem to get a grasp on the calculations I need to make in order to get the correct position. My best guess was the rotate the two points around the center point of the sprite by the sprites rotation value. however I havnt touched on linear algebra in a while to figure it out. Any tips?

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Translate to the gun location and perform the rotation in 2D.

    Code:
    float fNewX=(fGunPosX*cosf(angle))+(fGunPosY*sinf(angle));
    float fNewY=(fGunPosX*sinf(angle))-(fGunPosY*cosf(angle));
    or:
    X Y Z W
    X cosf sinf 0 0
    Y -sinf cosf 0 0
    Z 0 0 1 0
    W 0 0 0 1
    It's been awhile since I did this myself in matrix form or in 2D like that. My signs might be messed up.

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    Thanks bubba, im much closer now. It is just slightly off. as I rotate 180* the bullets end up a ship's width to the left and starting at the rear of the ship. Looks like it has to do with translating it back or the where it is when i rotate.

    Code:
    // Store the position of the bullet
    		tVector2D ptBulletPosition;
    
    		// Bullet position with respect to ship
    		ptBulletPosition.dX = m_nFocusPointOne.dX * m_fScale;
    		ptBulletPosition.dY = m_nFocusPointOne.dY * m_fScale;
    
    		// Rotate 
    		ptBulletPosition = Vector2DRotate(ptBulletPosition, m_fRotation);
    
    		// Translate to the location of the ship
    		ptBulletPosition.dX += m_dX;
    		ptBulletPosition.dY += m_dY;
    
    		// Set the x and y value
    		bullet->SetX(ptBulletPosition.dX);
    		bullet->SetY(ptBulletPosition.dY);

  4. #4
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    Code:
    // Rotates a vector in 2D Space.
    tVector2D Vector2DRotate(tVector2D vector, double dRadians)
    {
                    // Flip 1 due to windows coord system
    	vector.dY *= -1;
    
    	tVector2D vctRotated;
    	vctRotated.dX = cos(dRadians) * vector.dX + sin(dRadians) * vector.dY;
    	vctRotated.dY = -sin(dRadians) * vector.dX + cos(dRadians) * vector.dY;
    
                   // Flip 1 due to windows coord system
    	vctRotated.dY *= -1;
    
    	return vctRotated;
    }

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Start at the end of the gun. Or the chamber, if you want to be a bit more accurate. Or if you don't have a chamber because it's a laser or something, the end of the gun works I suppose...


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    Thats what im trying to get done. The m_nFocusPointOne is the location at the end of the barrel. However after rotating im having trouble keeping that position in the correct spot with the rotation

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    No sense of humor I see.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    hehe, I was wondering what the point of that was. Fustration after a long night of coding has my head shot

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ahh your problem is stemming from the fact that 0 degrees is to the right. You may have to subtract from ship's x pos and add to y pos. Work with them until you get it right because you are very close.

    It's either adding or subtracting from x and y ship pos. Mess with them a bit and watch what happens.

  10. #10
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    I see what your saying, but trying to change those messed up the starting pos of the bullets when I wasnt rotated. I tried all the combinations. The bullets start off in the correct position with the code above, but its when I rotate.

    Maybe Im adding to the wrong spots?

    Code:
    ptBulletPosition.dX = m_nFocusPointTwo.dX * m_fScale;
    		ptBulletPosition.dY = m_nFocusPointTwo.dY * m_fScale;
    		
    	///////////////////////////////////////////////////
    
    		// Translate to the location of the ship
    		ptBulletPosition.dX += m_dX;
    		ptBulletPosition.dY += m_dY;
    I tried on both those spots. Doing it to the position after caused it to be correct when it was rotated 180*, but the starting pos was off.

  11. #11
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    Got it! My problem was the fact I was setting the focus points with respect to the top left of the sprites rather than the center.

    Thanks for all the help

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    BTW just in case you might need a way to fire bullets 'at' a target:

    Code:
    //An extremely simple Vector2D object
    //Is just begging for operator support like addition, subtraction, etc, etc
    struct Vector2D
    {
      float x;
      float y;
      Vector2D(void):x(0.0f),y(0.0f) { }
      Vector2D(float sx,float sy):x(sx),y(sy) { }
      ...
      ...
    
    };
    
    //Computes direction vector from object to Target
    //CObject can be the base and CEnemy and CPlayer can be derived from CObject
    //This way you can maintain a list of CObject's and yet gain different functionality in the derived 
    //class
    void CObject::Target(Vector2D Target)
    {
      float fDiffx=m_Pos.x-Target.Pos.x;
      float fDiffy=m_Pos.y-Target.Pos.y;
      fDiffx*=fDiffx;
      fDiffy*=fDiffy;
      float fDist=sqrtf(fDiffx+fDiffy);
      m_FireVector.x=fDiffx/fDist;
      m_FireVector.y=fDiffy/fDist;
    }
    Code:
    //A simple bullet object
    struct Bullet
    {
      Vector2D vecPos;
      Vector2D vecDirection;
      float fSpeed;
    }
    
    
    //A class that manages a collection or list of bullet objects
    class BulletMgr
    {
      std::vector<Bullet *> m_vBullets;
      ...
      ...
      public:
       ... 
       void Update();
       ...
    };
    
    //Update all bullets in list according to direction and speed
    void BulletMgr::Update(void)
    {
      for (int i=0;i<iNumBullets;i++)
      {
        m_vBullets[i].Pos.x+=(m_vBullets[i].Direction.x*m_vBullets[i].fSpeed);
        m_vBullets[i].Pos.y+=(m_vBullets[i].Direction.y*m_vBullets[i].fSpeed);
      }
    }
    Note that I derived everything from CObject. As long as you put most of the important actions and functions in CObject, you can then derive from it to create different types of game objects.

    Then you can manage the entire game system using 1 class.

    Code:
    class CObject {};
    class CEnemy::public CObject {};
    class CPlayer::public CObject {};
    class CWhatever::public CObject {};
    
    class CObjectMgr
    {
      std::vector<CObject *> m_vGameObjects;
    
      public:
        ...
        int Add(CObject *pObject)
        {
           m_vGameObjects.push_back(pObject);
           return static_cast<int>(m_vGameObjects.size()-1);
        }
        ...
    };
    And then in your drawing class you can now do this:

    Code:
    class CRenderer
    {
       CObjectMgr *m_pObjectMgr;
       ...
    };
    You can delegate all drawing to each object by first putting:

    Code:
    virtual void Draw(void);
    Inside of the CObject base class and then iterating through the object manager list and calling draw for each one. Your overriden versions of draw for player, enemy, and whatever will be called if you override it. You can provide some base functionality in the base class draw to handle simple drawing of all objects. For objects that need more, you can put that in the derived class's draw() function.

    As you can see when you have the power of classes, STL, and DirectX/OpenGL - you can actually make a decent game framework in no time at all.

  13. #13
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    My best guess was the rotate the two points around the center point of the sprite by the sprites rotation value.
    that would be a good way to do it. This might help you brush up on your math: http://www.geocities.com/siliconvalley/2151/math2d.html

    /edit hmm, I wasn't seeing the any of the replys when I posted this....but you might still find the url helpful.
    Last edited by skorman00; 07-23-2006 at 03:13 PM.

  14. #14
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    I am trying to use your target method to make the tiefighters make suicide runs at the player. I simply add the vector found by that with the current vector of the tie fighter which is randomly generated on creation. I add the current vector with the target vector every frame. It seems to work when im lower and to the right of the tie fighter, but otherwise they fly off the screen.

    I just want to have them slowly follow the player, so if the player stops he will get hit.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. cannot start a parameter declaration
    By Dark Nemesis in forum C++ Programming
    Replies: 6
    Last Post: 09-23-2005, 02:09 PM
  2. Linked List Anamoly
    By gemini_shooter in forum C++ Programming
    Replies: 3
    Last Post: 02-28-2005, 05:32 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Next Question...
    By Azmeos in forum C++ Programming
    Replies: 3
    Last Post: 06-06-2003, 02:40 PM
  5. Need some help with a basic tic tac toe game
    By darkshadow in forum C Programming
    Replies: 1
    Last Post: 05-12-2002, 04:21 PM