Allegro Game Won't Fire 2D Projectile

Daniel Lopez
  • Allegro Game Won't Fire 2D Projectile Daniel Lopez

    To begin with I am developing a PSP application so I have no clue how to debug a PSP application. That doesn't mean I do not know how debug period. Anyway, when I run the game everything runs fine but when I press the X button on the PSP I see no bullet being drawn or updated on the screen. I know the problem doesn't lie with the pad because I press start and it exits my game so I do not think it is the pad that is causing the problem. Maybe the bullet is being drawn out of the screen already. But I am not sure since I cannot debug maybe somebody can see the flaw in my code. main.cpp

    class Missile
    {
        private:
            static const double angle = (3.14159265358979323846 / 2);
        public:
            bool Alive;
            static const int V = 5;
            double X;
            double Y;
            void Init(bool alive, int x, int y)
            {
                Alive = alive;
                X = x;
                Y = y;
            }
            void Update()
            {
                Y -= V;
            }
            void Kill()
            {
                Alive = false;
            }
            void Draw(BITMAP* buffer, BITMAP* sprite)
            {
    
                draw_sprite(buffer, sprite, X, Y);
            }
    };
    std::vector<Missile*>* bullets = new std::vector<Missile*>();
    void FireBullet(Ship* s)
    {
            if (bullets->size() < Constants::MAXBULLETS)
            {
                Missile* missile = new Missile();
                missile->Init(true, s->X, s->Y);
                bullets->push_back(missile);
            }
    }
    
    void CleanUp()
    {
        for(unsigned int index = 0; index < bullets->size(); index++)
        {
            if (bullets->at(index)->Alive == false)
            {
                bullets->erase(bullets->begin() + index);
            }
        }
    }
    void UpdateBullets()
    {
        for(unsigned int index = 0; index < bullets->size(); index++)
        {
            if (bullets->at(index)->Y < 0)
            {
                bullets->at(index)->Update();
            }
            else
            {
                bullets->at(index)->Kill();
            }
        }
    }
    void DrawBullets(BITMAP* buffer, BITMAP* sprite)
    {
        for(unsigned int index = 0; index < bullets->size(); index++)
        {
            if (bullets->at(index)->Alive == true)
            {
                bullets->at(index)->Draw(buffer, sprite);
            }
        }
    }
    //Entry point of the application
    int main(void)
    {   
    
        Ship* s = new Ship();
        int x = (WIDTH / 2) - 64;
        allegro_message("Initialzing ship class");
        s->Init(x);
        int frame = 0;
        BITMAP* buffer = NULL;
        BITMAP* background = NULL;
        BITMAP* ship = NULL;
        SceCtrlData pad;
        bool done = false;
        allegro_message("Initializing Game...");
        int rval = allegro_init();
        if (allegro_init() != 0)
        {
            allegro_message("Error initializing Game Because it returned: %i", rval);
            return 1;
        }
        allegro_message("Setting Graphics Mode...Press X To Begin Game. Default Missile count: %i", bullets->size());
        set_color_depth(32);
        int ret = set_gfx_mode(GFX_AUTODETECT,480,272,0,0);
        if (ret != 0)
        {
            allegro_message("Error setting grahpic mode! Because of it returned: %i", ret);
            return ret;
        }
        background = load_bmp("background.bmp", NULL);
        ship = load_bmp("ship.bmp", NULL);
        BITMAP* m = load_bmp("missile.bmp", NULL);
        if (background == NULL || ship == NULL || m == NULL){
            allegro_message("Couldn't load one or more sprites...");
            return 0;
        }
        buffer = create_bitmap(WIDTH, HEIGHT);
        if (buffer == NULL)
        {
            allegro_message("Couldn't create buffer!");
            return 0;
        }
        while(!done)
        {
    
            sceCtrlReadBufferPositive(&pad, 1); 
            if (pad.Buttons & PSP_CTRL_START)
            {
                done = true;
            }
            else if (pad.Buttons & PSP_CTRL_CROSS)
            {
                    FireBullet(s);
            }
            else if (pad.Buttons & PSP_CTRL_LEFT)
            {
                s->MoveLeft();
            }
            else if (pad.Buttons & PSP_CTRL_RIGHT)
            {
                s->MoveRight();
            }
            if (bullets->size() > 0)
            {
                UpdateBullets();
                CleanUp();
            }
            clear(buffer);
            draw_sprite(buffer, background, 0, 0);
            s->Draw(buffer, ship, frame);
            DrawBullets(buffer, m);
            masked_blit(buffer, screen, 0, 0, 0, 0, WIDTH, HEIGHT);
            if (frame == (60 * 10))
            {
                frame = 0;
            }
            frame++;
            vsync();
    
        }
        allegro_message("Clearing resources!");
        clear(buffer);  
        clear(ship);
        clear(background);
        clear(screen);
        allegro_message("Thank you for playing!");
        return 0;
    }
    END_OF_MAIN()
    

  • I see two problems right off the bat, the first has to do with the marked line below:

    void UpdateBullets()
    {
        for(unsigned int index = 0; index < bullets->size(); index++)
        {
            if (bullets->at(index)->Y < 0) //<-- HERE
            {
                bullets->at(index)->Update();
            }
            else
            {
                bullets->at(index)->Kill();
            }
        }
    }
    

    The origin for screen coordinates is the upper left corner of the screen, as such, the line if(bullets->at(index)->Y < 0) is always false, making every bullet fired immediately set Alive = false. Swapping the lines bullets->at(index)->Update(); and bullets->at(index)->Kill(); should fix the problem.

    The second issue is:

    int rval = allegro_init();
    if (allegro_init() != 0) {
    ...
    }
    

    Calling allegro_init() multiple times is ineffective, you are already storing the return value in rval so just check its value instead: if(rval != 0) { ... }

