Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Ball/Ball.cpp
- Committer:
- kocemax
- Date:
- 2019-05-09
- Revision:
- 15:40cf30a7a71b
- Parent:
- 13:3585d2ea4ff4
File content as of revision 15:40cf30a7a71b:
#include "Ball.h"
#include "Paddle.h"
#include <math.h>
Ball::Ball()
{
reset(); // initial parameters of ball
}
Ball::~Ball()
{
}
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);
}
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);
}
}
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;
}
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
}