1+ /* TODO (GamerMan7799#4#): Show path of each ball on the screen */
2+ /* FIXME (GamerMan7799#1#): The balls will become stuck together for seemingly random reasons */
3+ /* TODO (GamerMan7799#1#): Balls are different colors based on their IDS */
4+ /* TODO (GamerMan7799#1#): Balls are more transparent the less mass it has. */
15/* *********************************************************************************************************************************************************************/
26#include < SDL2/SDL.h>
37#include < cstdio>
1014#include " tick.h"
1115#include " config.h"
1216/* *********************************************************************************************************************************************************************/
13- void addNewCannonball (LOC, LOC);
17+ void addNewCannonball (LOC, LOC, double );
1418void checkForCollisons (uint);
1519bool checkCollide (BOX, BOX);
1620void doCollision (uint, uint);
@@ -36,17 +40,18 @@ namespace Global {
3640 // Friction values based on Concrete and Steel
3741 const float fKineticFriction = 0.36 ;
3842 const float fDensityAir = 1.2754 ; // Density of air
39- const float fRecoil = -0.56 ; // the mulitplier of the velocity when a ball hits the walls / floor
43+ const float fRecoil = -0.56 ; // the multiplier of the velocity when a ball hits the walls / floor
4044 const float fVelocityScalar = 1 ; // Changing this effects the fire velocity
4145 const float fMinVelocity = 0.0 ; // If a ball has less velocity than the it will "die"
4246 const float fCoefficientRestitution = 0.76 ; // How much total energy remains after a collision
4347 // (see https://en.wikipedia.org/wiki/Coefficient_of_restitution for more info
48+ const float fTimetoSizeRatio = 1.2458 ; // One second of holding down the mouse button = this many meters for the ball
4449 const uchar CollisionMethod = CollideInelastic;
4550 }
4651}
4752/* *********************************************************************************************************************************************************************/
4853// This is the maximum number of cannonballs which can be "alive" at a time
49- #define DEFINED_CANNONBALL_LIMIT 10
54+ #define DEFINED_CANNONBALL_LIMIT 20
5055/* *********************************************************************************************************************************************************************/
5156clsCannonball Cannonballs[DEFINED_CANNONBALL_LIMIT];
5257/* *********************************************************************************************************************************************************************/
@@ -79,21 +84,22 @@ int main(int argc, char *argv[]) {
7984 else if ( event.type == SDL_MOUSEBUTTONUP ) {
8085 holding = false ;
8186 if (Global::blnDebugMode) {printf (" Mouse button up\n " );}
82- addNewCannonball (CurrentMouse, OldMouse);
87+ addNewCannonball (CurrentMouse, OldMouse, Tick. stopHolding () );
8388 } else if ( event.type == SDL_MOUSEMOTION && holding) {
8489 // Draw the line
8590 SDL_GetMouseState (&CurrentMouse.x , &CurrentMouse.y );
8691 if (Global::blnDebugMode) {printf (" Mouse found at (%d,%d)\n " ,CurrentMouse.x ,CurrentMouse.y );}
8792 } else if ( event.type == SDL_MOUSEBUTTONDOWN ) {
8893 holding = true ;
94+ Tick.startHolding ();
8995 SDL_GetMouseState (&OldMouse.x , &OldMouse.y );
9096 CurrentMouse = OldMouse;
9197 if (Global::blnDebugMode) {printf (" Mouse Button down at (%d,%d)\n " ,OldMouse.x ,OldMouse.y );}
9298 } else if ( event.type == SDL_KEYDOWN ) {
9399 switch ( event.key .keysym .sym ) {
94100 case SDLK_k:
95101 // kill all the balls
96- for (uint i = 0 ; i < DEFINED_CANNONBALL_LIMIT; i++) {Cannonballs[i].blnstarted = false ;}
102+ for (uint i = 0 ; i < DEFINED_CANNONBALL_LIMIT; i++) { Cannonballs[i].blnstarted = false ; }
97103 break ;
98104 case SDLK_q:
99105 case SDLK_ESCAPE:
@@ -103,8 +109,7 @@ int main(int argc, char *argv[]) {
103109 case SDLK_r:
104110 // stop all motion of balls
105111 dblXY StopVel;
106- StopVel.x = 0.0 ;
107- StopVel.y = 0.0 ;
112+ StopVel.x = StopVel.y = 0.0 ;
108113 for (uint i = 0 ; i < DEFINED_CANNONBALL_LIMIT; i++) { Cannonballs[i].setVelocity (StopVel); }
109114 break ;
110115 } // end switch key
@@ -113,7 +118,6 @@ int main(int argc, char *argv[]) {
113118 if (holding) {CannonWindow.drawline (CurrentMouse, OldMouse);}
114119 // Update every ball
115120 tempdeltat = Tick.getTimeDifference ();
116-
117121 for (uint i = 0 ; i < DEFINED_CANNONBALL_LIMIT; i++) { // Loop through each cannonball
118122 if (Cannonballs[i].blnstarted ) { // only update cannonball if it is "alive"
119123 // Check for collisions if no collide is not on
@@ -123,29 +127,26 @@ int main(int argc, char *argv[]) {
123127 } // end for loop
124128
125129 CannonWindow.update (); // Update the screen
126- } while (!quit);
130+ } while (!quit); // keep looping until we get a quit
127131 return 0 ;
128132}
129133/* *********************************************************************************************************************************************************************/
130- void addNewCannonball (LOC mouseC, LOC mouseO ) {
134+ void addNewCannonball (LOC mouseC, LOC mouseO, double HoldTime ) {
131135 // Get location, vel, and angle
132136 double fire_v;
133137 double angle;
138+ double radius = (double )Global::Physics::fTimetoSizeRatio * HoldTime;
134139
135140 // Because y increasing is going down according to SDL we first negative the velocity
136141 fire_v = -1 * sqrt ( pow (mouseC.x - mouseO.x , 2 ) + pow (mouseC.y - mouseO.y , 2 ) );
137142 fire_v /= (double ) Global::Physics::fVelocityScalar ;
138143
139144 // if the mouse if pointing straight up or straight down make the angle 90
140- // Other calculate the angle with atan.
145+ // Otherwise calculate the angle with atan.
141146 if (mouseC.x == mouseO.x ) {
142- if (mouseC.y > mouseO.y ) {angle = -90.0 ;}
143- else if (mouseC.y < mouseO.y ) {angle = 90.0 ;}
144- else {angle = 0.0 ;}
147+ angle = (PI / 2.0 ) * ( (mouseC.y > mouseO.y ) ? -1.0 : 1.0 );
145148 } else {
146- angle = (double )-1.0 * atan ( (mouseC.y - mouseO.y ) / (mouseC.x - mouseO.x ) );
147- if (mouseC.x < mouseO.x ) {angle += (double )PI;}
148- angle *= (double )(180.0 /PI);
149+ angle = (double ) -1.0 * atan ( (double )(mouseC.y - mouseO.y ) / (double )(mouseC.x - mouseO.x ) ) + (double )( (mouseC.x < mouseO.x ) ? PI : 0.0 );
149150 } // end if x = x
150151
151152 // mod mouse start, once again because the top left is 0,0 to SDL
@@ -154,12 +155,12 @@ void addNewCannonball(LOC mouseC, LOC mouseO ) {
154155 // loop through array to find next available cannonball slot
155156 for (uint i = 0 ; i < DEFINED_CANNONBALL_LIMIT; i++) {
156157 if (!Cannonballs[i].blnstarted ) {
157- Cannonballs[i].setValues (2.0 , mouseO, fire_v, angle, i);
158+ Cannonballs[i].setValues (radius , mouseO, fire_v, angle, i);
158159 return ;
159160 } // end if not started
160161 } // end for cannonballs.
161162
162- // since the program would have exited this function if a spot was open
163+ // Since the program would have exited this function if a spot was open
163164 // below we tell the use they have to wait
164165 printf (" You cannot add more cannonballs, please wait for some to decay.\n " );
165166}
@@ -200,11 +201,6 @@ void doCollision(uint numA, uint numB) {
200201 CenterA = Cannonballs[numA].getplace();
201202 CenterB = Cannonballs[numB].getplace();
202203
203- CenterA.x += 5;
204- CenterA.y += 5;
205- CenterB.x += 5;
206- CenterB.y += 5;
207-
208204 DeltaCenters.x = abs(CenterA.x - CenterB.x);
209205 DeltaCenters.y = abs(CenterA.y - CenterB.y);
210206 //Since it is r^2 and the sqrt of this give us r, we just drop the sqrt part to save time
@@ -234,23 +230,19 @@ void doCollision(uint numA, uint numB) {
234230 // get the angle for both A and B
235231 if (Avel.x != 0.0 ) {Aangle = atan (Avel.y /Avel.x );}
236232 else {
237- if (Avel.y > 0.0 ) {Aangle = PI / 2.0 ;}
238- else if (Avel.y < 0.0 ) {Aangle = - PI / 2.0 ;}
239- else {Aangle = 0.0 ;}
233+ Aangle = (Avel.y >= 0.0 ) ? PI / 2.0 : -PI / 2.0 ;
240234 }
241235
242236 if (Bvel.x != 0.0 ) {Bangle = atan (Bvel.y /Bvel.x );}
243237 else {
244- if (Bvel.y > 0.0 ) {Bangle = PI / 2.0 ;}
245- else if (Bvel.y < 0.0 ) {Bangle = - PI / 2.0 ;}
246- else {Bangle = 0.0 ;}
238+ Bangle = (Bvel.y >= 0.0 ) ? PI / 2.0 : -PI / 2.0 ;
247239 }
248240
249241 // Adjust the angle to be the right one.
250242 // Since atan will only yield a number between -PI/2 and PI/2 we
251243 // have to adjust it if xvel is negative.
252- if ( Avel.x < 0.0 ) {Aangle += PI;}
253- if ( Bvel.x < 0.0 ) {Bangle += PI;}
244+ Aangle += Avel.x < 0.0 ? PI : 0 ;
245+ Bangle += Bvel.x < 0.0 ? PI : 0 ;
254246 // The contact angle has to be the difference between the two angles but
255247 // since sometimes one or the other is negative, we'll use abs to ensure the right number
256248 ContactAngle = abs ( abs (Aangle) - abs (Bangle) );
0 commit comments