我在弄清楚如何从宇宙飞船的前方射击子弹时遇到了一些困难。我可以将它绘制到屏幕上,但每次按下空格键时我都无法正确地弄清楚如何制作子弹。项目符号的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;
}