Thread: OpenGL shooting game

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    176

    OpenGL shooting game

    I'm trying to make a game which allows the user to rotate a canon thats sitting at the center of my window and shoot whenever they like.

    Code:
    void rotate_canon(int direction)
    {
                    if ((direction == LEFT) && (canon_yaw < 90))
                    {
                            canon_yaw += 5;
                    }
                    else if ((direction == RIGHT) && (canon_yaw > -90))
                    {
                            canon_yaw -= 5;
                    }
                    else if ((direction == UP) && (canon_pitch < 90))
                    {
                            canon_pitch +=5;
                    }
                    else if ((direction == DOWN) && (canon_pitch > -90))
                    {
                            canon_pitch -=5;
                    }
    
                    draw_canon();
    }
    rotates the canon

    Code:
    void draw_canon()
    {
            /* Only redraw the part that is changing */
            glPushMatrix();
    
            glEnable(GL_SCISSOR_TEST);
            glScissor(0, TEXTHEIGHT, WIDTH, HEIGHT);
    
            glDisable(GL_SCISSOR_TEST);
    
            glMatrixMode(GL_PROJECTION);
    
            glLoadIdentity();
            glViewport(0, 0, WIDTH, HEIGHT);
            gluPerspective(45.0, 1.0, 1.0, 300.0);
    
            gluLookAt(
                    0.0, 0.0, 30.0,
                    0.0, 0.0, 0.0,
                    0.0, 1.0, 0.0);
    
            glRotatef(canon_pitch, 1.0, 0.0, 0.0);
            glRotatef(canon_yaw, 0.0, 1.0, 0.0);
    
            glBegin(GL_QUADS);
                    glColor3f(0.0, 0.0, 1.0);
    
                    /* canon front */
                    glVertex3f(-0.5, -0.5,  -1.5);
                    glVertex3f( 0.5, -0.5,  -1.5);
                    glVertex3f( 0.5,  0.5,  -1.5);
                    glVertex3f(-0.5,  0.5,  -1.5);
    
                    // canon back */
                    glVertex3f(-0.5, -0.5, -0.5);
                    glVertex3f(-0.5,  0.5, -0.5);
                    glVertex3f( 0.5,  0.5, -0.5);
                    glVertex3f( 0.5, -0.5, -0.5);
    
                    /* canon left */
                    glVertex3f(-0.5, -0.5,  0.5);
                    glVertex3f(-0.5,  0.5,  0.5);
                    glVertex3f(-0.5,  0.5, -2.0);
                    glVertex3f(-0.5, -0.5, -2.0);
    
                    /* canon right */
                    glVertex3f( 0.5, -0.5, -2.0);
                    glVertex3f( 0.5,  0.5, -2.0);
                    glVertex3f( 0.5,  0.5,  0.5);
                    glVertex3f( 0.5, -0.5,  0.5);
    
                    glColor3f(0.2, 0.0, 1.0);
    
                    /* canon top */
                    glVertex3f(-0.5,  0.5,  0.5);
                    glVertex3f( 0.5,  0.5,  0.5);
                    glVertex3f( 0.5,  0.5, -2.0);
                    glVertex3f(-0.5,  0.5, -2.0);
    
                    /* canon bottom */
                    glVertex3f(-0.5, -0.5,  0.5);
                    glVertex3f(-0.5, -0.5, -2.0);
                    glVertex3f( 0.5, -0.5, -2.0);
                    glVertex3f( 0.5, -0.5,  0.5);
            glEnd();
    
            glPopMatrix();
    
            glFlush();
    }
    draws the canon
    everything is working good so far.

    my question is, when the user clicks to fire....how can I find out where to draw a sphere that represents the canonball (front center of the gun is where?). and how can I determine a trajectory for the shot, so I will be able to update it, and have it seem like its moving.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    169
    You could keep a variable that holds the rotation degree, update it when the player rotates the cannon, and then use the current degree with the shoot() function

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    the rotate_canon function I posted updates 2 variables, holding the rotation degrees, canon_yaw and canon_pitch. what point do I use to rotate around?...since with a sphere those would just make it spin. And I still can't think of how I will figure out a trajectory for the canonball, other than maybe find a point on the back of the canon and one on the front and create a line. But if I could do that, I could draw the canonball correctly right off the bat

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well is this 2D or 3D?

    For the following equations your 'gun' must be centered around Gun.x and Gun.y.
    For 2D:

    Gun=gun position
    CannonBall=cannon ball position
    Offset=a location representing the end of the gun
    Angle=Rotation angle of the gun

    This is a simple parametric form of a line equation:

    Code:
    CannonBall.x=Gun.x+cosf(Angle)+Offset.x;
    CannonBall.y=Gun.y+sinf(Angle)+Offset.y;
    
    CannonBall.direction.x=cosf(Angle);
    CannonBall.direction.y=sinf(Angle);
    For 3D:

    matView - view matrix
    matCannonBallTrans - cannon ball translation matrix - relative to gun position
    matGunTrans

    Gun.right = right vector of gun
    Gun.up = up vector of gun
    Gun.look = look vector of gun

    Gun.fYaw = yaw angle of gun (radians)
    Gun.fPitch = pitch angle of gun (radians)
    Gun.fRoll = roll angle of gun (radians)

    In 3D if you take an object at local 0,0,0 and multiply it by the inverse of the camera view matrix you will move the 3D object to the camera position.

    Code:
    ...
    Matrix4x4 matView;
    Matrix4x4 matInvView;
    Matrix4x4 matGunTrans;
    Matrix4x4 matCannonBallTrans;
    Matrix4x4 matGunRotation;
    Matrix4x4 matWorld;
    
    
    matView=Camera->GetViewMatrix();
    
    MatrixInverse(&matInvView,&matView);
    
    //Compute gun pos
    Vector3 vecGunPos=Gun->GetWorldPosition();
    
    //Compute end of gun in world space
    float fGunLength=Gun->GetLength();
    Vector3 vecEndOfGun=Gun->GetLook()*fGunLength;
    
    
    //Create gun translation matrix
    MatrixTranslation(&matGunTrans,vecGunPos);
    
    //Create cannon ball translation matrix
    MatrixTranslation(&matCannonBallTrans,vecEndOfGun);
    
    //Now to display the gun in the correct orientation
    //Build the gun rotation matrix from the view matrix we've been given
    matGunRotation._11=matView._11;
    matGunRotation._12=matView._21;
    matGunRotation._13=matView._31;
    matGunRotation._14=0.0f;
    
    matGunRotation._21=matView._12;
    matGunRotation._22=matView._22;
    matGunRotation._23=matView._32;
    matGunRotation._24=0.0f;
    
    matGunRotation._31=matView._13;
    matGunRotation._32=matView._23;
    matGunRotation._33=matView._33;
    matGunRotation._34=0.0f;
    
    matGunRotation._41=vecGunPos.x;
    matGunRotation._42=vecGunPos.y;
    matGunRotation._43=vecGunPos.z;
    matGunRotation._44=1.0f;
    
    vecCannonBallDirection.z=Gun->GetLook().z;
    vecCannonBallDirection.y=Gun->GetUp().y;
    vecCannonBallDirection.x=Gun->GetRight().x;
    
    //Gun world matrix
    matWorld=matGunRotation*matGunTrans*matInvView;
    Gun->SetWorld(&matWorld);
    
    //Cannonball world matrix
    matWorld=matGunRotation*matCannonBallTrans;
    
    ...

    This code will put the camera at the gun position. The problem is you won't see the gun because you are inside of it. So you need to setup an object view mode in your camera class which will translate the camera away from the object prior to computing the final view matrix. Then once that is done you will see your gun.

    This code will compute the end of the gun and set the cannonball's position to that 3D point/vector and will also set the orientation of the cannonball as well as set the direction vector of the cannonball.

    Once you have your orientation class set up, you can move the cannonball with this code:

    Code:
    void CannonBall::Update(float fTimeDelta)
    {
      m_vecDirection+=vecLook*fSpeed*fTimeDelta;
    }
    This isn't the fastest code in the world and other may find some 3D math errors here but for the most part it is exactly what I'm doing in my 3D engine to achieve the same effect. I coded this from memory here so it may have some errors.

    Also OpenGL uses different 'handedness' matrices so you will have to ask some OpenGL guys here about the order of my matrices. Bob and psychopath can help you more with GL.

    I just tried to show the math here. As you can see for 3D you will need a matrix library that does basic matrix functions as well as a Vector3 class that operates on 3D vectors. You will also need a camera class, an object class, an orientation class, and other classes to get the system working.

    A 3D engine is a well-oiled machine with many many parts to it.

    You will run into gimbal lock with the code you have for your rotations.

    Here is a workaround for left handed matrices.
    Keep in mind this is for DirectX using the D3DX library so you will have to substitue in your own functions where D3DX functions and D3DX vectors are used. This class works in tandem with object classes so you may find some undefined references but I tried to code it as a standalone object.

    COrient3D.h
    Code:
    #pragma once
    
    #include "d3dx9.h"
    
    //Implements a 3D orientation class for all object
    //This class controls all vectors for the object
    //It currently uses euler angles
    //This class is very similar to a camera class, but it does not
    //compute view matrices
    
    enum OBJECT_TYPE
    {
      OBJECT_AIR,
      OBJECT_GND
    };
    
    class COrient3D
    {
      protected:
        D3DXVECTOR3 m_vecUp;
        D3DXVECTOR3 m_vecRight;
        D3DXVECTOR3 m_vecLook;
        D3DXVECTOR3 m_vecPos;
        OBJECT_TYPE m_iObjType;
        
        float m_fRoll;
        float m_fYaw;
        float m_fPitch;
        
        float m_fAzimuth;
        float m_fElevation;
        
        
      public:
        COrient3D(void);
        
        void GetLook(D3DXVECTOR3 *out_vecLook)    {*out_vecLook=m_vecLook;}
        void GetRight(D3DXVECTOR3 *out_vecRight)  {*out_vecRight=m_vecRight;}
        void GetUp(D3DXVECTOR3 *out_vecUp)        {*out_vecUp=m_vecUp;}
        void GetPosition(D3DXVECTOR3 *out_vecPos) {*out_vecPos=m_vecPos;}
        void GetViewMatrix(D3DXMATRIX *outMatrix);
        void GetViewMatrixAzEl(D3DXMATRIX *outMatrix);
        
        float GetPitch() {return D3DX_PI-m_fPitch;}
        float GetYaw() {return D3DX_PI-m_fYaw;}
        float GetRoll() {return D3DX_PI-m_fRoll;}
        
        float GetAzimuth() {return m_fAzimuth;}
        float GetElevation() {return m_fElevation;}
        
        D3DXVECTOR3 GetLook() {return m_vecLook;}
        D3DXVECTOR3 GetRight() {return m_vecRight;}
        D3DXVECTOR3 GetUp() {return m_vecUp;}
        D3DXVECTOR3 GetPosition() {return m_vecPos;}
        
        //Movement about the axes given current roll, pitch and yaw
        void Fly(float fUnits);
        void Strafe(float fUnits);
        void Walk(float fUnits);
           
        //Orientation
        void Roll(float fAngle);
        void Pitch(float fAngle);
        void Yaw(float fAngle);
        
        void MakeOrtho(void);
        
        
        void AdjustRoll(float fAngle) 
        {
          m_fRoll+=fAngle;
          //if (m_fRoll>D3DX_PI) m_fRoll-=D3DX_PI;
          //if (m_fRoll<=0) m_fRoll+=D3DX_PI;
        }
        void AdjustPitch(float fAngle) 
        {
          m_fPitch+=fAngle;
          //if (m_fPitch>D3DX_PI*2.0f) m_fPitch-=D3DX_PI*2.0f;
          //if (m_fPitch<0) m_fPitch+=D3DX_PI*2.0f;
          
          //if (m_fYaw>D3DX_PI) m_fPitch=D3DX_PI-m_fPitch;
          
        }
        void AdjustYaw(float fAngle) 
        {
          m_fYaw+=fAngle;
          //if (m_fYaw>D3DX_PI*2.0f) m_fYaw-=D3DX_PI*2.0f;
          //if (m_fYaw<0) m_fYaw+=D3DX_PI*2.0f;
        }
        
        
        
        
        void SetOrientation(float fRoll,float fPitch,float fYaw)
        {
          AdjustRoll(fRoll);
          AdjustPitch(fPitch);
          AdjustYaw(fYaw);
        }
        void Reset(void)
        {
          m_vecRight=D3DXVECTOR3(1.0f,0.0f,0.0f);
          m_vecUp=D3DXVECTOR3(0.0f,1.0f,0.0f);
          m_vecLook=D3DXVECTOR3(0.0f,0.0f,1.0f);
        }
        
        void SetPosition(D3DXVECTOR3 vecPos) {m_vecPos=vecPos;}
        void SetPosition(float x,float y,float z) {m_vecPos=D3DXVECTOR3(x,y,z);}
          
            
        OBJECT_TYPE GetObjectType() {return m_iObjType;}
        
        void SetObjectType(OBJECT_TYPE iNewType)
        {
          if (iNewType==OBJECT_AIR || iNewType==OBJECT_GND) 
          {
            m_iObjType=iNewType;
            return;
          } else m_iObjType=OBJECT_AIR;
          return;
       }
    };
    COrient3D.cpp
    Code:
    COrient3D::COrient3D()
    {
      m_vecRight=D3DXVECTOR3(1.0f,0.0f,0.0f);
      m_vecUp=D3DXVECTOR3(0.0f,1.0f,0.0f);
      m_vecLook=D3DXVECTOR3(0.0f,0.0f,1.0f);
      m_vecPos=D3DXVECTOR3(0.0f,0.0f,0.0f);
      m_iObjType=OBJECT_AIR;
      m_fYaw=0.0f;
      m_fRoll=0.0f;
      m_fPitch=0.0f;
      
      m_fAzimuth=0.0f;
      m_fElevation=0.0f;
      
    }
    
    void COrient3D::Fly(float fUnits)
    {
        if (m_iObjType==OBJECT_AIR)
          m_vecPos+=m_vecUp*fUnits;
    }
    
    void COrient3D::Strafe(float fUnits)
    {
      if (m_iObjType==OBJECT_GND)
        m_vecPos+=D3DXVECTOR3(m_vecRight.x,0.0f,m_vecRight.z)*fUnits;
    
      if (m_iObjType==OBJECT_AIR)
        m_vecPos+=m_vecRight*fUnits;
    }
    
    void COrient3D::Walk(float fUnits)
    {
      if (m_iObjType==OBJECT_GND)
         m_vecPos+=D3DXVECTOR3(m_vecLook.x,0.0f,m_vecLook.z)*fUnits;
    
      if (m_iObjType==OBJECT_AIR)
         m_vecPos+=m_vecLook*fUnits;
    }
           
    
    void COrient3D::Roll(float fAngle)
    {
      m_fRoll+=fAngle;
      if (m_fRoll>(D3DX_PI*2.0f)) m_fRoll-=(D3DX_PI*2.0f);
      if (m_fRoll<0.0f) m_fRoll+=(D3DX_PI*2.0f);
      
      D3DXMATRIX T;
      D3DXMatrixRotationAxis(&T,&m_vecLook,fAngle);
    
      D3DXVec3TransformCoord(&m_vecRight,&m_vecRight,&T);
      D3DXVec3TransformCoord(&m_vecUp,&m_vecUp,&T);
    
    }
    
    void COrient3D::Pitch(float fAngle)
    {
      m_fPitch+=fAngle;
      if (m_fPitch>(D3DX_PI*2.0f)) m_fPitch-=(D3DX_PI*2.0f);
      if (m_fPitch<0.0f) m_fPitch+=(D3DX_PI*2.0f);
      
      D3DXMATRIX T;
      D3DXMatrixRotationAxis(&T,&m_vecRight,fAngle);
    
      D3DXVec3TransformCoord(&m_vecUp,&m_vecUp,&T);
      D3DXVec3TransformCoord(&m_vecLook,&m_vecLook,&T);
    
    }
    
    void COrient3D::Yaw(float fAngle)
    {
      m_fYaw+=fAngle;
      if (m_fYaw>(D3DX_PI*2.0f)) m_fYaw-=(D3DX_PI*2.0f);
      if (m_fYaw<0.0f) m_fYaw+=(D3DX_PI*2.0f);
      
      D3DXMATRIX T;
    
      if (m_iObjType==OBJECT_GND) D3DXMatrixRotationY(&T,fAngle);
      if (m_iObjType==OBJECT_AIR) D3DXMatrixRotationAxis(&T,&m_vecUp,fAngle);
    
      D3DXVec3TransformCoord(&m_vecRight,&m_vecRight,&T);
      D3DXVec3TransformCoord(&m_vecLook,&m_vecLook,&T);
    
    }
    
    void COrient3D::MakeOrtho(void)
    {
      D3DXVec3Normalize(&m_vecLook,&m_vecLook);
      
      D3DXVec3Cross(&m_vecUp,&m_vecLook,&m_vecRight);
      D3DXVec3Normalize(&m_vecRight,&m_vecRight);
    
      D3DXVec3Cross(&m_vecRight,&m_vecUp,&m_vecLook);
      D3DXVec3Normalize(&m_vecLook,&m_vecLook);
    }
    
    
    void COrient3D::GetViewMatrix(D3DXMATRIX *outMatrix)
    {
      
      D3DXVec3Normalize(&m_vecLook,&m_vecLook);
      
      D3DXVec3Cross(&m_vecUp,&m_vecLook,&m_vecRight);
      D3DXVec3Normalize(&m_vecUp,&m_vecUp);
    
      D3DXVec3Cross(&m_vecRight,&m_vecUp,&m_vecLook);
      D3DXVec3Normalize(&m_vecRight,&m_vecRight);
    
      (*outMatrix)(0,0)=m_vecRight.x;
      (*outMatrix)(0,1)=m_vecRight.y;
      (*outMatrix)(0,2)=m_vecRight.z;
      (*outMatrix)(0,3)=0.0f;
    
      (*outMatrix)(1,0)=m_vecUp.x;
      (*outMatrix)(1,1)=m_vecUp.y;
      (*outMatrix)(1,2)=m_vecUp.z;
      (*outMatrix)(1,3)=0.0f;
    
      (*outMatrix)(2,0)=m_vecLook.x;
      (*outMatrix)(2,1)=m_vecLook.y;
      (*outMatrix)(2,2)=m_vecLook.z;
      (*outMatrix)(2,3)=0.0f;
      
    
      (*outMatrix)(3,0)=0.0f;
      (*outMatrix)(3,1)=0.0f;
      (*outMatrix)(3,2)=0.0f;
      (*outMatrix)(3,3)=1.0f;
      
      
    }
    
    void COrient3D::GetViewMatrixAzEl(D3DXMATRIX *outMatrix)
    {
      
      D3DXVec3Normalize(&m_vecLook,&m_vecLook);
      
      D3DXVec3Cross(&m_vecUp,&m_vecLook,&m_vecRight);
      D3DXVec3Normalize(&m_vecRight,&m_vecRight);
    
      D3DXVec3Cross(&m_vecRight,&m_vecUp,&m_vecLook);
      D3DXVec3Normalize(&m_vecLook,&m_vecLook);
    
      D3DXVECTOR3 vecPos=m_vecPos;
      
      (*outMatrix)(0,0)=m_vecRight.x;
      (*outMatrix)(0,1)=m_vecUp.x;
      (*outMatrix)(0,2)=sinf(m_fElevation)*cosf(m_fAzimuth);
      (*outMatrix)(0,3)=0.0f;
    
      (*outMatrix)(1,0)=m_vecRight.y;
      (*outMatrix)(1,1)=m_vecUp.y;
      (*outMatrix)(1,2)=sinf(m_fElevation)*sinf(m_fAzimuth);;
      (*outMatrix)(1,3)=0.0f;
    
      (*outMatrix)(2,0)=m_vecRight.z;
      (*outMatrix)(2,1)=m_vecUp.z;
      (*outMatrix)(2,2)=cosf(m_fElevation);
      (*outMatrix)(2,3)=0.0f;
      
    
      (*outMatrix)(3,0)=vecPos.x;
      (*outMatrix)(3,1)=vecPos.y;
      (*outMatrix)(3,2)=vecPos.z;
      (*outMatrix)(3,3)=1.0f;
      
        
    }
    Last edited by VirtualAce; 12-01-2006 at 07:12 PM.

  5. #5
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    For your trajectory, you could find the height of the point where the cannonball leaves the cannon with some basic trig. Of course, that assumes you know the vertical angle of the cannon.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yeah...or that. I just took the more complicated exact approach.

    For 2D trig will do everything you need. For 3D you will need much more.

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    its 3d, thanks for all the help, thats a huge post bubba, I got alot to read I guess. Thanks for putting in the time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Game Designer vs Game Programmer
    By the dead tree in forum Game Programming
    Replies: 8
    Last Post: 04-28-2005, 09:17 PM
  2. OpenGL Game Programming
    By KneeGrow in forum Game Programming
    Replies: 5
    Last Post: 11-14-2003, 03:29 PM
  3. Someone help me with this game??
    By stehigs321 in forum Game Programming
    Replies: 15
    Last Post: 10-30-2003, 09:42 PM
  4. Game Design Topic #1 - AI Behavior
    By TechWins in forum Game Programming
    Replies: 13
    Last Post: 10-11-2002, 10:35 AM
  5. want to play a useless shooting game i made?
    By Xterria in forum A Brief History of Cprogramming.com
    Replies: 25
    Last Post: 10-01-2002, 05:34 PM