C ++小行星克隆 - 宇宙飞船运动问题

时间:2014-10-27 20:29:00

标签: c++ opengl

我很难理解如何在小行星克隆中移动我的飞船。我可以沿着世界y轴​​移动它,但是当我旋转飞船时,它不会在它自己的相对y轴内向前移动。我已经评论了if语句用于宇宙飞船运动的代码。它位于update()方法的底部附近。谢谢你的任何建议。

#include "Game.h"

Game::Game() 
    : mUColorProgram(0)
    , mVColorProgram(0)
    , mAsteroid(NULL)
    , mSpaceship(NULL)
    , mManualRotation(0.0f)
    , mManualTranslation(0.0f, 0.0f, 0.0f)
    , mSpinnerAngle(0.0f)
    , mSpinnerAngularVelocity(glm::radians(90.0f))
    , mMinX(-1.0f)
    , mMinY(-1.0f)
    , mMaxX(1.0f)
    , mMaxY(1.0f)
    , mBouncerPosition(0.0f, 0.0f, 0.0f)
    , mBouncerVelocity(0.0f, 0.0f, 0.0f)
    , mMinScale(0.5f)
    , mMaxScale(5.0f)
    , mCurrScale(mMinScale)
    , mScalingSpeed(2.0f)
    , mBlendColor1(1.0f, 1.0f, 0.0f, 1.0f)
    , mBlendColor2(1.0f, 0.0f, 0.0f, 1.0f)
    , mAlpha(1.0f)
    , mBlendSpeed(-0.5f)
    , mBlendedColor(mAlpha * mBlendColor1 + (1 - mAlpha) * mBlendColor2)
{
    glsh::InitRandom();  // initialize random number generator

    mBouncerPosition.x = glsh::Random(mMinX, mMaxX);
    mBouncerPosition.y = glsh::Random(mMinY, mMaxY);

    float angle = glm::radians(glsh::Random(-180.0f, 180.0f));
    float speed = 0.75f;
    mBouncerVelocity.x = speed * std::cos(angle);
    mBouncerVelocity.y = speed * std::sin(angle);
}

Game::~Game()
{
}

void Game::initialize(int w, int h)
{
    // set clearing (background) color
    glClearColor(0.25f, 0.25f, 0.25f, 1.0f);

    // import some symbols from glsh namespace
    using glsh::VertexPositionColor;

    // define triangle mesh data (positions only)
    VertexPositionColor asteroid[] = {
        VertexPositionColor(0.0f, 0.40, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(0.0f, 0.4f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(-0.3f, 0.3f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(-0.4f, 0.0f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(-0.1f, -0.3f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(0.1f, -0.4f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(0.3f, -0.2f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(0.4f, 0.2f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
        VertexPositionColor(0.1f, 0.5f, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f),
    };

    // define quad mesh data (positions and colors)
    VertexPositionColor spaceship[] = {
        VertexPositionColor(0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.8f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(0.8f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(0.0f, 0.9f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.5f, -0.9f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(0.0f, -0.5f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(0.0f, 0.9f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(0.0f, -0.5f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(0.5f, -0.9f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),

    };

    // create meshes
    mAsteroid = glsh::CreateMesh(GL_TRIANGLE_FAN, asteroid, 9);
    mSpaceship = glsh::CreateMesh(GL_TRIANGLES, spaceship, 9);

    // build shader programs
    mUColorProgram = glsh::BuildShaderProgram("ucolor-vs.glsl", "ucolor-fs.glsl");
    mVColorProgram = glsh::BuildShaderProgram("vcolor-vs.glsl", "vcolor-fs.glsl");

}

void Game::shutdown()
{
    delete mAsteroid;
    delete mSpaceship;

    glUseProgram(0);
    glDeleteProgram(mUColorProgram);
    glDeleteProgram(mVColorProgram);
}

void Game::resize(int w, int h)
{
    glViewport(0, 0, w, h);
}

void Game::draw()
{
    glClear(GL_COLOR_BUFFER_BIT);

    // activate the per-vertex color shader program
    glUseProgram(mVColorProgram);

    T = glsh::CreateTranslation(mBouncerPosition);
    R = glsh::CreateRotationZ(mSpinnerAngle);
    S = glsh::CreateScale(0.1f, 0.1f, 0.1f);
    glsh::SetShaderUniform("u_Transform", T * R * S);
    mAsteroid->draw();

    T = glsh::CreateTranslation(mManualTranslation);
    R = glsh::CreateRotationZ(mManualRotation);
    S = glsh::CreateScale(0.1f, 0.1f, 0.1f);
    glsh::SetShaderUniform("u_Transform", T * R * S);
    mSpaceship->draw();
}

bool Game::update(float dt)
{
    const glsh::Keyboard* kb = getKeyboard();

    if (kb->keyPressed(glsh::KC_ESCAPE)) {
        return false; // exit
    }

    // Rotation of spaceship
    if (kb->isKeyDown(glsh::KC_LEFT)) {
        mManualRotation += 3.0f * dt;
    }
    else if (kb->isKeyDown(glsh::KC_RIGHT)) {
        mManualRotation -= 3.0f * dt;
    }

    // SPACESHIP MOVEMENT
    // Translation of spaceship
    if (kb->isKeyDown(glsh::KC_UP)) {
        mManualTranslation.y += 0.5f * dt;
    }
    else if (kb->isKeyDown(glsh::KC_DOWN)) {
        mManualTranslation.y -= 0.5f * dt;
    }


    // update spinner angle
    mSpinnerAngle += dt * mSpinnerAngularVelocity;

    // keep the angle in standard range
    if (mSpinnerAngle > 180.0f) {
        mSpinnerAngle -= 360.0f;
    } else if (mSpinnerAngle < -180.0f) {
        mSpinnerAngle += 360.0f;
    }


    // update bouncer position
    mBouncerPosition += dt * mBouncerVelocity;

    // bounce off of the horizontal boundaries of the screen
    if ((mBouncerVelocity.x > 0 && mBouncerPosition.x > mMaxX) ||
        (mBouncerVelocity.x < 0 && mBouncerPosition.x < mMinX))
    {
        mBouncerVelocity.x *= -1;
    }

    // bounce off of the vertical boundaries of the screen
    if ((mBouncerVelocity.y > 0 && mBouncerPosition.y > mMaxY) ||
        (mBouncerVelocity.y < 0 && mBouncerPosition.y < mMinY))
    {
        mBouncerVelocity.y *= -1;
    }

    return true;
}

1 个答案:

答案 0 :(得分:5)

您似乎在运动代码中缺少正弦和余弦函数。你目前使用mManualTranslation做的只是更新Y坐标,而我想你也希望宇宙飞船在水平轴上移动。要做到这一点,你必须使用正弦和余弦。

if (kb->isKeyDown(glsh::KC_UP)) {
    mManualTranslation.x += std::cos(mManualRotation) * 0.5f * dt;
    mManualTranslation.y += std::sin(mManualRotation) * 0.5f * dt;
}
else if (kb->isKeyDown(glsh::KC_DOWN)) {
    mManualTranslation.x -= std::cos(mManualRotation) * 0.5f * dt;
    mManualTranslation.y -= std::sin(mManualRotation) * 0.5f * dt;
}

另外请注意在使用角度度时要小心(因为你似乎在做),因为标准数学函数假设参数是弧度。