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