Kostadin Chakarov / Mbed 2 deprecated el17kec

Dependencies:   mbed

Ball/Ball.cpp

Committer:
kocemax
Date:
2019-05-09
Revision:
10:da5743dfb137
Parent:
9:f720f5d87420
Child:
12:b3ec47d606a5

File content as of revision 10:da5743dfb137:

#include "Ball.h"
#include "Paddle.h"
#include <math.h>

/** Constructor */
Ball::Ball()
{
    reset(); /** initial parameters of ball */
}

/** Destructor - nothing happens here */
Ball::~Ball()
{
}

/** Ball screen edge detection and movement */
void Ball::move()
{
    GameObject::move();
    
    /** Right edge */
    if (pos.x > WIDTH-1) {
        velocity.x = -velocity.x;
        pos.x = WIDTH-1;
    } 
    /** Left edge */
    else if(pos.x < 1) {
        velocity.x = -velocity.x;
        pos.x = 1;
    }
    /** Top edge */
    if (pos.y < 1) {
        velocity.y = -velocity.y;
        pos.y = 1;
    }
    /** Bottom edge */ 
    else if (pos.y > HEIGHT-1) {
        velocity.y = -velocity.y;
        pos.y = HEIGHT-1;
    }
}


#define PI 3.14159265
float Deg2Rad = PI / 180;
float Rad2Deg = 180 / PI;

/** NOTE: This is how our coordinate system is setup. */
/** angles go clock-wise, right is zero, up is -pi/2, down is pi/2 */
/** printf("angle of down: %.02f\n", atan2(1.f, 0)); */
/** printf("angle of right: %.02f\n", atan2(0.f, 1)); */
/** printf("angle of up: %.02f\n", atan2(-1.f, 0)); */

/** Standard rotation of a vector by given degrees */
/** Example of this function to play around with: https://repl.it/repls/HopefulTrimWordprocessing */
void Rotate(Vector2D& v, float degrees) 
{
    float s = (float)sin(degrees * Deg2Rad); /** stores sin value betweem -1 and 1 */
    float c = (float)cos(degrees * Deg2Rad); /** stores cos value betweem -1 and 1 */
     
    float tx = v.x;     /** 2D Vector (tx, ty) for the velocity */
    float ty = v.y;
    
    /** Rotation: Multiply vector by rotation matrix */
    v.x = (c * tx) - (s * ty);
    v.y = (s * tx) + (c * ty);
}

/** Sets upper and lower boundary for angle 
* @return clamped angle between sane boundaries 
*/
float clamp(float x, float minn, float maxx) 
{
    return min(max(x, minn), maxx);
}
 
 

/** Collision detection between ball and paddle */
void Ball::hitPad(Paddle &paddle)
{
    const Vector2D& posPad = paddle.getPos();
    if (pos.y >= posPad.y - 1 && (pos.x >= posPad.x && pos.x <= posPad.x + paddle.getW())) {
        /** We hit the pad */
        
        /** First: rotate about paddle's surface normal (flip upward) */
        velocity.y = -velocity.y;
        
        /** Change angle based on distance to center */
        float distanceSensitivity = 120;            /** Add at most this many degrees */
        float maxDx = paddle.getW()/2;              /** Maximum distance from centre */
        float cx = posPad.x + paddle.getW()/2.0f;   /** Maximum distance from current paddle centre */
        float dx = pos.x - cx;                      /** Positive dx means right of center, 0 means at center */
        
        float dangle = dx/maxDx * distanceSensitivity; /** Delta angle, meaning change in angle */
        float currentAngle = atan2(velocity.y, velocity.x)*Rad2Deg; /** Angle of our original outgoing velocity vector */
        float newAngle = currentAngle + dangle; /** The current angle + the change in the angle */
        
        //printf("angle: %.02f %.02f, %.02f\n", dx, currentAngle, newAngle);
        
        
        /** Always clamp angle in sane boundaries */
        newAngle = clamp(newAngle, -160, -20); /** Clamp to the range of an upward facing cone (NOTE: -90 degrees is up) */
        
        /** Rotate the outgoing vector by the clamped dangle */
        dangle = newAngle - currentAngle;
        Rotate(velocity, dangle);
        
    }

}

/** Randomizes the initial x-direction of the ball  */
int Ball::randomize()
{
    AnalogIn noisy(PTB0);           /** Disconnected pin so will have random noise */
    srand(1000000*noisy.read());    /** Read the random noise and seed */
    int direction = rand() % 2;     /** Randomise initial direction */
    int movement;                   /** Int to store the x-direction */
    if (direction == 0) {
        movement = -1;
    } else if (direction == 1) {
        movement = 1;
    }
    return movement;
}

/** Resets ball's initial parameters when game is over / lost */
void Ball::reset()
{
    pos.x = WIDTH/2;                /** initial position of ball on x-axis */
    pos.y = HEIGHT - GAP - 2;       /** initial position of ball on y-axis */
    velocity.x = randomize();       /** initial x-velocity of ball */
    velocity.y = -1;                /** initial y-velocity of ball */
    w = 1;                          /** width of the ball */
    h = 1;                          /** height of the ball */
}