OpenGL - 小行星克隆 - 从太空船射击子弹

时间:2014-10-27 22:54:19

标签: c++ opengl

我在弄清楚如何从宇宙飞船的前方射击子弹时遇到了一些困难。我可以将它绘制到屏幕上,但每次按下空格键时我都无法正确地弄清楚如何制作子弹。项目符号的if语句位于底部附近的update()方法中。

#include "Game.h"

Game::Game() 
    : mUColorProgram(0)
    , mVColorProgram(0)
    , mAsteroid(NULL)
    , mSpaceship(NULL)
    , mManualRotation(glm::radians(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;

    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),
    };

    VertexPositionColor spaceship[] = {
        VertexPositionColor(0.3f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.2f, 0.8f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.2f, -0.8f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),

        VertexPositionColor(1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.8f, 0.4f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.3f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),

        VertexPositionColor(1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.8f, -0.4f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),
        VertexPositionColor(-0.3f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f),

    };

    VertexPositionColor bullet[] = {
        VertexPositionColor(0.2f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f),
        VertexPositionColor(-0.1f, 0.1f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f),
        VertexPositionColor(-0.1f, -0.1f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f),
    };

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

    // 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;
    delete mBullet;

    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(mBulletTranslation);
    R = glsh::CreateRotationZ(glm::radians(0.0f));
    S = glsh::CreateScale(0.1f, 0.1f, 0.1f);
    glsh::SetShaderUniform("u_Transform", T * R * S);
    mBullet->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;
    }

    // Translation of spaceship
    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;
    }

    // Shoot bullet
    if (kb->keyPressed(glsh::KC_SPACE)) {
        // shoot bullet, modify mBulletTranslation

    }

    // 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;
}

0 个答案:

没有答案