1
\$\begingroup\$

I'm currently making space invaders and I'm using the game loop pattern as described here. I have an entity class from which there is a spaceship derived class. The base entity class contains all of the general entity data such as the x/y position, speed, etc...

Currently, I have the X and Y positions initialized to (0,0) so the spaceship is rendered in the center of the screen. I tried initializing the y position to a different coordinate corresponding to a position, but for some reason, the spaceship just keep moving vertically as if the y position is just being accumulated at each frame. I think the problem is caused by the fact that in my render() method of the spaceship class, I'm translating the modelmatrix with the x and y position of the spaceship as that would explain why there isn't vertical movement when the coordinates are (0,0). I'm not sure exactly if this is the proper way to structure the render() method but I couldn't think of another way to change the object's position. Below is the relevant code:

Spaceship class definition:

class Spaceship : public Entity {
public:
    Spaceship(float xDirect, float yDirect,
        float xPosition, float yPosition, float speed, float rState, ShaderProgram* program, SheetSprite newSprite, bool movingLeft, bool movingRight): 
        Entity(xDirect, yDirect, xPosition, yPosition, speed, rState, program, newSprite), movingLeft(movingLeft), movingRight(movingRight)
    {
        posY = 0.1;
    }

    virtual void Update(float elapsed) {
        // move stuff and check for collisions
        
        if (movingLeft) {
            posX -= elapsed* 0.001;
        }

        else if (movingRight) {
            posX += elapsed * 0.001;
        }
    }

    virtual void Render() {
        setOrthoProj();
        setObjMatrices();
        translateObj(posX, posY, 0.0);
        mySprite.Draw();
    }
    bool movingLeft;
    bool movingRight;
};

Initialization Code in main

Spaceship* spaceship = new Spaceship( 1.0f, 1.0f, -5.1f, 0.0f, 3.0f, 0.0f, program,mySprite, false, false);
    spaceship->Render();

Game Loop movement code

    const Uint8 *keys = SDL_GetKeyboardState(NULL);

    if (keys[SDL_SCANCODE_LEFT]) {
        spaceship->movingRight = false;
        spaceship->movingLeft = true;
        spaceship->Update(elapsed);

    }
    else if (keys[SDL_SCANCODE_RIGHT]) {
        spaceship->movingLeft = false;
        spaceship->movingRight = true;
        spaceship->Update(elapsed);
        
    }
    spaceship->Render();

For some reason, the first render() call outside of the loop isn't rendering the spaceship, only the one inside the loop works.

Given the structure of the program, what could be causing the problem?

EDIT

Translate method from Entity base class

void translateObj(float x, float y, float z) {
        posX = x;
        posY = y;
        modelMatrix.Translate(posX, posY, 0.0);
    }

void setObjMatrices() {
        glUseProgram(program->programID);
        program->setModelMatrix(modelMatrix);
        program->setProjectionMatrix(projectionMatrix);
        program->setViewMatrix(viewMatrix);

    }
\$\endgroup\$
1
\$\begingroup\$

You are on the right track.

Your problem is most likely here:

translateObj(posX, posY, 0.0);

You didn't post the code for that method but, from your description, you are translating the object by, and not to (posX, posY). When your objects move, they should replace the translation component of their world matrix.

Edit per your edit:

You want to modify the matrix as follows (sorry for DX style):

//Static method
modelMatrix = Matrix::CreateTranslation(posX, posY, 0.0f);

//or

//Simple enough to just store it
modelMatrix.Translation = Vector3(posX, posY, 0.0f);

Something like this:

virtual void Update(float elapsed)
{
    // move stuff and check for collisions
    if (movingLeft)
    {
        posX -= elapsed* 0.001;
        modelMatrixUpdated = true;
    }
    else if (movingRight)
    {
        posX += elapsed * 0.001;
        modelMatrixUpdated = true;
    }
}

virtual void Render()
{
    setOrthoProj();
    setObjMatrices();
    //translateObj(posX, posY, 0.0);
    mySprite.Draw();
}

//void translateObj(float x, float y, float z)
//{
    //posX = x;
    //posY = y;
    //modelMatrixUpdated = true;
//}

void setObjMatrices()
{
    glUseProgram(program->programID);
    if (modelMatrixUpdated)
    {
       //update or replace modelMatrix here
       modelMatrix.Translation = Vector3(posX, posY, 0.0f);
       modelMatrixUpdated = false;
    }
    program->setModelMatrix(modelMatrix);
    program->setProjectionMatrix(projectionMatrix);
    program->setViewMatrix(viewMatrix);
}
\$\endgroup\$
8
  • \$\begingroup\$ Thanks for the response. I just update the post with the code for the translateObj method. How should I change it to ensure that the translation component of the model matrix is being replaced? \$\endgroup\$ – loremIpsum1771 Mar 4 '16 at 5:00
  • 1
    \$\begingroup\$ @loremIpsum1771, if you still need help, please post the contents of the setObjMatrices() method. \$\endgroup\$ – Jon Mar 4 '16 at 5:47
  • \$\begingroup\$ Thanks, yeah I think that's essentially what I was doing, but I added the code for SetObjMatrices(). Also here is the link for the full program on github for reference. \$\endgroup\$ – loremIpsum1771 Mar 4 '16 at 21:01
  • \$\begingroup\$ @loremIpsum1771, I added one more code sample at the end. \$\endgroup\$ – Jon Mar 4 '16 at 21:27
  • \$\begingroup\$ I added the changes you included in your edit, but the problem persists. I think the issue has to do with the fact that in the translateObj function, I'm setting the entity's x and y positions to the amounts to be translated by instead of adding on to the current position. However, when I use += instead of = here, it seems that the object being drawn flies off the screen to quickly to even be seen since the position values (based on elapsed time) are accumulating to quickly I would think. \$\endgroup\$ – loremIpsum1771 Mar 6 '16 at 0:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.