int main() { // Since we use the ‘smooth’ animation algorithm, we must register it. motive::SmoothInit::Register(); // The engine is the central place for animation data. motive::MotiveEngine engine; // In this example, we animate a one-dimensional floating point value. motive::Motivator1f facing_angle; // Initialize facing_angle Motivator to animate as a 'Smooth' Motivator. // Alternatively, we could initialize as an 'Overshoot' Motivator. All // Motivator types have the same interface. Internally, they are animated // with different algorithms, and they will move differently towards their // targets. However, to switch between Motivator types it is a simple matter // of initializing with a different kind of MotiveInit struct. // // Angles wrap around with modular arithmetic. That is, -pi is equivalent to // pi. Valid range for angles is -pi..pi, inclusive of +pi and exclusive of // -pi. const motive::SmoothInit init(Range(-kPi, kPi), true); facing_angle.Initialize(init, &engine); // Set initial state of the Motivator, and the target parameters. // 'Smooth' Motivators animate to a target-value in a target-time. Not all // types of Motivators use all target data. const Angle start = Angle::FromDegrees(120.0f); const float start_angular_velocity = 0.0f; const Angle target = Angle::FromDegrees(-120.0f); const float target_angular_velocity = 0.0f; const motive::MotiveTime target_time = 100; const motive::MotiveTime delta_time = 1; facing_angle.SetTarget( motive::CurrentToTarget1f(start.ToRadians(), start_angular_velocity, target.ToRadians(), target_angular_velocity, target_time)); std::vector<vec2> points(target_time / delta_time + 1); for (motive::MotiveTime t = 0; t <= target_time; t += delta_time) { // All Motivators created with 'engine' are animated here. engine.AdvanceFrame(delta_time); // The current value of the variable being animated is always available. const Angle angle_at_t = Angle::FromWithinThreePi(facing_angle.Value()); points.push_back( vec2(static_cast<float>(t), angle_at_t.ToDegrees())); } printf("\n%s", Graph2DPoints(&points[0], points.size()).c_str()); return 0; }
int main() { // Since we will be using the ‘smooth’ animation algorithm, we must register it // with the engine. motive::SmoothInit::Register(); // The engine is the central place where animation data is stored and processed. motive::MotiveEngine engine; // In this example, we animate a one-dimensional floating point value. // It's also possible to animate a mathfu::vec2 with motive::Motivator2f, and // similarly for higher dimensional vectors. We can even animate a mathfu::mat4 // (a 4x4 matrix) with motive::MotivatorMatrix4f. // // If you have your own math library, you can also animate those instead of // mathfu types. See [Using Your Own Math Types][]. motive::Motivator1f facing_angle; // Initialize facing_angle Motivator to animate as a 'Smooth' Motivator. // Alternatively, we could initialize as an 'Overshoot' Motivator. All // Motivator types have the same interface. Internally, they are animated // with different algorithms, and they will move differently towards their // targets. However, to switch between Motivator types it is a simple matter // of initializing with a different kind of MotiveInit struct. // // Angles wrap around with modular arithmetic. That is, -pi is equivalent to // pi. Valid range for angles is -pi..pi, inclusive of +pi and exclusive of // -pi. const motive::SmoothInit init(Range(-kPi, kPi), true); facing_angle.Initialize(init, &engine); // Set initial state of the Motivator, and the target parameters. // 'Smooth' Motivators animate to a target-value in a target-time. Not all // types of Motivators use all target data. const Angle start = Angle::FromDegrees(120.0f); const float start_angular_velocity = 0.0f; const Angle target = Angle::FromDegrees(-120.0f); const float target_angular_velocity = 0.0f; const motive::MotiveTime target_time = 100; const motive::MotiveTime delta_time = 1; facing_angle.SetTarget( motive::CurrentToTarget1f(start.ToRadians(), start_angular_velocity, target.ToRadians(), target_angular_velocity, target_time)); std::vector<vec2> points(target_time / delta_time + 1); for (motive::MotiveTime t = 0; t <= target_time; t += delta_time) { // That is, all Motivators created with 'engine' are animated here. engine.AdvanceFrame(delta_time); // The current value of the variable being animated is always available. // Additionally, we can also access facing_angle.Velocity() for the angular // velocity. const Angle facing_angle_at_time_t(facing_angle.Value()); points.push_back( vec2(static_cast<float>(t), facing_angle_at_time_t.ToDegrees())); } printf("\n%s", Graph2DPoints(&points[0], points.size()).c_str()); return 0; }
void Ball::Update() { Vector2* prevPosition = new Vector2(ballPosition->X, ballPosition->Y); Vector2* v = new Vector2( ballDirection->ToDegrees() ); v->Multiply( ballVelocity ); ballPosition->Add( v ); delete v; if( ballPosition->X < gameArena->Player1WallX ) { ballPosition->X = gameArena->Player1WallX - (ballPosition->X - gameArena->Player1WallX); if( ballDirection->ToDegrees() < 180.0f ) { ballDirection->Add( ballDirection->ShortestAngleTo(90.0f) * -2.0f ); } else { ballDirection->Add( (270.0f - ballDirection->ToDegrees()) * 2.0f ); } // Hurt Player 1 if( gameArena->Player1 != 0 ) { gameArena->Player1->TakeDamage( 2 ); } } if( ballPosition->X >= gameArena->Player2WallX ) { ballPosition->X -= ballPosition->X - gameArena->Player2WallX; if( ballDirection->ToDegrees() > 270.0f ) { ballDirection->Add( ballDirection->ShortestAngleTo(270.0f) * -2.0f ); } else { ballDirection->Add( 180.0f - (ballDirection->ToDegrees() * 2.0f) ); } // Hurt player 2 if( gameArena->Player2 != 0 ) { gameArena->Player2->TakeDamage( 2 ); } } if( ballPosition->Y < gameArena->RoofY ) { ballPosition->Y = gameArena->RoofY - (ballPosition->Y - gameArena->RoofY); if( ballDirection->ToDegrees() < 270.0f ) { ballDirection->Add( ballDirection->ShortestAngleTo(180.0f) * -2.0f ); } else { ballDirection->Add( (360.0f - ballDirection->ToDegrees()) * 2.0f ); } } if( ballPosition->Y >= gameArena->FloorY ) { ballPosition->Y -= ballPosition->Y - gameArena->FloorY; if( ballDirection->ToDegrees() > 90.0f ) { ballDirection->Add( ballDirection->ShortestAngleTo(180.0f) * 2.0f ); } else { ballDirection->Add( 360.0f - (ballDirection->ToDegrees() * 2.0f) ); } } // Check collisions with players Line* ballPath = new Line( prevPosition, ballPosition ); Line* pArea = 0; bool ballAdjustXLeft; if( ballDirection->ToDegrees() > 90.0f && ballDirection->ToDegrees() < 270.0f && gameArena->Player1 != 0 ) { ballPath->Points[0]->X -= ballRadius; ballPath->Points[1]->X -= ballRadius; ballAdjustXLeft = true; pArea = gameArena->Player1->GetCollisionLine(); } if( (ballDirection->ToDegrees() < 90.0f || ballDirection->ToDegrees() > 270.0f) && gameArena->Player2 != 0 ) { ballPath->Points[0]->X += ballRadius; ballPath->Points[1]->X += ballRadius; ballAdjustXLeft = false; pArea = gameArena->Player2->GetCollisionLine(); } if( pArea != 0 ) { Vector2* pContact = ballPath->GetIntersection( pArea ); if( pContact != 0 ) { /* if( ballDirection->ToDegrees() < 180.0f && ballDirection->ToDegrees() > 90.0f ) { ballDirection->Add( ballDirection->ShortestAngleTo(90.0f) * -2.0f ); ballPosition->X += (pContact->X - ballPosition->X) * 2.0f; } else if( ballDirection->ToDegrees() >= 180.0f && ballDirection->ToDegrees() < 270.0f ) { ballDirection->Add( (270.0f - ballDirection->ToDegrees()) * 2.0f ); ballPosition->X += (pContact->X - ballPosition->X) * 2.0f; } else if( ballDirection->ToDegrees() > 270.0f ) { ballDirection->Add( ballDirection->ShortestAngleTo(270.0f) * -2.0f ); ballPosition->X -= (ballPosition->X - pContact->X) * 2.0f; } else if( ballDirection->ToDegrees() < 90.0f ) { ballDirection->Add( 180.0f - (ballDirection->ToDegrees() * 2.0f) ); ballPosition->X -= (ballPosition->X - pContact->X) * 2.0f; } */ Angle* a = pArea->Reflection( ballPath ); ballDirection->Set( a->ToDegrees() ); ballPosition->X += (!ballAdjustXLeft ? (pContact->X - ballRadius - ballPosition->X) * 2.0f : (ballPosition->X - ballRadius - pContact->X) * -2.0f); delete a; } } delete pArea; delete ballPath; delete prevPosition; }