Tags
c++ 2d bullet-physics allegro
Related questions and answers
  • set_location(int X, int Y) { location[0] = X; location[1] = Y;}; bool Alive() {return alive;}; void SetLife(bool f) {alive= f;}; //////////////////////////////// Move //////////// bool move(int X, int Y) { location[0] += X; location[1] += Y; return true;}; };// end of sprite... line is needed; double refreshes= 0; int newlines= 0; const double speed= .1; int numb_coll= 0; bool dead= false; ///////////////////////// start of the for loop for (bool

  • i think i just found the solution. 1) the problem is that backbuffer surface and source surface are of different formats - that is why exception was thrown. 2) the image path needed double slash "C...: return DefWindowProc(hWnd, message, wParam, lParam); } } bool initDirect3D(void) { pD3D = NULL; pd3dDevice = NULL; // create the DirectX object if(NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION))) return false; std::wstring wsPath = L"C:\wood.bmp"; // path to the image D3DXIMAGE_INFO Info; if (FAILED(D3DXGetImageInfoFromFile(wsPath.c_str(), &amp;Info

  • () { } Cube::~Cube() { pBuffer-&gt;Release(); // why does this only work when put here? because it's created here? I thnk so, why not iBuffer though? } void Cube::Draw() { render_frame(); } void Cube...(pBackBuffer, NULL, &amp;rtv); pBackBuffer-&gt;Release(); // set the back buffer as the render target device-&gt;OMSetRenderTargets(1, &amp;rtv, dsv); D3D10_VIEWPORT viewport; // create a struct to hold... memcpy(pVoid, OurVertices, sizeof(OurVertices)); // copy the vertices to the buffer pBuffer-&gt;Unmap(); // create the index buffer out of DWORDs DWORD OurIndices[] = { 0, 1, 2, // side 1

  • ); // Set The Color Of The Model ( NEW ) // ORIGINAL DRAWING CODE //Draw the model as an interpolation between the two frames glBegin(GL_TRIANGLES); for(int i = 0; i...I am quite new to OpenGL, I have managed after long trial and error to integrate Nehe's Cel-Shading rendering with my Model loaders, and have them drawn using the Toon shade and outline... ) glColor3fv (&amp;outlineColor[0]); // Set The Outline Color ( NEW ) // HERE I AM PARSING THE VERTICES AGAIN (NOT IN THE ORIGINAL FUNCTION) FOR THE OUTLINE AS PER

  • every frame to handle input and render etc I call an UpdatePhysics method to update the physics simulation. void GameState::UpdatePhysics(unsigned int TDeltaTime) { World-&gt;stepSimulation(TDeltaTime... the rigid body object btRigidBody *RigidBody = new btRigidBody(0, MotionState, Shape, LocalInertia); // Store a pointer to the Ogre Node so we can update it later RigidBody-&gt;setUserPointer((void... btRigidBody *RigidBody = new btRigidBody(0, MotionState, Shape, LocalInertia); // Store a pointer to the Ogre Node so we can update it later RigidBody-&gt;setUserPointer((void *) (node)); // Add

  • new Object(); in the bottom part of the code sample. static BaseObject * CreateObjectFunc() { return new Object(); } How and where to delete the pointers? I wrote bool ReleaseClassType(). Despite the factory works well, ReleaseClassType() does not fix memory leaks. bool ReleaseClassTypes() { unsigned int nRecordCount = vFactories.size(); for (unsigned int nLoop = 0; nLoop &lt...;CreateObjectFunc<Object>; return true; } // create new object by calling the pointer to the appropriate type function BaseObject* create(unsigned int nObjectIDParam) const

  • { protected: Mix_Music *music; SDL_Surface *background; SDL_Surface *background2; vector<;Enemy> enemy; bool loaded; int time; public: Level(); virtual ~Level(); int bgX, bgY; int bg2X, bg2Y; int width, height; virtual void load(); virtual void unload(); virtual void update(); virtual void draw(); }; //level.cpp Level::Level... code in them... Right now for testing purposes, I just have the main loop call Level1 level1; and use the functions, but when I run the game I get a segmentation fault. This is the first time I've

  • wrong in my frame buffer set up code, or elsewhere. But I can't see what. The FBO is set up through the following function: unsigned int fbo_id; unsigned int depth_buffer; int m_FBOWidth, m_FBOHeight; unsigned int m_TextureID; void initFBO() { m_FBOWidth = screen_width; m_FBOHeight = screen_height; glGenRenderbuffers(1, &amp;depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER..., and an identity matrix for the view matrix (V). void drawBox(const Matrix4&amp; M) { const Matrix4 MVP = M * V * P; if (boundshader) { glUniformMatrix4fv((*boundshader)("MVP"), 1, GL_FALSE, &amp

  • : float m_Position[3]; // x, y, z // offset 0, size = 3*sizeof(float) float m_TexCoords[2]; // u, v // offset 3*sizeof(float), size = 2*sizeof(float) float m_Normal[3... in the shader code) for( int n = 0; n &lt; vShaderArgs.size(); n ++) glBindAttribLocation( m_nProgramId, n, vShaderArgs[n].sFieldName.c_str() ); // Create and bind to a vertex array object, which..._TRIANGLES, m_nNumIndices, GL_UNSIGNED_INT, ((char*)NULL + 0) ); glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY

Data information