I am having a hard time understanding how to move my spaceship like in the asteroids clone. I can move it along the world y-axis but not move it forward within its own relative y-axis when I rotate the spaceship. I have commented the code where the if statement is for the spaceship movement. It's near the bottom in the update() method. Thanks for any advice.
#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;
}
You seem to be missing a sine and cosine function in the movement code. What you are currently doing with mManualTranslation
is just update the Y-coordinate, while I suppose you want the spaceship to move on the horizontal axis as well. To accomplish this, you have to use a sine and cosine.
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;
}
Also keep in mind to be careful when using degrees for angles (as you appear to be doing) since the standard math functions assume the argument to be in radians.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.