Let's bounce some boulders! Your Clock program was so successful that NASA recently called and asked you to consult on their latest astronomical simulations. When they heard you'd worked with bouncing boulders on a lab exercise, they hired you on the spot! NASA wants to be able to create large collections of boulder-like objects and simulate their motions on the screen. They've got a few more requests that you can read about below.
I've created a new project BouncingBouldersAsmt to get you started. The project looks a lot like the finished product from the Boulders lab: There's a Canvas class that helps display our objects, a Boulder class (that's smart enough to wrap instances around at the edges of the screen), and a BouncingBoulders class that's mostly empty at this point. First you'll make a few small improvements to the Boulder class, then define methods in the BouncingBoulders class. Ultimately, the goal is to add code to BouncingBoulders that will keep lists of Boulder objects so that we can have lots of them.
Open the Boulder class. Note that it already has a constructor, but the constructor expects the user to pass in most of the information about the new boulder they want (position, speed, size). Define a second constructor that only takes one input the maximum allowable speed (a double) and creates a boulder with random X and Y velocities, random position, and random size. The randomly selected X and Y coordinates should be within the bounds of the Canvas window, and both negative and positive velocities should be allowed but not exceed the limit passed in by the user. (You'll want to look up the documentation for the Random class's nextDouble method.) The size should be between 1 and 100 (inclusive).
An additional note about velocities: I'm only asking you to ensure that the X velocity has a magnitude less than the speed limit, as does the Y velocity. So, for example, if the speed limit is 100, a boulder with X velocity of 99.998 and Y velocity of -98.274 should be possible, even though the math nerds out there might point out that the boulder's overall velocity is more like 140 when you do the vector math.
While you're still in the Boulder class, define a method named toString that returns a String describing the boulder's state. It should include the size, position, and speed. For example:
> Boulder b;
> b = new Boulder(20.5);
> b.toString()
"Boulder of size 52 is at 656.063, 240.661 with velocity -13.301, 4.454" (String)
In the output above I manually trimmed down the digits after the decimal point to make it fit on the screen. The X position originally showed up as 656.0631719593897, for example. You're not expected to limit the number of digits in the output, though you can certainly dig into that on your own if it bothers you.
Now open the BouncingBoulders class and work through the following steps:
Here are some sample interactions with the project:
> BouncingBoulders bb;
> bb = new BouncingBoulders(20, 12.7);
> bb.updateAll(10);
> bb.hideSmallBoulders(30);
> bb.printBoulders();
The simulation contains the following 20 boulders:
1: Boulder of size 50 is at 372.1875893819677, 133.87776166702926 with velocity 11.932056023677355, -10.554410451924971
2: Boulder of size 19 is at 433.82398487718194, 481.6550233232082 with velocity -6.080615674768774, 4.478703423386534
3: Boulder of size 25 is at 14.205130964340174, 393.97603145969526 with velocity 11.11050281871444, 7.603736784016846
4: Boulder of size 52 is at 620.951230348042, 323.61362827344834 with velocity 5.114525160868034, -4.187689679784777
5: Boulder of size 38 is at 768.4674629842491, 373.37094868583165 with velocity -1.8793981371839266, 2.323836781228364
6: Boulder of size 5 is at 106.94259393133359, 409.1286104889523 with velocity 8.541187451017588, -2.0980170740851207
7: Boulder of size 85 is at 559.8017179562688, 586.6516362879815 with velocity 3.2945829012953443, 9.293225362880605
8: Boulder of size 61 is at 73.67532737888092, 339.2820163629544 with velocity 2.9759777387407453, -1.0460581268287026
9: Boulder of size 72 is at 298.9813930724454, 56.310425271045304 with velocity -7.514211507103362, -6.184408602214812
10: Boulder of size 79 is at 259.367607069451, 118.06378240920512 with velocity -6.236904329580232, -8.086859198656914
11: Boulder of size 20 is at 210.4299455624453, 51.74854161385595 with velocity -11.979467778706224, -10.387300080994471
12: Boulder of size 87 is at 92.4472745844761, 266.8843323512295 with velocity 4.929968828747171, 0.37729816731534704
13: Boulder of size 87 is at 176.9020855021274, 443.40914283421677 with velocity 6.68723550255034, 0.6345696053823122
14: Boulder of size 59 is at 116.95477788856252, 578.302522353816 with velocity 11.197388847833434, 0.8888208572255731
15: Boulder of size 38 is at 182.33895355369228, 510.2331175188551 with velocity 4.35554045474316, 1.5838768509207295
16: Boulder of size 94 is at 764.2096929809328, 583.0330363997685 with velocity 0.4981611359740228, 6.4416864952641895
17: Boulder of size 25 is at 743.6657674362261, 486.7389217987581 with velocity 5.246475024380597, -5.967682834319399
18: Boulder of size 72 is at 242.15509909537224, 23.900988670872266 with velocity -7.936130021313706, -1.6208086389260128
19: Boulder of size 69 is at 577.4461866270992, 116.54887921309651 with velocity 12.44206759523237, 0.1350090685929981
20: Boulder of size 79 is at 234.82617887977983, 265.7267573132114 with velocity -11.455051901839385, 6.173991802852747
Each and every method should have a "javadoc-style" comment above it (the ones that use /** ... */). For full credit, you should use the @param and @return tags as appropriate in these method comments. Each instance variable should have a brief comment as well, and you should look for opportunities to use constants to tidy up your code. Don't forget the main comment at the top of the class either I'm looking for more than just a sentence or two.