# **Doodle Jump** :::danger <b>Early Handin: Monday, October 28th, 11:59PM EST Regular Handin: Wednesday, October 30th, 11:59PM EST Late Handin: Friday, November 1st, 11:59PM EST</b> ::: Watch the demo [here](https://www.youtube.com/watch?v=HQ39rtiHT4w)! :::danger <font color="#ff0000">**Note**: *Check out the [Partner Projects Logistics guide](https://docs.google.com/document/d/1Pg5YtaoUKsykerqjwS3E7BsLiy8ZDdiY-AZl_hwdwW0/edit?usp=sharing) for more detailed information about debugging hours, late days, and handin!* There are ++two++ options for ways to complete Doodle Jump. ***DO NOT SUBMIT YOUR PROGRAMS INDIVIDUALLY TO GRADESCOPE - FOLLOW THE INSTRUCTIONS IN THE GUIDE TO SUBMIT TOGETHER. IF YOU SUBMIT SEPARATELY, YOU WILL RECEIVE A -10 DEDUCTION.*** </font> ::: # Assignment Roadmap :::info [Silly Premise](#Silly-Premise) [Collaboration Policy Reminder](#Collaboration-Policy-Reminder) [New Concepts Covered](#New-Concepts-Covered) [Helpful Resources](#Helpful-Resources) [Installing Stencil Code](#Installing-Stencil-Code) [Grading](#Grading) ### **[FUNCTIONALITY](#Functionality)** [Different Types of Platforms](#Different-Types-of-Platforms) [Coding Incrementally](#Coding-Incrementally) [Suggested Order for Incremental Coding](#Suggested-Order-for-Incremental-Coding) [Programming with a Partner](#Programming-with-a-Partner) [Using a Shared GitHub Repository](#Using-a-Shared-GitHub-Repository) [Minimum Functionality Requirements](#Minimum-Functionality-Requirements) [Full Functionality Requirements](#Full-Functionality-Requirements) [Bells and Whistles](#Bells-and-Whistles) ### **[IMPLEMENTATION](#Implementation)** [Physics Simulation](#Physics-Simulation) [Essential Constants](#Essential-Constants) [Timeline Updates](#Timeline-Updates) [Keyboard Interactions](#Keyboard-Interactions) [Platform Generation and Removal](#Platform-Generation-and-Removal) ### **[DESIGN](#Design)** [Storing Platforms](#Storing-Platforms) [Design Questions](#Design-Questions) ### **[STYLE](#Style)** ### **[HANDING IN](#Handing-In)** [README](#README) [Handin](#Handin) ::: ## Silly Premise Aang and Team Avatar have just arrived at the Air Temple. Aang excitedly shows Katara and Sokka one of his favorite Air Nation pastimes: Airball. In the game, you must jump off different platforms to score. Help your doodle do the same in Doodle Jump! Reference: Avatar the Last Airbender, Nickelodeon <img style="display: block; margin: auto;" src="https://hackmd.io/_uploads/r1dKDrf3C.png" alt="DJ Image" width="380" height="310"> ## Collaboration Policy Reminder If you ever have questions about [the collaboration policy](https://docs.google.com/document/d/10rbbd0Y6s1JUzPe8VmoWcL_Mz26XczX-i7p2LUFa9vc/edit?usp=sharing), refer to the collaboration policy or ask a TA! ![collab policy](https://hackmd.io/_uploads/BkSOpo1nC.png) :::danger **Note:** The usage of any artificial intelligence technologies, except those explicitly endorsed by CS15, is *strictly prohibited*. Because of TAs reading your code and a software package we use called MOSS (Measure of Software Similarity), illegal collaboration is easily detected in CS15. ::: ## New Concepts Covered * **`for`** and **`while`** loops * **`java.util.ArrayList`** * Representing parts of your program graphically and logically * Collaborative designing and programming ## Helpful Resources * This handout! * [Github and Debugging Code-along Recording](https://www.youtube.com/watch?v=IY9cwe207k8) * [The demo](https://www.youtube.com/watch?v=HQ39rtiHT4w) * [Doodle Jump Help Slides](https://docs.google.com/presentation/d/1EltzVwbe1q2ZuK2HZpDVnpbdRGbe786OFuo2qt8U0D8/edit#slide=id.p3) * [Design Patterns + Principles Part 1 Lecture](https://cs.brown.edu/courses/cs015/lecture/pdf/CS15.Lecture_14_Design_Patterns_and_Principles_Part_1.10.22.24.pdf) * [Style Guide](https://docs.google.com/document/d/1olSJxbrhuIystA_kVbmKu4V8JfN7HE-eDzM5blkoeFw/edit#heading=h.b1nvuu1nggmv), [GitHub Guide](https://docs.google.com/document/d/1tSxfUIn-Ro6Pr1X4y21BbYKdsiK-nlWW3pGDfyh7SQ8/edit), and [README Guide](https://docs.google.com/document/d/1QJPit-_8ZC3r4l_f5F3ydMK34-NchBYgwtm0c21iwsU/edit) * [CS15 JavaFX Guide](https://docs.google.com/document/d/1cOq649OLNp0-UHxz5W5KAOH-KyM2VXvq_TKmuGHv0Rg/edit) and [JavaFX Javadocs](https://docs.oracle.com/javase/8/javafx/api/toc.htm) * [ArrayList tutorial video](https://www.youtube.com/watch?v=3Ty0akxaJMM) ### Help Slides :::info We highly recommend looking through the [Doodle Jump Help Slides](https://docs.google.com/presentation/d/1EltzVwbe1q2ZuK2HZpDVnpbdRGbe786OFuo2qt8U0D8/edit#slide=id.p3) to get a better understanding and hints for the project. ::: ## Installing Stencil Code Similar to Lab5, you should receive an email inviting you to join a repository in the **`brown-cs15-2024`** organization. Once you accept this, you should see your repository available on GitHub, with the name **`doodlejump-<partner1login>-<partner2login>`**. If you don’t see it immediately, search for **`doodlejump`** in the repositories section in the left hand sidebar. If it still doesn’t show up, email the HTAs. Once you’ve cloned this repository from GitHub, you’ll need to rename the folder from **`doodlejump-<partner1login>-<partner2login>`** to just **`doodlejump`**. You will have issues running your code until you make the change. ## Grading The grade for this assignment will be determined by [functionality](#Functionality) (50%), [design](#Design) (38%), and [style](#Style) (12%). An ‘A’ project would meet mostly all [full functionality](#Full-Functionality-Requirements) requirements with good design and style. --- # Functionality Before you read this section, make sure you watch the [demo](https://www.youtube.com/watch?v=HQ39rtiHT4w)! Doing so will make understanding the assignment much easier. In this program, you will write the CS15 version of the game Doodle Jump. This game features a “doodle” whose goal is to hop along a series of never-ending platforms without falling to the ground. The doodle will fall according to the laws of gravity until it hits a platform, at which point it will bounce up until gravity brings it down again. The doodle’s horizontal position can be controlled with the left and right arrow keys. When the doodle moves off screen, it appears on the other side of the screen (known as “wrapping”). As the doodle jumps higher and higher, the game will need to scroll vertically. By “scroll vertically,” we mean that when the doodle hits a certain height (say, the midway point of the window), rather than have the doodle move higher on the screen, all the platforms should move lower (giving the illusion that the doodle is still climbing up). See the [demo](https://www.youtube.com/watch?v=HQ39rtiHT4w) for an example. As the game scrolls upward, old platforms need to disappear off the bottom of the screen and new platforms need to be regenerated at the top of the screen so that the doodle will have more places to jump. The game randomly generates four different types of platforms: * “Regular” platforms * Platforms that also scroll back-and-forth horizontally at a constant rate * Platforms that disappear after the doodle bounces on it once * Extra bouncy platforms The game ends when the doodle falls past the bottom of the screen because it missed all the platforms as it fell. A message should be displayed to tell the user that the game is over, and at this point **the doodle can no longer be moved left or right and the moving platforms should stop moving**. Your game should display the doodle’s score, which increases whenever the platforms scroll; additionally, it should include a quit button that closes the game window. ### Different Types of Platforms As mentioned above, the game should feature four different types of platforms the Doodle can use to bounce upward. The platforms should be added semi-randomly, with the standard platform being the most common. Each type of platform should have a unique color and capability, as follows: 1. ++Standard Platforms++: When the Doodle bounces on a standard platform, it should simply bounce upward. These platforms do not exhibit any special capabilities. 2. ++Disappearing Platforms++: When the Doodle bounces on a disappearing platform, it should be immediately graphically removed from the program. The Doodle should not be able to bounce on the same disappearing platform multiple times. 3. ++Extra Bouncy Platforms++: When the Doodle bounces on an extra bouncy platform, its rebound velocity should be greater than the standard rebound velocity (within a reasonable range), causing the Doodle to bounce higher than a standard platform. 4. ++Moving Platforms++: These platforms should constantly move back and forth horizontally across the screen with a Timeline, but react the same as standard platforms when contacted by the Doodle. Unlike the doodle “wrapping” movement, these platforms should never leave the screen but instead should reverse direction when reaching an edge. ## Coding Incrementally After you’ve watched the [demo](https://www.youtube.com/watch?v=HQ39rtiHT4w&feature=youtu.be), thoroughly read this handout and plan a thorough program design with your partner. Once you’re ready, do a second pass on your project design to make sure you feel confident in the design choices. Then, once you’re actually ready, start coding! It is important to code **incrementally**, meaning you completely accomplish one logical task before moving on to the next one. ### Suggested Order for Incremental Coding **Step 0.** Work with your partner to create a design for the program, including a class diagram and inheritance/interface diagram. **Step 1.** Download and run the stencil code. **Step 2.** Make your game window show up. * The game should display a quit button that calls **`System.exit(0)`** or **`Platform.exit()`** when clicked. **Important note**: If you have a class named **`Platform`**, you ***must*** use **`System.exit(0)`**. **Step 3.** Get your doodle to display. **Step 4.** Set up the **`Timeline`** that will be in charge of updating the doodle’s location and displaying the graphical changes. * To test if your **`Timeline`** is working, you can start with printlines. **Step 5.** Set up the KeyEvent handler so you can use the left and right arrows to get your doodle to move. **Step 6.** Add “wrapping” capabilities so the doodle reappears on the other side when it moves offscreen. **Step 7.** Add some physics simulation so that your doodle falls. **Step 8.** Start with creating one *basic* platform and add/test collision detection with that platform. **Step 9.** Generate a whole screen of semi-randomly positioned platforms so that your doodle can jump its way upwards! **Step 10.** Add the vertical scrolling so that when the doodle tries to pass a certain height, it stops moving, and all the platforms move downward. * **WARNING!** This step is tricky! Really think about the best way to implement this -- careful design and pseudocode will simplify this step greatly. **Step 11.** As platforms scroll down, be sure to delete them and generate new ones both graphically and logically. **Step 12.** Add the moving, disappearing, and extra bounce platforms. **Step 13.** When the game is over, stop the **`Timeline`**, display a “Game Over” label, and make sure the Doodle can no longer be moved with the arrow keys. **Step 14.** Add score tracking to the game. <center><img src="https://hackmd.io/_uploads/S1CRosNn0.png" height="300"></center> ### Programming with a Partner ++When working with your partner, you should decide how to divide up the codebase *prior* to starting to code++. However, it’s common that one piece of functionality may take longer than expected, so you should be willing to help each other and be flexible in order to complete the project as best as possible. When determining the division of labor with your partner, it’s important to keep in mind realistic expectations about your work styles. For example, if you will be able to usually work simultaneously on Zoom or in person, you each could code the Doodle functionality together (perhaps one person does horizontal movement while the other does vertical movement). Or, if you will have to work mostly asynchronously, it may be easier to have one person do the Doodle functionality while the other does the basic platform functionality. ++Regardless of how it’s split, be sure to have a conversation upfront about your work styles++. The division of labor is up to you and your partner, but here are some guidelines to follow so that you each have an understanding of important concepts: * Each partner should implement one of the platform algorithms (platform scrolling and platform generation) - or you can implement them both together * Each partner should add at least one special type of platform :::info For more concrete instructions on how to divide up the work, please refer to [this guide](https://docs.google.com/document/d/1yXkiW3qpMmg1lZhrlB_bzWyABEFdKUAQBGXFDI-hofQ/edit#heading=h.b1nvuu1nggmv). ::: **If you are being ghosted by your partner or have an other concern please email the HTAs.** ### Using a Shared GitHub Repository Using GitHub to collaborate on the code base in a single repository is a bit more complicated than using GitHub for code edited by a single person. As you saw in lab 5, sometimes merge conflicts may arise when both partners edit the same area of the code, and you should now have a basic sense of how to resolve merge conflicts. However, merge conflicts are avoidable! How? * Follow the sequence of **`git add -A`**, **`git commit -m “<msg>”`**, and <span style="background: yellow;">**`git pull`**</span> each time before you write new chunk of code in order to incorporate any changes your partner has made * Follow the sequence of **`git add -A`**, **`git commit -m “<msg>”`**, and <span style="background: yellow;">**`git push`**</span> each time after you finish writing a chunk of code so that your partner can incorporate the changes you’ve made * If you and your partner are working at the same time, make sure to keep track of the lines of code you add or edit before using <span style="background: yellow;">**`git pull`**</span> or <span style="background: yellow;">**`git push`**</span> and follow the previous two steps * **Communicate with your partner so that you’re working on separate parts of the program!** ## Minimum Functionality Requirements MF Policy Summary: *In order to pass CS15, you will have to meet minimum functionality requirements for all projects. If you don’t meet them the first time around, you may hand the project in again until you succeed, but you will keep your original grade. MF requirements are **not** the same as the requirements for full credit on the project. You should attempt the full requirements on every project to keep pace with the course material. An ‘A’ project would meet all of the requirements on the handout and have good design and code style.* To meet MF for DoodleJump: * A doodle appears on screen. * Platforms generated at semi-random locations appear on screen. * The doodle's position and velocity are updated continuously with a **`Timeline`**. * The doodle can collide with and bounce off of platforms. * Platforms scroll downward when the doodle reaches some point on the screen. * The doodle moves left and right in response to key presses. * At least one type of platform with extra capabilities generates. ## Full Functionality Requirements Beyond the minimum functionality requirements, the rest of the functionality grade will depend on the following criteria: * As platforms scroll downward, new platforms are randomly generated to fill the screen. * Four types of platforms — regular, moving, disappearing, and extra bounce — generate. * The game keeps track of the player’s score, which increases when the platforms scroll. * The game displays a “Game Over” label and stops all movement when the doodle falls off the screen. * The doodle “wraps” when it moves off screen. * Quit button quits the app. * No minor bugs. ## Bells and Whistles Once you’ve met all of the above requirements, feel free to snazz up your DoodleJump with some bells and whistles! ++Reminder: you are not eligible for extra credit unless your project meets minimum functionality requirements.++ Here are a few ideas: * **SRC consideration**: Implement a feature that considers the addictive nature of playing a game with endless scrolling. How might you mitigate this in your version of Doodle Jump? Explain this decision in your README. * More than four different types of platforms * Different levels of difficulty * Make the Doodle a composite shape * Pause and restart functionality * Support for multiple players * ‘Smooth’ left/right movement with the arrow keys * Toys to alter the Doodle’s velocity - jetpacks, helicopter-hats, etc. * Venomous black holes and hungry monsters Keep in mind that most TAs have not implemented every one of these extra credit features, so we cannot guarantee support for them (though they will try to send you in the right direction). Remember that you should make sure that you have a fully functional program before working on extra credit. Remember, from the [Course Missive](https://docs.google.com/document/d/1_zT7i5ApBusdW0GKzz5U939mZBQD02p5wG5e8V49cbg/edit#heading=h.vq2wg61xggf0): >*Extra credit is only to be done after the original assignment has been fully completed - if you have not met the requirements, you will not receive extra credit. Extra credit may not redefine the original assignment.* --- # Implementation ## Physics Simulation Just like in Cartoon, your doodle needs to be “moving”. Remember that this can be done by using a **`Timeline`**, and updating its position at every **`KeyFrame`**. Additionally, your doodle should fall under the influence of gravity. This means that your doodle won’t have a constant velocity -- its velocity will update together with your doodle’s position! The exact calculations surrounding how your doodle should follow gravity involve a few kinematic equations, none of which are necessary for CS15. The constant for gravity (explained more in-depth below) combined with the duration of your **`KeyFrame`** can be used to calculate the updated velocity and position of your doodle at every **`KeyFrame`**. Here’s some pseudocode for making this calculation each time the **`Timeline`** cycles through to the end of a **`KeyFrame`**: ``` updated velocity = current velocity + acceleration * DURATION updated position = current position + updated velocity * DURATION ``` ## Essential Constants The constants **`GRAVITY`** and **`DURATION`** you see above are already defined for you in the **`Constants`** class, as well as suggested constants for dimensions of the Doodle and the platforms, though you are welcome to change them. Be sure to review the [Math and Making Decisions lecture](https://cs.brown.edu/courses/cs015/lecture/pdf/CS15.Lecture_8_Math_and_Making_Decisions.10.1.24.pdf) for more information on constants! **`GRAVITY`** corresponds to the downward force on your doodle. On Earth, gravity points toward the center of the planet with a force of *-9.8 m/s^2^*. This isn’t super helpful, though, in the world of JavaFX. Because the JavaFX coordinate system defines the positive y-direction as downward, our acceleration constant is positive (approximately 1000 pixels/s2). The **`DURATION`** constant corresponds to the amount of time, in seconds, that elapses for each iteration of your **`KeyFrame`**, and thus should also be used to initialize your **`KeyFrame`**. Another constant you will see in your **`Constants`** class is **`REBOUND_VELOCITY`**. **`REBOUND_VELOCITY`** is the initial velocity the Doodle achieves right after jumping on a platform. Set your doodle’s velocity to **`REBOUND_VELOCITY`** whenever your doodle hits a platform while falling to make it jump. You can also change this constant to whatever makes your program work smoothest. Take a second to think about why this works. Each time your doodle bounces, including at the very start of the game, it has an upward speed of **`REBOUND_VELOCITY`**. As we have seen, though, each tick of the **`TimeHandler`** corresponds to the passage of a discrete unit of time, during which **`GRAVITY`** acted on your doodle. **`GRAVITY`**, which is a constant downward force, reduces your doodle’s non-constant upward speed by a particular amount (which you have the equations to calculate) at each of these ticks. Once, after several ticks, **`GRAVITY`** has reduced your doodle’s upward speed to 0, it continues to push down on your doodle, increasing its downward speed until your doodle either drops off the screen, or intersects a platform. ## Timeline Updates By this point it should be clear that your **`Timeline`** is going to have to do a bit more than it did in Cartoon. To make your lives easier, we have provided a list of steps that need to be taken at the end of each **`KeyFrame`**. Remember that your top-level logic class doesn’t need to do all of this directly. It can (and should) delegate appropriate tasks to other methods and objects. At each timestep, you should: 1. Calculate a new y-velocity for the doodle using your physics simulation equation. 2. Calculate your doodle’s new potential position based on the new y-velocity. Note that you shouldn’t change the doodle’s position at this point. 3. Check to see if the doodle will be above the horizontal middle of the window based on its new potential position. Recall that the top left of the window is at position (0, 0), and that the y-position increases as you move down the window. Assuming that your window has a height of 400 pixels, if the doodle’s y-position is less than 200 pixels, then it is above the horizontal middle of the window. * If the doodle is above the midpoint of the screen: * Calculate and store how far the doodle is above the midpoint. * Set the doodle’s position to the screen midpoint. * For each platform, lower the platform by how much the doodle was above the midpoint. * If it isn’t above the midpoint of the screen, set the doodle’s position to the calculated potential position. 4. If the doodle intersects with a platform AND the doodle is falling: * Set the doodle’s y velocity to **`REBOUND_VELOCITY`**. 5. Check to see if any of the platforms are below the bottom of the window. * If a platform is below the bottom of the window, remove it both graphically and logically (more on this later). Now you may be wondering—how do we detect when the doodle collides with a platform? You can do this by using the **`javafx.scene.Node`** [intersects()](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#intersects-double-double-double-double-) method (and consider checking out the [getLayoutBounds()](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#getLayoutBounds--) method to help)! Be sure to check the Javadocs to understand how it should be used. Importantly, make sure to only check for platform collisions when the doodle is falling—you don’t want it to bump into anything on the way up! ## Keyboard Interactions Keyboard input in DoodleJump should be similar to the key handling that you wrote for Cartoon -- the [Cartoon handout](https://hackmd.io/@Fall2024-CS15/S1otNrRoA) has more information on the specifics of handling key input, but here are some helpful reminders on handling key input in JavaFX: * Make sure to **`consume()`** your **`KeyEvents`** after you are finished with them to prevent them from triggering other actions in your program. * For the keys to receive input, you need to “request focus” on the **`Pane`** that the key handler is added to. “Focus” deals with which graphical element is currently “selected.” To register and handle key input, we want to give focus to the **`Pane`** associated with the key handler. This can be accomplished by calling **`setFocusTraversable(true)`** on your **`Pane`** after you add the key handler to your **`Pane`** using **`setOnKeyPressed`**, and call **`setFocusTraversable(false)`** on all other **`Panes`** and buttons. * At the end of the game, the program should no longer respond to any key pressed. In order to achieve this, you can use the **`setOnKeyPressed`** method, passing in the **`null`** value as the argument. This will remove any previously-registered key pressed handlers. ## Platform Generation and Removal Begin by creating the bottommost platform so it is just below your doodle's start position. Next, you'll want to “semi-randomly” generate the platform above that one. Platforms cannot be generated completely randomly because the doodle needs to be able to reach the next platform. Therefore, you should decide on minimum and maximum x and y distances between two consecutive platforms to ensure that the doodle is able to jump from one to the other. Here's an example of how to use this information to generate the platform's location: * Assume: Platform p has x-y coordinates (300, 600) * Assume: Doodle can move up 100 pixels, and left or right by 200 pixels per jump, before starting to fall. **(This will differ based on the constants you use, make sure your game is playable)** * Note: The second platform must be above the first platform. For this example, say the height of each platform is 10 pixels. ![Screen Shot 2024-09-02 at 10.24.10 AM](https://hackmd.io/_uploads/rJK9cBX30.png) * With the above assumptions, the maximum x-distance between consecutive platforms should be 200, the maximum y-distance should be 100, and the minimum y-distance should be 10. AKA, any platforms you generate must be within the red bounds in the above picture. * **Note**: Platforms should not generate outside the board. You must also consider the pane’s width when constraining your generation to stay within the board. The third platform will need to be positioned relative to the second platform, and so on. Do you see a pattern? How should you generate *all* the platforms? A loop! At each iteration of the loop, you are creating a new platform whose position is relative to the platform created in the previous iteration of the loop. Your loop will exit when the last platform created meets a certain condition — more on this below. Here’s an idea of how you might want to implement this: 1. Create your first platform and store it in a current topmost platform variable. Position the platform directly under the Doodle’s starting location (probably somewhere near the bottom of the Pane). 2. Add that platform to your ArrayList of platforms. 3. While the current topmost platform's y position is not above the top of the Pane: * Create a new platform and add it to the ArrayList. * “Semi-randomly” position the new platform relative to the current topmost platform. * Update the current topmost platform variable to reference this new platform. Here’s pseudocode for step 3 of the platform generation process (note that **`xOffset`**, **`yOffsetMin`**, and **`yOffsetMax`** are x that you can determine yourself): ``` function generatePlatforms: set topPlatform to the most recent platform while topPlatform is on screen: // calculate low and high x bounds low = Math.max[0, topPlatform.x - xOffset] high = Math.min[pane width - platform width, topPlatform.x + xOffset] generate random x coordinate between low and high // calculate min and max y bounds low = topPlatform.y - yOffsetMin high = topPlatform.y - yOffsetMax generate random y coordinate between low and high create a new platform with your random coordinates add the new platform graphically and logically update topPlatform ``` :::info **Remember:** To graphically add or remove **`Nodes`**, you should do so from the Pane that contains them. To add or remove **`Nodes`** in your game logic, you should make sure to add or remove them from the data structure in which they’re stored. This is *not* the same as the graphical Pane! ::: For a review of **`ArrayLists`**, look over the slides in the [Arrays lecture](https://cs.brown.edu/courses/cs015/lecture/pdf/CS15.Lecture_13_Arrays_and_ArrayLists.10.17.24.pdf). This will also help you understand how to declare and instantiate an **`ArrayList`** that holds a unique type of object. --- # Design On this project, your design grade will be based on your use of delegation (class design and method design with proper abstractions), encapsulation (especially wrapper classes and getters/setters), and polymorphism. ## Storing Platforms So how will you keep track of your platforms? By using a **`java.util.ArrayList`**, that’s how! An **`ArrayList`** is a data structure that allows you to store and access a dynamic number of objects in a resizable list, which is exactly what we’re looking for: a way to keep track of all the platforms in our game. But wait! Why can’t we use an array for this? Since the horizontal and vertical positioning of platforms is based on a degree of randomness, varying numbers of platforms may fit on the screen at any one time. Remember — arrays always have a set capacity. The **`java.util.ArrayList`** ’s dynamic capacity lends itself very well to handling this type of dynamic storage, whereas an array of fixed capacity would not. **`ArrayLists`** also allow you to easily add and remove elements. The [Javadocs](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) for the **`java.util.ArrayList`** data structure highlight some of the important methods that have already been defined for **`ArrayLists`**, so you should become familiar with these before starting this project. ## Design Questions Here are *some* questions to consider when creating a design for your program. There are definitely more questions to consider as well! * How can you leverage “wrapper classes” to wrap various JavaFX elements of the program? * How can you model properties like game score and doodle velocity? Which classes are those properties of? * What do platforms have in common and how are they different? How can you leverage polymorphism to make it so that the game doesn’t need to know the actual type of each platform it’s moving? This program is large and complex, so it is more important than ever to **design all your classes before you write any code.** We mean it! --- # Style Refer to the [CS15 Style Guide](https://docs.google.com/document/u/0/d/1olSJxbrhuIystA_kVbmKu4V8JfN7HE-eDzM5blkoeFw/edit) for the specific style guidelines along which your code will be graded. # Handing In ## README In CS15, you’re required to hand in a README file (must be named README) that documents any notable design choices or known bugs in your program. Remember that clear, detailed, and concise READMEs make your TAs happier when it counts (right before grading your project). You are expected to create your own README file. Please refer to the [README guide](https://docs.google.com/document/d/1QJPit-_8ZC3r4l_f5F3ydMK34-NchBYgwtm0c21iwsU/edit) for information on how to create a README, what information your README should contain, and how you must format it. **You do not need to add the number of hours spent on the project. That will be covered in a form after submission!** In addition to describing your design choices, if you decide to implement any extra credit, please detail it in an EXTRA CREDIT section of your README. ## Handin To hand in your assignment, follow the steps listed in [this document](https://docs.google.com/document/d/1Pg5YtaoUKsykerqjwS3E7BsLiy8ZDdiY-AZl_hwdwW0/edit#heading=h.hl218puks2cr). <b style="color: red;">DO NOT SUBMIT YOUR PROGRAMS INDIVIDUALLY TO GRADESCOPE - FOLLOW THE INSTRUCTIONS IN THE GUIDE TO SUBMIT TOGETHER. IF YOU SUBMIT SEPARATELY, YOU WILL RECEIVE A -10 DEDUCTION.</b> Be sure to upload your class and interface/inheritance diagram as a **.pdf**, **.jpg/.jpeg**, or **.png** file to your GitHub respository. <b style="color: red;">If you submit a different file format, it may be unsupported so you will receive no credit for the diagram.</b> If you do not submit all the proper files, we will allow you to resubmit with a 5 point penalty, only if you’ve pushed your code to GitHub prior to the deadline. **If your code wasn’t pushed to GitHub by the deadline and you submit incorrectly to Gradescope, we will grade whatever was submitted.** You can submit as many times as you want prior to the deadline, and only your most recent handin will be graded. If you handin before the deadline and again after the deadline, the submission will be counted as late. <b style="color: red;">Do not include any identifying information (name, login, Banner ID) anywhere on your handin (files names, in the code, in the README) as we grade anonymously.</b> **Including identifying information will result in a deduction from your assignment.** Good luck and remember: **<font size="6" style="display: block; font-family: cursive; text-align: center; margin-left: auto; margin-bottom: -20px;">Start Early... Start Today... Start Yesterday!</font>** <font style="display: block; text-align: center; font-family: courier">- William Shakespeare</font> <img src="https://hackmd.io/_uploads/r1lVX2N3R.png" alt="Avatar picture" width="500" style="display: block; margin: auto">