Introduction

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.

The Assignment

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:

  • An instance of the BouncingBoulders class needs to contain a collection of Boulder instances so that it can make them all move around the screen. Start be defining an instance variable for the ArrayList that will be used to hold all of the Boulders.
  • Implement a constructor that takes two inputs: The desired number of boulders (an int), and the maximum speed the boulders should have (a double). Your constructor should create the required number of boulders (using your new Boulder constructor) and add them to the ArrayList. While you're at it, make sure you call MakeVisible on each boulder so they all start out visible.
  • Define a void method called printBoulders. It shouldn't take any inputs, but when called it should print out information on each of the boulders in the collection. For full credit, there should be a boulder "number" printed out with each entry, with the first boulder being displayed as #1. (See sample output below for examples.)
  • Define a void method called updateAll that takes a single integer as its input the number of update steps that should be performed on the collection of boulders. If the user passes this method 10 as an input, for example, each boulder in the group should have its position updated, then you should start over and do it again for each boulder, and again, until each boulder has had its position updated 10 times. (Do not just update the first boulder 10 times, then the second boulder 10 times, etc. That would look weird.)

    Tip: Start by ignoring the input and just updating each boulder's position once. Once you've got that working, think about how to do repeat that "operation" the specified number of times.
  • Write a void hideSmallBoulders method that takes an integer argument the size limit and makes any circles smallerthan the limit invisible. (You don't need to remove them from the collection. Just make them invisibe so they don't show up when we call updateAll.)

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

Comments

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.

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.