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@13:3585d2ea4ff4, 2019-05-09 (annotated)
- Committer:
- kocemax
- Date:
- Thu May 09 11:55:47 2019 +0000
- Revision:
- 13:3585d2ea4ff4
- Parent:
- 12:b3ec47d606a5
Hopefully final commit, since I probably fixed all the comments
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| kocemax | 2:006a2ddfabb6 | 1 | #include "Ball.h" |
| kocemax | 8:9b77eea95088 | 2 | #include "Paddle.h" |
| kocemax | 8:9b77eea95088 | 3 | #include <math.h> |
| kocemax | 2:006a2ddfabb6 | 4 | |
| kocemax | 2:006a2ddfabb6 | 5 | Ball::Ball() |
| kocemax | 2:006a2ddfabb6 | 6 | { |
| kocemax | 12:b3ec47d606a5 | 7 | reset(); // initial parameters of ball |
| kocemax | 2:006a2ddfabb6 | 8 | } |
| kocemax | 2:006a2ddfabb6 | 9 | |
| kocemax | 2:006a2ddfabb6 | 10 | Ball::~Ball() |
| kocemax | 2:006a2ddfabb6 | 11 | { |
| kocemax | 2:006a2ddfabb6 | 12 | } |
| kocemax | 2:006a2ddfabb6 | 13 | |
| kocemax | 7:cd3cafda3dd4 | 14 | void Ball::move() |
| kocemax | 7:cd3cafda3dd4 | 15 | { |
| kocemax | 6:39bda45efeed | 16 | GameObject::move(); |
| kocemax | 10:da5743dfb137 | 17 | |
| kocemax | 12:b3ec47d606a5 | 18 | // Right edge |
| kocemax | 7:cd3cafda3dd4 | 19 | if (pos.x > WIDTH-1) { |
| kocemax | 8:9b77eea95088 | 20 | velocity.x = -velocity.x; |
| kocemax | 8:9b77eea95088 | 21 | pos.x = WIDTH-1; |
| kocemax | 10:da5743dfb137 | 22 | } |
| kocemax | 12:b3ec47d606a5 | 23 | // Left edge |
| kocemax | 10:da5743dfb137 | 24 | else if(pos.x < 1) { |
| kocemax | 8:9b77eea95088 | 25 | velocity.x = -velocity.x; |
| kocemax | 8:9b77eea95088 | 26 | pos.x = 1; |
| kocemax | 2:006a2ddfabb6 | 27 | } |
| kocemax | 12:b3ec47d606a5 | 28 | // Top edge |
| kocemax | 7:cd3cafda3dd4 | 29 | if (pos.y < 1) { |
| kocemax | 8:9b77eea95088 | 30 | velocity.y = -velocity.y; |
| kocemax | 8:9b77eea95088 | 31 | pos.y = 1; |
| kocemax | 10:da5743dfb137 | 32 | } |
| kocemax | 12:b3ec47d606a5 | 33 | // Bottom edge |
| kocemax | 10:da5743dfb137 | 34 | else if (pos.y > HEIGHT-1) { |
| kocemax | 8:9b77eea95088 | 35 | velocity.y = -velocity.y; |
| kocemax | 8:9b77eea95088 | 36 | pos.y = HEIGHT-1; |
| kocemax | 2:006a2ddfabb6 | 37 | } |
| kocemax | 3:fe856d0890ee | 38 | } |
| kocemax | 3:fe856d0890ee | 39 | |
| kocemax | 8:9b77eea95088 | 40 | |
| kocemax | 8:9b77eea95088 | 41 | #define PI 3.14159265 |
| kocemax | 8:9b77eea95088 | 42 | float Deg2Rad = PI / 180; |
| kocemax | 8:9b77eea95088 | 43 | float Rad2Deg = 180 / PI; |
| kocemax | 8:9b77eea95088 | 44 | |
| kocemax | 12:b3ec47d606a5 | 45 | // NOTE: This is how our coordinate system is setup. |
| kocemax | 12:b3ec47d606a5 | 46 | // angles go clock-wise, right is zero, up is -pi/2, down is pi/2 |
| kocemax | 12:b3ec47d606a5 | 47 | // printf("angle of down: %.02f\n", atan2(1.f, 0)); |
| kocemax | 12:b3ec47d606a5 | 48 | // printf("angle of right: %.02f\n", atan2(0.f, 1)); |
| kocemax | 12:b3ec47d606a5 | 49 | // printf("angle of up: %.02f\n", atan2(-1.f, 0)); |
| kocemax | 8:9b77eea95088 | 50 | |
| kocemax | 13:3585d2ea4ff4 | 51 | // Standard rotation of a vector by given degrees |
| kocemax | 13:3585d2ea4ff4 | 52 | // Example of this function to play around with: https://repl.it/repls/HopefulTrimWordprocessing |
| kocemax | 8:9b77eea95088 | 53 | void Rotate(Vector2D& v, float degrees) |
| kocemax | 8:9b77eea95088 | 54 | { |
| kocemax | 12:b3ec47d606a5 | 55 | float s = (float)sin(degrees * Deg2Rad); // stores sin value betweem -1 and 1 |
| kocemax | 12:b3ec47d606a5 | 56 | float c = (float)cos(degrees * Deg2Rad); // stores cos value betweem -1 and 1 |
| kocemax | 8:9b77eea95088 | 57 | |
| kocemax | 12:b3ec47d606a5 | 58 | float tx = v.x; // 2D Vector (tx, ty) for the velocity |
| kocemax | 8:9b77eea95088 | 59 | float ty = v.y; |
| kocemax | 8:9b77eea95088 | 60 | |
| kocemax | 12:b3ec47d606a5 | 61 | // Rotation: Multiply vector by rotation matrix |
| kocemax | 8:9b77eea95088 | 62 | v.x = (c * tx) - (s * ty); |
| kocemax | 8:9b77eea95088 | 63 | v.y = (s * tx) + (c * ty); |
| kocemax | 8:9b77eea95088 | 64 | } |
| kocemax | 8:9b77eea95088 | 65 | |
| kocemax | 8:9b77eea95088 | 66 | /** Sets upper and lower boundary for angle |
| kocemax | 8:9b77eea95088 | 67 | * @return clamped angle between sane boundaries |
| kocemax | 8:9b77eea95088 | 68 | */ |
| kocemax | 8:9b77eea95088 | 69 | float clamp(float x, float minn, float maxx) |
| kocemax | 3:fe856d0890ee | 70 | { |
| kocemax | 8:9b77eea95088 | 71 | return min(max(x, minn), maxx); |
| kocemax | 8:9b77eea95088 | 72 | } |
| kocemax | 8:9b77eea95088 | 73 | |
| kocemax | 8:9b77eea95088 | 74 | |
| kocemax | 8:9b77eea95088 | 75 | void Ball::hitPad(Paddle &paddle) |
| kocemax | 8:9b77eea95088 | 76 | { |
| kocemax | 8:9b77eea95088 | 77 | const Vector2D& posPad = paddle.getPos(); |
| kocemax | 9:f720f5d87420 | 78 | if (pos.y >= posPad.y - 1 && (pos.x >= posPad.x && pos.x <= posPad.x + paddle.getW())) { |
| kocemax | 12:b3ec47d606a5 | 79 | // We hit the pad |
| kocemax | 8:9b77eea95088 | 80 | |
| kocemax | 12:b3ec47d606a5 | 81 | // First: rotate about paddle's surface normal (flip upward) |
| kocemax | 8:9b77eea95088 | 82 | velocity.y = -velocity.y; |
| kocemax | 8:9b77eea95088 | 83 | |
| kocemax | 12:b3ec47d606a5 | 84 | // Change angle based on distance to center |
| kocemax | 12:b3ec47d606a5 | 85 | float distanceSensitivity = 120; // Add at most this many degrees |
| kocemax | 12:b3ec47d606a5 | 86 | float maxDx = paddle.getW()/2; // Maximum distance from centre |
| kocemax | 12:b3ec47d606a5 | 87 | float cx = posPad.x + paddle.getW()/2.0f; // Maximum distance from current paddle centre |
| kocemax | 12:b3ec47d606a5 | 88 | float dx = pos.x - cx; // Positive dx means right of center, 0 means at center |
| kocemax | 8:9b77eea95088 | 89 | |
| kocemax | 12:b3ec47d606a5 | 90 | float dangle = dx/maxDx * distanceSensitivity; // Delta angle, meaning change in angle |
| kocemax | 12:b3ec47d606a5 | 91 | float currentAngle = atan2(velocity.y, velocity.x)*Rad2Deg; // Angle of our original outgoing velocity vector |
| kocemax | 12:b3ec47d606a5 | 92 | float newAngle = currentAngle + dangle; // The current angle + the change in the angle |
| kocemax | 8:9b77eea95088 | 93 | |
| kocemax | 8:9b77eea95088 | 94 | //printf("angle: %.02f %.02f, %.02f\n", dx, currentAngle, newAngle); |
| kocemax | 8:9b77eea95088 | 95 | |
| kocemax | 8:9b77eea95088 | 96 | |
| kocemax | 12:b3ec47d606a5 | 97 | // Always clamp angle in sane boundaries |
| kocemax | 12:b3ec47d606a5 | 98 | newAngle = clamp(newAngle, -160, -20); // Clamp to the range of an upward facing cone (NOTE: -90 degrees is up) |
| kocemax | 8:9b77eea95088 | 99 | |
| kocemax | 12:b3ec47d606a5 | 100 | // Rotate the outgoing vector by the clamped dangle |
| kocemax | 8:9b77eea95088 | 101 | dangle = newAngle - currentAngle; |
| kocemax | 8:9b77eea95088 | 102 | Rotate(velocity, dangle); |
| kocemax | 8:9b77eea95088 | 103 | |
| kocemax | 2:006a2ddfabb6 | 104 | } |
| kocemax | 2:006a2ddfabb6 | 105 | |
| kocemax | 6:39bda45efeed | 106 | } |
| kocemax | 6:39bda45efeed | 107 | |
| kocemax | 6:39bda45efeed | 108 | int Ball::randomize() |
| kocemax | 4:0e01cbb95434 | 109 | { |
| kocemax | 12:b3ec47d606a5 | 110 | AnalogIn noisy(PTB0); // Disconnected pin so will have random noise |
| kocemax | 12:b3ec47d606a5 | 111 | srand(1000000*noisy.read()); // Read the random noise and seed |
| kocemax | 12:b3ec47d606a5 | 112 | int direction = rand() % 2; // Randomise initial direction |
| kocemax | 12:b3ec47d606a5 | 113 | int movement; // Int to store the x-direction |
| kocemax | 7:cd3cafda3dd4 | 114 | if (direction == 0) { |
| kocemax | 6:39bda45efeed | 115 | movement = -1; |
| kocemax | 7:cd3cafda3dd4 | 116 | } else if (direction == 1) { |
| kocemax | 6:39bda45efeed | 117 | movement = 1; |
| kocemax | 6:39bda45efeed | 118 | } |
| kocemax | 7:cd3cafda3dd4 | 119 | return movement; |
| kocemax | 6:39bda45efeed | 120 | } |
| kocemax | 6:39bda45efeed | 121 | |
| kocemax | 7:cd3cafda3dd4 | 122 | void Ball::reset() |
| kocemax | 6:39bda45efeed | 123 | { |
| kocemax | 12:b3ec47d606a5 | 124 | pos.x = WIDTH/2; // initial position of ball on x-axis |
| kocemax | 12:b3ec47d606a5 | 125 | pos.y = HEIGHT - GAP - 2; // initial position of ball on y-axis |
| kocemax | 12:b3ec47d606a5 | 126 | velocity.x = randomize(); // initial x-velocity of ball |
| kocemax | 12:b3ec47d606a5 | 127 | velocity.y = -1; // initial y-velocity of ball |
| kocemax | 12:b3ec47d606a5 | 128 | w = 1; // width of the ball |
| kocemax | 12:b3ec47d606a5 | 129 | h = 1; // height of the ball |
| kocemax | 2:006a2ddfabb6 | 130 | } |