Difference From trunk To release-1
2022-12-29
| ||
21:40 | add feature matching exercise Leaf check-in: 0418693d59 user: theo tags: main, trunk | |
21:05 | update supporting materials check-in: ed0e82e855 user: theo tags: main, trunk | |
2022-12-22
| ||
04:42 | Remove unnecessary image check-in: 05807086e1 user: theo tags: main, trunk | |
2022-12-09
| ||
04:34 | Merge pull request #108 from CSC207-2022F-UofT/readme added m chip issues check-in: aa3fd4bfd4 user: siddharth tags: main, prerelease-41, release-1, trunk | |
04:19 | Update README.md check-in: 05eeb9e756 user: siddharth tags: main, trunk | |
02:14 | Merge pull request #101 from CSC207-2022F-UofT/meta/readme-round-2 Final README Updates Leaf check-in: 127699655f user: theo tags: main, prerelease-40, trunk | |
Deleted EXT_LICENSE.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to README.md.
1 2 | # Mountain Group 105 | < < < < | | | | | | | | | | | > | > > | > > | > > | > > > > > > | | < < < | < | < < < < < < | > | | < < < | < | > | | < | < | < | < | < | | < < < | < | | | > > > > | > | | | < | < | | | | < < < | | < < | < | | < < | < < < < | > | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | # Mountain Group 105 You are a group of four weary travelers. You have been walking for so long that you no longer have any memory of where you came from or who you are. You cannot recall anything but the endless action of putting one foot in front of the other, traversing this empty landscape. Suddenly, you look up, startled out of your reverie. An imposing mountain looms before you. Your party steps forward, drawn to it for some inexplicable reason. You crane your neck to see if you can make out the peak, but the morning mist impedes your view. You all know you cannot go back to wherever you came from. You have to keep going. You have to climb the mountain. Maybe whatever waits for you up there will remind you of who you are… and what you’re searching for. ## Quickstart Guide This section contains instructions on how to download and run pre-compiled Jar distribution. First, this project requires [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html), so make sure that is installed. Next, navigate to the [latest GitHub release](https://github.com/CSC207-2022F-UofT/course-project-group-105/releases/latest), then download and unzip the attached `course-project-group-105.zip` file. Finally, navigate to the `bin` folder and run either `course-project-group-105.bat` (on Windows) or `course-project-group-105`. Note: because JavaFX has native components, it is somewhat hit-or-miss whether the pre-compiled Jar will on a specific platform/operating system combination. It is only known to consistently work on Linux+amd64 *If it does not work, try the instructions in the next section* ## Build (and Run) from Source ### IntelliJ IDEA (IDE) Instructions First download the source code by going to `File > New > Project from Version Control...`, set `Version control:` to `Git`, and the `URL:` to `https://github.com/CSC207-2022F-UofT/course-project-group-105.git`. Then press `Clone`. Next, if IntelliJ does not immediately recognize the fact this is a Gradle project (you can tell by the lack of a `Gradle` tab on any of the edges), navigate to the `build.gradle` file in the IDE. An icon with an elephant should appear, click it. There should now be a `Gradle` tab on one of the edges. Finally, open the `Gradle` tab and navigate to `course-project-group-105 > Tasks > application` and double-click run. ### Command-Line (CLI) Instructions First, this project requires [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html), so make sure that is installed. Next clone the repository and switch to the directory which can be done by ```sh git clone https://github.com/CSC207-2022F-UofT/course-project-group-105.git cd course-project-group-105 ``` Finally, this is a standard Gradle project, so to start the application simply run ```sh gradlew.bat run ``` in the Windows CMD, or ```sh ./gradlew run ``` on any Unix-like operating system (or the built-in IntelliJ IDEA terminal). ## Highlights (and extra hints for the TA) - Functionality - All twelve (12) of our original user stories are complete. - In addition we've added the following extra functionality: - Persistence: When a battle ends your characters' stats are automatically saved and are recalled on next game open. Even if you lose the game your characters' stats get saved! - Minimap: Press 'm' to open a minimap that will show a visual representation of the map you've discovered so far! - Keyboard layout: - `w`, `a`, `s`, `d`: movement keys, in the usual configuration. - `e`: interact with an adjacent chest on the map. - `f`: fight an adjacent enemy on the map. - `m`: open the minimap (any key closes it). - `i`: open/close the inventory. - `<SPACEBAR>`: open the walking menu. - `k`: open the help text. - `t`: start the tutorial. - Code Organization - Code is organized by layers, `com.mg105.user_interface`, `com.mg105.interface_adapters`, `com.mg105.data_control`, `com.mg105.use_cases`, `com.mg105.entities`. - The `com.mg105.user_interface` package is the only package that knows anything about the graphics library, JavaFX. - The `com.mg105.utils` package mostly keeps track of constants. - Testing - As of [96e8a0a3](https://github.com/CSC207-2022F-UofT/course-project-group-105/pull/101/commits/96e8a0a3081fbd400cdc11552415465772a5a1a1), (line) test coverage is as follows: - `com.mg105.entities`: 90% - `com.mg105.use_cases`: 90% - `com.mg105.data_control`: 76% - `com.mg105.interface_adapters`: 57% - `com.mg105.user_interface`: 1% - `com.mg105.utils`: 100% - Total: 51% - Some tests assume a **completely clean** environment, if some tests fail delete `move_data.csv` and `party_data.csv` and run them again. - Documentation - Current up-to-date Javadoc can be found [here](https://docs.mg105.com/). - Extra GitHub Features Used - GitHub actions to make sure sensitive files (`.idea/*`) are not accidentally modified in a PR ([link](https://github.com/CSC207-2022F-UofT/course-project-group-105/actions/workflows/sanity.yml)). - GitHub releases for every merge into `main`, built by GitHub actions ([link](https://github.com/CSC207-2022F-UofT/course-project-group-105/releases)). - GitHub pages that host up-to-date Javadoc of `main`, built automatically by GitHub actions ([link](https://docs.mg105.com/)). ## Note for Apple Silicon Users (m1 and beyond chips) Due to some dependency issues this game will NOT build properly for anyone using Apple Silicon (m1 or m2 chips). You should still be able to make changes and run and create tests. ## Copyright Unless mentioned otherwise, code is licensed under the GNU Affero General Public License, Version 3.0. See the [LICENSE](/LICENSE) file for more details. Here are the exceptions: - `imgs/background2.jpg` by Fred Seibert is licensed under [CC BY-NC-ND 2.0](https://www.creativecommons.org/licenses/by-nc-nd/2.0/). |
Added images/closed_issue.png.
cannot compute difference between binary files
Added images/closed_project.png.
cannot compute difference between binary files
Added images/create_branch.png.
cannot compute difference between binary files
Added images/create_pr.png.
cannot compute difference between binary files
Added images/create_project.png.
cannot compute difference between binary files
Added images/link_branch.png.
cannot compute difference between binary files
Added images/link_project.png.
cannot compute difference between binary files
Added images/new_issue.png.
cannot compute difference between binary files
Added images/new_pr.png.
cannot compute difference between binary files
Added images/rename.png.
cannot compute difference between binary files
Added images/set_tags.png.
cannot compute difference between binary files
Added imgs/background2.jpg.
cannot compute difference between binary files
Added project_plan_dev.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | # Project Planning and Development with Github In this course project, you are expected to use Github to manage your code. This document describes the workflow for using Github when you are developing the course project. Please read it carefully and follow the instructions. **Try to work through the steps with the help of your team first, but please ask for help if your team gets stuck on any of the steps or needs something clarified.** ## Create a New Github Project [Github Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects) (*Yes, the name of this product is called "Github Projects", do not confuse it with the course project*) is a lightweight project management tool that is integrated to Github. You can use it to track issues, pull requests, visualize tasks status, and track responsibilities. **TAs will mark you project implementation plan and track your progression using the Github project.** 1. Navigate to **Projects** Page on [CSC207 organization page](https://github.com/orgs/CSC207-2022F-UofT/projects) 2. Click **New project**, and click **Create** on the new page. ![](images/create_project.png) 3. Click the title bar to rename the project to your team/project's name, and press **Enter** to save the change. ![](images/rename.png) 4. Link the project to your repository. Navigate to your repository and select **Projects** tab, then click **Add Project** and select the project you just created. ![](images/link_project.png) 5. The project will show up in the the list below. ## Define Your Features for the Implementation Plan As a part of the project planning, you are required to record all features formulated from your user stories, as **issues** in your Github repository. 1. Navigate to your repository and select **Issues** tab, then click **New issue**. ![](images/new_issue.png) 1. Fill in the title as the name of the feature and provide a brief description of the feature. **Please use a consistent naming convention for your issues.** For example, you can use the following format: `[Feature x] <feature name>` 2. On the side bar, select the **Assignee**, **Labels** (Enhancement for your Features), and **Projects**(the one you just created) for the issue. Then click **Submit new issue**. ![](images/set_tags.png) 3. On the project page, you can see an item is automatically created. :warning: :warning: **Make sure you verify that each feature issue is successfully created in the project.** :warning: :warning: ## Feature Development When you work on a feature, you are always required to create a **branch** for the feature and **merge** the branch back to the main branch with **pull requests** when the feature is completed. Note: the below should remind you of the "workflow" we covered in the first lab this term. Please review the details of that document in addition to the below, which provides additional details about how the process works on GitHub. 1. To create a new branch, navigate to the issue you are assigned to, and click **Create branch** on the right side bar. ![](images/create_branch.png) 2. Select a name and click **Create branch** on the pop-up window. Use the provided command to check out the branch you just created on your local machine. *Alternatively, you can create a branch manually, and link it to the issue.* 3. Verify that the branch is successfully linked to the issue. ![](images/link_branch.png) ## Merge Feature Branch to Main Branch When you finish working on a feature, you are required to merge the feature branch back to the main branch with a **pull request**. 1. After you make changes to the code and commit them to the feature branch, you will see a **Compare & pull request** button on the repository page. Click it to create a pull request. *Alternatively, you can create a pull request in the **Pull requests** tab.* ![](images/create_pr.png) 2. Give a meaningful title and description for the pull request, remember please make the name consistent. 2.1 First make sure that you are merging from the feature branch to the main branch (see blue box). 2.2 Make sure that you set the correct fields as issues (see red box). ![](images/new_pr.png) 3. Select reviewers for the pull request. You can select multiple reviewers. The reviewers will be notified and will review your code. You can also add comments to the pull request. 4. After the reviewers approve the pull request, you can merge the pull request. :warning: :warning: **Pull requests must be reviewed and approved by other team members before merging.** :warning: :warning: **Reviewing and approving pull requests will be a part of the evaluation.** 5. After the pull request is merged, the linked issue will be automatically closed. You can verify that the issue is closed by navigating to the issues page and project page. ![](images/closed_issue.png) ![](images/closed_project.png) 6. (Optional) Delete the feature branch after the pull request is merged. You can delete the branch by navigating to the **View all branches** page. 7. (Optional) If the feature is not completed or you want to continue working on the feature, you can reopen the issue and create new pull requests. Remember to change the status of the issue to **In Progress**. ## More Project Management and Other Resoruces (Optional) - Use issues to keep track of bugs, tasks and other things that need to be done by selecting the appropriate labels. - Use milestones to group issues into a set of deliverables. To create milestones, navigate to the **Milestones** tab and click **New milestone**. - Use Projects to tracks issues and collaborate with your team. See the [sample project (Password Manager example)](https://github.com/orgs/CSC207-2022F-UofT/projects/2) for reference. - Github document for projects: https://docs.github.com/en/issues/planning-and-tracking-with-projects - Git operations: https://docs.github.com/en/get-started/using-git - Git cheat sheet: https://education.github.com/git-cheat-sheet-education.pdf - I MESSED UP GIT WHAT TO DO?!: https://dangitgit.com/ |
Deleted screenshots.webp.
cannot compute difference between binary files
Changes to src/main/java/com/mg105/Application.java.
︙ | ︙ | |||
11 12 13 14 15 16 17 | import com.mg105.interface_adapters.battle.BattlePresenter; import com.mg105.interface_adapters.inventory.InventoryController; import com.mg105.interface_adapters.inventory.InventoryPresenter; import com.mg105.interface_adapters.map.MapGeneratorInterpreter; import com.mg105.interface_adapters.map.MinimapInterpreter; import com.mg105.interface_adapters.map.RoomInterpreter; import com.mg105.interface_adapters.map.RoomInterpreterInterface; | > > | > > < > > > > | > > > | > < < < | > > | | < < < > > > > > > > > | > > | > > > > > > | > > | | < < < < < < < < < < < < < | | < < < > < < | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | import com.mg105.interface_adapters.battle.BattlePresenter; import com.mg105.interface_adapters.inventory.InventoryController; import com.mg105.interface_adapters.inventory.InventoryPresenter; import com.mg105.interface_adapters.map.MapGeneratorInterpreter; import com.mg105.interface_adapters.map.MinimapInterpreter; import com.mg105.interface_adapters.map.RoomInterpreter; import com.mg105.interface_adapters.map.RoomInterpreterInterface; import com.mg105.interface_adapters.tutorial.TutorialTextController; import com.mg105.use_cases.ChestInteractor; import com.mg105.use_cases.OpponentSetInteractor; import com.mg105.use_cases.ReplayGenerator; import com.mg105.use_cases.WalkVisInteractor; import com.mg105.use_cases.battle.BattleInteractor; import com.mg105.use_cases.inventory.InventoryInteractor; import com.mg105.use_cases.map.*; import com.mg105.use_cases.save.PartySaver; import com.mg105.use_cases.save.Save; import com.mg105.use_cases.save.Saver; import com.mg105.use_cases.set_up.data_system_creator.CreateDataStorage; import com.mg105.use_cases.set_up.data_system_creator.DataStorageSystemCreator; import com.mg105.use_cases.set_up.state_setter.GameStateSetter; import com.mg105.use_cases.set_up.state_setter.PartyCreator; import com.mg105.user_interface.*; import javafx.scene.input.KeyEvent; import javafx.stage.Stage; import java.awt.*; import java.util.HashMap; import java.util.Map; /** * Effectively, the main class that sets up the clean architecture mountain group 105 game! */ public class Application extends javafx.application.Application { /** * Note that while this isn't our main method explicitly, we (probably) need this to effectively be our main method * for scoping rules. * * @param primaryStage the primary stage for this application. */ @Override public void start(Stage primaryStage) { // Set up the initial use cases Inventory inventory = new Inventory(); GameState state = new GameState(inventory, new WalkingCharacter(new Point(1, 1))); // Setting up database CreateDataStorage[] databaseCreators = {new MoveDataCreator(), new PartyDataCreator()}; DataStorageSystemCreator databaseCreator = new DataStorageSystemCreator(databaseCreators); databaseCreator.create(); // Setting the values from the database in game state PartyCreator[] partyCreator = {new PartyCreator(new PartyDataAccess(new MoveDataAccess()))}; GameStateSetter setter = new GameStateSetter(partyCreator); setter.setState(state); Map<Toggler.ToggleableComponent, Toggleable> drawableComponents = new HashMap<>(); // We fill this map in later because of the ordering of parameters SceneController sceneController = new SceneController( primaryStage, drawableComponents, Toggler.ToggleableComponent.MAP ); MapGenerator mapGenerator = new MapGenerator(state); MapGeneratorInterpreter mapGeneratorInterpreter = new MapGeneratorInterpreter(mapGenerator); MapGeneratorButton generateMapButton = new MapGeneratorButton(mapGeneratorInterpreter, sceneController); MainMenu mainMenu = new MainMenu(generateMapButton); RoomGetterInterface roomGetter = new RoomGetter(state); RoomInterpreterInterface roomInterpreter = new RoomInterpreter(roomGetter); MapDrawer mapDrawer = new MapDrawer(roomInterpreter); drawableComponents.put(Toggler.ToggleableComponent.MAIN_MENU, mainMenu); drawableComponents.put(Toggler.ToggleableComponent.MAP, mapDrawer); // Minimap setup MinimapInterpreter minimapInterpreter = new MinimapInterpreter(roomGetter); MinimapDrawer minimapDrawer = new MinimapDrawer(minimapInterpreter); drawableComponents.put(Toggler.ToggleableComponent.MINIMAP, minimapDrawer); // InventoryDisplay set up InventoryPresenter inventoryPresenter = new InventoryPresenter(); InventoryInteractor inventoryInteractor = new InventoryInteractor(state, inventoryPresenter); InventoryDisplay inventoryDisplay = new InventoryDisplay(new InventoryController( inventoryInteractor)); inventoryPresenter.setView(inventoryDisplay); drawableComponents.put(Toggler.ToggleableComponent.INVENTORY, inventoryDisplay); /////Tutorial scene//// TutorialTextController textChanger = new TutorialTextController(false); TutorialTextDisplay textDisplay = new TutorialTextDisplay(); TutorialTextWindow tutorialDisplay = new TutorialTextWindow(textChanger, textDisplay); drawableComponents.put(Toggler.ToggleableComponent.TUTORIAL, tutorialDisplay); ////////////////////// //WalkingMenu scene// WalkVisInteractor walkVisInteractor = new WalkVisInteractor(state); WalkVisController walkVisController = new WalkVisController(walkVisInteractor); WalkingMenu walkingMenu = new WalkingMenu(walkVisController); drawableComponents.put(Toggler.ToggleableComponent.WALK_MENU, walkingMenu); ///////////////////// //LoseMenu scene// ReplayGenerator replayGenerator = new ReplayGenerator(state, minimapInterpreter); replayGenerator.replay(); ReplayGeneratorInterpreter replayGeneratorInterpreter = new ReplayGeneratorInterpreter(replayGenerator); ReplayGeneratorButton loseButton = new ReplayGeneratorButton(replayGeneratorInterpreter, sceneController, Toggler.ToggleableComponent.LOSE_MENU); LoseMenu loseMenu = new LoseMenu(loseButton); drawableComponents.put(Toggler.ToggleableComponent.LOSE_MENU, loseMenu); //////////////////// //BattleMenu scene// //OpponentSet setup OpponentSetInteractor opponentInteractor = new OpponentSetInteractor(state); // Creating Saver Save[] savers = {new PartySaver(state, new PartyDataAccess(new MoveDataAccess()))}; Saver saver = new Saver(savers); //Battle setup BattleInteractor battleInteractor = new BattleInteractor(state, inventoryInteractor, saver); BattlePresenter battlePresenter = new BattlePresenter(battleInteractor, sceneController); BattleMenu battleMenu = new BattleMenu(battlePresenter); drawableComponents.put(Toggler.ToggleableComponent.BATTLE, battleMenu); ///////////////////// RoomUpdater roomUpdater = new RoomUpdater(); roomUpdater.addObserver(mapDrawer); roomUpdater.addObserver(minimapInterpreter); CharacterMoverInterface characterMover = new CharacterMover(state, roomUpdater); /////WinGame Scene///// ReplayGeneratorButton winButton = new ReplayGeneratorButton(replayGeneratorInterpreter, sceneController, Toggler.ToggleableComponent.WIN_MENU); WinMenu winMenu = new WinMenu(winButton); WinDisplay winDisplay = new WinDisplay(sceneController, roomGetter, replayGenerator); roomUpdater.addObserver(winDisplay); drawableComponents.put(Toggler.ToggleableComponent.WIN_MENU, winMenu); ///////////////// ChestInteractor chestInteractor = new ChestInteractor(state, inventoryInteractor, roomUpdater); InputInterpreter inputInterpreter = new InputInterpreter(characterMover, sceneController, textChanger, chestInteractor, opponentInteractor); InputListener inputListener = new InputListener(inputInterpreter); primaryStage.addEventFilter(KeyEvent.KEY_TYPED, inputListener); sceneController.toggle(Toggler.ToggleableComponent.MAIN_MENU); primaryStage.setResizable(false); primaryStage.show(); } } |
Added src/main/java/com/mg105/entities/GiveTutorial.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package com.mg105.entities; import com.mg105.utils.TutorialTexts; /** * Data for what actions player has completed, contains methods for mutating the data */ public class GiveTutorial { private boolean moved; private boolean attacked; private boolean usedItem; /** * Constructor for GiveTutorial entity * * @param moved whether player has moved * @param attacked whether player has attacked * @param usedItem whether player has opened a chest */ public GiveTutorial(boolean moved, boolean attacked, boolean usedItem) { this.moved = moved; this.attacked = attacked; this.usedItem = usedItem; } /** * Set moved, attacked, usedItem to true if they have been performed by player * <p> * action should be a valid action * * @param action the action that has been performed */ public void actionPerformedSetter(String action) { if (action.equalsIgnoreCase(TutorialTexts.MOVED)) { this.moved = true; } else if (action.equalsIgnoreCase(TutorialTexts.ATTACKED)) { this.attacked = true; } else if (action.equalsIgnoreCase(TutorialTexts.USED_ITEM)) { this.usedItem = true; } } /** * Get if player has moved, attacked, and usedItem. * <p> * action should be a valid action * * @param action the action that is checked * @return whether the player has performed each action */ public boolean actionPerformedGetter(String action) { if (action.equalsIgnoreCase(TutorialTexts.MOVED)) { return this.moved; } else if (action.equalsIgnoreCase(TutorialTexts.ATTACKED)) { return this.attacked; } else if (action.equalsIgnoreCase(TutorialTexts.USED_ITEM)) { return this.usedItem; } else { return false; } } } |
Deleted src/main/java/com/mg105/interface_adapters/InputControllable.java.
|
| < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/interface_adapters/InputInterpreter.java.
1 2 3 4 5 6 7 8 | package com.mg105.interface_adapters; import com.mg105.use_cases.ChestInteractor; import com.mg105.use_cases.OpponentSetInteractor; import com.mg105.use_cases.map.CharacterMoverInterface; import org.jetbrains.annotations.NotNull; import java.awt.*; | > > < < | | | < > < < < < | < | | < < < < > < < < < < < < < < < | < < > | > > > | > > > | > > > | > > > > > > > > > > > > > | > > > > > > | > > | | > | | < | > | > | > | | > < < < < < < < < < < < < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | package com.mg105.interface_adapters; import com.mg105.interface_adapters.tutorial.TutorialTextController; import com.mg105.use_cases.ChestInteractor; import com.mg105.use_cases.OpponentSetInteractor; import com.mg105.use_cases.map.CharacterMoverInterface; import com.mg105.utils.TutorialTexts; import org.jetbrains.annotations.NotNull; import java.awt.*; /** * InputInterpreter takes in keyboard inputs and distributes them to their appropriate use cases. */ public class InputInterpreter { private final @NotNull CharacterMoverInterface mover; private final @NotNull Toggler toggler; private final @NotNull ChestInteractor chestInteractor; private final @NotNull TutorialTextController textChanger; private final @NotNull OpponentSetInteractor opponentInteractor; /** * Create a new InputInterpreter that translates keyboard inputs to appropriate function invocations. * * @param mover the character mover. * @param toggler the toggler used to change the displayed interface. * @param textChanger the text controller for tutorial * @param chestInteractor the ChestInteractor used to interact with chests. * @param opponentInteractor the interactor used to interact with opponents. */ public InputInterpreter(@NotNull CharacterMoverInterface mover, @NotNull Toggler toggler, @NotNull TutorialTextController textChanger, @NotNull ChestInteractor chestInteractor, @NotNull OpponentSetInteractor opponentInteractor) { this.mover = mover; this.toggler = toggler; this.textChanger = textChanger; this.opponentInteractor = opponentInteractor; this.chestInteractor = chestInteractor; } /** * Interpret key being pressed as an action. * * @param key the key being pressed as a string. */ public void interpret(String key) { switch (toggler.getCurrentComponent()) { case MAP -> { switch (key) { case "w" -> { mover.generateMapMoveBy(new Point(0, -1)); textChanger.getTutorial().setActionPerformed(TutorialTexts.MOVED); } case "a" -> { mover.generateMapMoveBy(new Point(-1, 0)); textChanger.getTutorial().setActionPerformed(TutorialTexts.MOVED); } case "s" -> { mover.generateMapMoveBy(new Point(0, 1)); textChanger.getTutorial().setActionPerformed(TutorialTexts.MOVED); } case "d" -> { mover.generateMapMoveBy(new Point(1, 0)); textChanger.getTutorial().setActionPerformed(TutorialTexts.MOVED); } case "k" -> { toggler.toggle(Toggler.ToggleableComponent.TUTORIAL); textChanger.setShowControls(true); } case "t" -> { toggler.toggle(Toggler.ToggleableComponent.TUTORIAL); textChanger.setChangeText(); } case "e" -> { chestInteractor.getChestItem(); // tutorial only cares that you pick up item, not that you use it textChanger.getTutorial().setActionPerformed(TutorialTexts.USED_ITEM); } case "i" -> toggler.toggle(Toggler.ToggleableComponent.INVENTORY); case " " -> //There is a warning if curly brackets are used on this block. // I don't know what is correct to do in this situation. toggler.toggle(Toggler.ToggleableComponent.WALK_MENU); case "f" -> { if (opponentInteractor.setOpponentSet()) { toggler.toggle(Toggler.ToggleableComponent.BATTLE); textChanger.getTutorial().setActionPerformed(TutorialTexts.ATTACKED); } } case "m" -> toggler.toggle(Toggler.ToggleableComponent.MINIMAP); } } case TUTORIAL -> { switch (key) { case "w", "a", "s", "d" -> { toggler.toggle(Toggler.ToggleableComponent.TUTORIAL); textChanger.setChangeText(); } case "k" -> textChanger.setShowControls(true); } } case WALK_MENU -> { if (key.equals(" ")) { toggler.toggle(Toggler.ToggleableComponent.WALK_MENU); } } case MINIMAP -> toggler.toggle(Toggler.ToggleableComponent.MINIMAP); case INVENTORY -> { if (key.equals("i")) { toggler.toggle(Toggler.ToggleableComponent.INVENTORY); } } } } } |
Deleted src/main/java/com/mg105/interface_adapters/PartyGetter.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/interface_adapters/Toggler.java.
︙ | ︙ | |||
21 22 23 24 25 26 27 | @NotNull ToggleableComponent getCurrentComponent(); /** * All the possible components that could theoretically be toggled. */ enum ToggleableComponent { /** | < < < < < < > > > > | | < < < < < < < | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | @NotNull ToggleableComponent getCurrentComponent(); /** * All the possible components that could theoretically be toggled. */ enum ToggleableComponent { /** * The main menu */ MAIN_MENU, /** * The main map */ MAP, /** * The minimap */ MINIMAP, /** * The inventory menu */ INVENTORY, /** * The battle menu */ BATTLE, /** * The tutorial window */ TUTORIAL, /** * The character selection screen. */ WALK_MENU, /** * The game Lose menu */ LOSE_MENU, /** * The game Win menu */ WIN_MENU } } |
Changes to src/main/java/com/mg105/interface_adapters/battle/BattlePresenter.java.
︙ | ︙ | |||
111 112 113 114 115 116 117 | * * @return a String of the name of the moving character */ public String roundStart() { return interactor.roundStart(); } | < < < < < < < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | * * @return a String of the name of the moving character */ public String roundStart() { return interactor.roundStart(); } /** * Returns the name of every BattleCharacter which can be targeted by the given move. * Note: Function should only be called from view when caster is friendly, so method does not accommodate for case * where caster is an opponent. * * @param moveNum integer representing which of the two Moves is being used. * @param casterName String representing the name of the given moving BattleCharacter. |
︙ | ︙ |
Changes to src/main/java/com/mg105/interface_adapters/inventory/InventoryPresenter.java.
︙ | ︙ | |||
48 49 50 51 52 53 54 | * @param itemDetails the state of the item that was potentially used * @see ItemDetails * @see InventoryViewInterface */ @Override public void addItem(boolean isSuccessful, ItemDetails itemDetails) { if (isSuccessful) { | | | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | * @param itemDetails the state of the item that was potentially used * @see ItemDetails * @see InventoryViewInterface */ @Override public void addItem(boolean isSuccessful, ItemDetails itemDetails) { if (isSuccessful) { this.display.alert("Successfully added a " + itemDetails.getName() + "."); return; } this.display.alert(itemDetails.getName() + " could not be added. The inventory might be full, try removing an item."); } /** * Sends an alert the view about the status of the potentially removed item. * Also updates the view to display the appropriate amount of items left fo that type * * @param isSuccessful if an item of itemName was removed from the inventory * @param itemDetails the state of the item that was potentially used * @see ItemDetails * @see InventoryViewInterface */ @Override public void removeItem(boolean isSuccessful, ItemDetails itemDetails) { if (!isSuccessful) { this.display.alert("Could not remove a " + itemDetails.getDescription() + "."); return; } this.display.alert("Successfully removed a " + itemDetails.getName() + "."); if (itemDetails.getCount() == 0) { this.display.removeItemView(itemDetails.getName()); return; } |
︙ | ︙ |
Changes to src/main/java/com/mg105/interface_adapters/map/RoomInterpreter.java.
︙ | ︙ | |||
26 27 28 29 30 31 32 | * Get the current room as represented in an easier to draw grid. * * @return the room as a 2 dimension array of TileType representing the current state of the room. Note that (0, 0) * represents the top-left corner and (MapConstants.ROOM_SIZE, MapConstants.ROOM_SIZE) represents the bottom * right corner. */ @Override | | | | > > > | > > | | < < | < < > | > > > | < < < | | | > > > > > > > > > > > > > > > > > > > > | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | * Get the current room as represented in an easier to draw grid. * * @return the room as a 2 dimension array of TileType representing the current state of the room. Note that (0, 0) * represents the top-left corner and (MapConstants.ROOM_SIZE, MapConstants.ROOM_SIZE) represents the bottom * right corner. */ @Override public RoomTileType[][] getCurrentRoom() { RoomTileType[][] canvas = new RoomTileType[MapConstants.ROOM_SIZE][MapConstants.ROOM_SIZE]; for (int y = 1; y < MapConstants.ROOM_SIZE - 1; y++) { for (int x = 1; x < MapConstants.ROOM_SIZE - 1; x++) { canvas[y][x] = RoomTileType.FLOOR; } } for (int i = 0; i < MapConstants.ROOM_SIZE; i++) { canvas[i][MapConstants.ROOM_SIZE - 1] = RoomTileType.WALL; canvas[i][0] = RoomTileType.WALL; } for (int i = 1; i < MapConstants.ROOM_SIZE - 1; i++) { canvas[MapConstants.ROOM_SIZE - 1][i] = RoomTileType.WALL_WITH_FACE; canvas[0][i] = RoomTileType.WALL_WITH_FACE; } canvas[MapConstants.ROOM_SIZE - 1][0] = RoomTileType.WALL_WITH_FACE; canvas[MapConstants.ROOM_SIZE - 1][MapConstants.ROOM_SIZE - 1] = RoomTileType.WALL_WITH_FACE; RoomLayout room = getter.getCurrentRoomLayout(); for (Point doorway : room.getDoorways()) { canvas[doorway.y][doorway.x] = RoomTileType.EXIT; if (doorway.x == 0 || doorway.x == MapConstants.ROOM_SIZE - 1) { canvas[doorway.y - 1][doorway.x] = RoomTileType.WALL_WITH_FACE; } } for (Point chest : room.getClosedChests()) { canvas[chest.y][chest.x] = RoomTileType.CHEST; } for (Point chest : room.getOpenChests()) { canvas[chest.y][chest.x] = RoomTileType.CHEST_OPEN; } for (Point opponents : room.getOpponents()) { canvas[opponents.y][opponents.x] = RoomTileType.OPPONENT_SET; } return canvas; } /** * Get the current player position in the room. * * @return the current player position in the room. */ @Override public @NotNull Point getPlayer() { return getter.getCurrentRoomLayout().getPlayer(); } /** * Retrieves the sprite String currently associated with the WalkingCharacter. * * @return a file name/location as a String for the desired character sprite. */ @Override public @NotNull String getCharacterSprite() { return this.getter.getWalkingSprite(); } } |
Changes to src/main/java/com/mg105/interface_adapters/map/RoomInterpreterInterface.java.
1 2 3 4 5 6 7 8 9 | package com.mg105.interface_adapters.map; import org.jetbrains.annotations.NotNull; /** * Layout the current room. */ public interface RoomInterpreterInterface { /** | > > | | > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package com.mg105.interface_adapters.map; import org.jetbrains.annotations.NotNull; import java.awt.*; /** * Layout the current room. */ public interface RoomInterpreterInterface { /** * Lay out the current room as a square of tiles to be displayed. * * @return the state of the current room. */ RoomTileType[][] getCurrentRoom(); /** * Get the position of the player within the room. * * @return the position of the player within the room. */ @NotNull Point getPlayer(); /** * Get the path of the current character sprite. * * @return the path of the current character sprite */ @NotNull String getCharacterSprite(); } |
Deleted src/main/java/com/mg105/interface_adapters/map/RoomState.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/interface_adapters/map/RoomTileType.java.
1 2 3 4 5 6 7 8 9 10 11 | package com.mg105.interface_adapters.map; /** * Types of tiles that can appear within a room. */ public enum RoomTileType { /** * Wall that cannot be walked on. Mainly used for the border */ WALL, /** | > > > > | | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package com.mg105.interface_adapters.map; /** * Types of tiles that can appear within a room. */ public enum RoomTileType { /** * Empty floor that can be walked on */ FLOOR, /** * Wall that cannot be walked on. Mainly used for the border */ WALL, /** * A wall where you can see the side */ WALL_WITH_FACE, /** * A doorway */ EXIT, /** * A treasure chest */ CHEST, /** * A treasure chest that has been opened */ |
︙ | ︙ |
Added src/main/java/com/mg105/interface_adapters/tutorial/TutorialTextController.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | package com.mg105.interface_adapters.tutorial; import com.mg105.use_cases.PlayerGetsTutorial; import com.mg105.utils.TutorialTexts; import java.util.List; /** * A controller that converts phase number into displayed text */ public class TutorialTextController { private final PlayerGetsTutorial tutorial = new PlayerGetsTutorial(TutorialTexts.PHASES, 0); private boolean changeText; private boolean showControls = false; /** * A constructor for the tutorial controller * * @param changeText whether to initially change the text. */ public TutorialTextController(boolean changeText) { this.changeText = changeText; } /** * Gets the current text that should be displayed * * @return what the text displayed at the bottom of the screen should be */ public String bottomText() { return tutorial.allPhases().get(tutorial.currentPhase()); } /** * Go to the next tutorial phase */ public void nextPhase() { this.tutorial.nextPhase(); } /** * Make text start changing */ public void setChangeText() { this.changeText = !this.changeText; } /** * Check if tutorial phases should advance * * @return if text should start changing */ public boolean changeText() { return this.changeText; } /** * Check if player should be shown controls again * * @return whether player should be shown the control texts */ public boolean getShowControls() { return this.showControls; } /** * Tell player the controls again * * @param show the text on the screen when true */ public void setShowControls(boolean show) { this.showControls = show; } /** * Get an instance of the PlayerGetsTutorial use case * * @return the tutorial instance */ public PlayerGetsTutorial getTutorial() { return this.tutorial; } /** * Get if the tutorial is complete, changes text if it is * * @return if the tutorial is complete */ public boolean isComplete() { return tutorial.isComplete(); } /** * Returns if the action has been performed * * @param action that is checked * @return if the specified action has been performed */ public boolean getActionPerformed(String action) { return !tutorial.getActionPerformed(action); } /** * Get names of all phases of tutorial * * @return the list of all tutorial phases */ public List<String> allPhases() { return tutorial.allPhases(); } } |
Deleted src/main/java/com/mg105/use_cases/PartyStatGetter.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/main/java/com/mg105/use_cases/PlayerGetsTutorial.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | package com.mg105.use_cases; import com.mg105.entities.GiveTutorial; import com.mg105.utils.TutorialTexts; import java.util.List; /** * Class for determining what phase of the tutorial the player is on, and changing the phase */ public class PlayerGetsTutorial { private final List<String> tutorialPhases; // Go through multiple phases of tutorial in order private final GiveTutorial tutorial; private int currentPhase; /** * Constructor for PlayerGetsTutorial use case * * @param tutorialPhases a list of all possible phases in the tutorial * @param currentPhase the integer representing what phase the player is on in the tutorial */ public PlayerGetsTutorial(List<String> tutorialPhases, int currentPhase) { this.tutorialPhases = tutorialPhases; this.currentPhase = currentPhase; this.tutorial = new GiveTutorial(false, false, false); } /** * Check if all required actions performed by player * * @return whether all actions are complete */ public boolean isComplete() { return tutorial.actionPerformedGetter(TutorialTexts.MOVED) & tutorial.actionPerformedGetter(TutorialTexts.ATTACKED) & tutorial.actionPerformedGetter(TutorialTexts.USED_ITEM); } /** * Get names of all phases of tutorial * * @return the list of all tutorial phases */ public List<String> allPhases() { return this.tutorialPhases; } /** * Get current phase of tutorial, which is first index of phase list * * @return the current phase of tutorial */ public int currentPhase() { return this.currentPhase; } /** * Advance current phase by 1 */ public void nextPhase() { if (currentPhase < TutorialTexts.PHASES.size() - 1) { this.currentPhase++; } } /** * Set the action to true if it has been performed * * @param action to set to performed */ public void setActionPerformed(String action) { this.tutorial.actionPerformedSetter(action); } /** * Check if specific action has been performed * * @param action get if it has been performed yet * @return if the action has been performed */ public boolean getActionPerformed(String action) { return this.tutorial.actionPerformedGetter(action); } } |
Changes to src/main/java/com/mg105/use_cases/ReplayGenerator.java.
1 2 3 4 5 6 7 8 9 10 11 12 | package com.mg105.use_cases; import com.mg105.entities.BattleCharacter; import com.mg105.entities.GameState; import com.mg105.entities.items.MegaPotion; import com.mg105.utils.PartyConstants; import org.jetbrains.annotations.NotNull; /** * A class that implement the game restart and replay function. * this class have players' attribute inheritance method and players' inventory clean method. | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.mg105.use_cases; import com.mg105.entities.BattleCharacter; import com.mg105.entities.GameState; import com.mg105.entities.items.MegaPotion; import com.mg105.use_cases.map.MapGenerator; import com.mg105.utils.PartyConstants; import org.jetbrains.annotations.NotNull; /** * A class that implement the game restart and replay function. * this class have players' attribute inheritance method and players' inventory clean method. |
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 | //Party is empty, fainted is full. state.getParty().addAll(state.getFainted()); state.getFainted().removeAll(state.getParty()); this.inventoryClean(); this.attributeInheritance(); for (Resetable resetable : resetables) { resetable.reset(); } } } | > > > > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | //Party is empty, fainted is full. state.getParty().addAll(state.getFainted()); state.getFainted().removeAll(state.getParty()); this.inventoryClean(); this.attributeInheritance(); // incomplete remake, need to amend later. exactly implementation should depend // on other use cases' implementation MapGenerator isekai = new MapGenerator(state); isekai.generateMap(); for (Resetable resetable : resetables) { resetable.reset(); } } } |
Changes to src/main/java/com/mg105/use_cases/battle/BattleInteractor.java.
︙ | ︙ | |||
22 23 24 25 26 27 28 | private final static int MAX_UPGRADE_TOKEN_REWARDED = 3; private final GameState state; private final InventoryInteractor inventoryInteractor; private final Saver saver; private BattlePresenterInterface presenter; | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | private final static int MAX_UPGRADE_TOKEN_REWARDED = 3; private final GameState state; private final InventoryInteractor inventoryInteractor; private final Saver saver; private BattlePresenterInterface presenter; /** * Creates a new BattleInteractor with a reference to the GameState. * * @param state the GameState to be referred to. * @param inventoryInteractor the inventoryInteractor to be referred to. * @param saver an instance of Saver used to save data. |
︙ | ︙ | |||
67 68 69 70 71 72 73 | partyNames[i] = party.get(i).getName(); } for (int i = 0; i < opponents.size(); ++i) { opponentNames[i] = opponents.get(i).getName(); } | < < | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | partyNames[i] = party.get(i).getName(); } for (int i = 0; i < opponents.size(); ++i) { opponentNames[i] = opponents.get(i).getName(); } presenter.setViewNames(partyNames, opponentNames); } /** * Returns whether the given name is associated with a fainted character. * Assumes that the inputted name corresponds to a character who was in the encounter at some point. * |
︙ | ︙ | |||
149 150 151 152 153 154 155 | * If encounter is still in progress, get the next moving character. * If opponent is moving, choose a random move and random target and use it. * returns null iff the battle has ended * * @return a String of the name of the moving character */ public String roundStart() { | < < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | * If encounter is still in progress, get the next moving character. * If opponent is moving, choose a random move and random target and use it. * returns null iff the battle has ended * * @return a String of the name of the moving character */ public String roundStart() { int status = getBattleStatus(); if (Math.abs(status) == 1) { //Player either lost or won the battle return null; } else { //Battle is ongoing BattleCharacter moving = state.getCurrEncounter().getMovingCharacter(); if (moving.isOpponent()) { //Opponent character is moving Random rand = new Random(); int moveNumber = rand.nextInt(2); Move chosenMove; if (moveNumber == 0) { chosenMove = moving.getMoveOne(); } else { chosenMove = moving.getMoveTwo(); } if (!chosenMove.isFriendly()) { ArrayList<BattleCharacter> players = state.getCurrEncounter().getPlayerCharacters(); //Choose a random player character to attack int target = rand.nextInt(players.size()); this._useMove(chosenMove, moving, players.get(target)); } else { ArrayList<BattleCharacter> opponents = state.getCurrEncounter().getOpponents(); //Choose a random opponent to use the friendly move on int target = rand.nextInt(opponents.size()); this._useMove(chosenMove, moving, opponents.get(target)); } } //No matter what, the moving BattleCharacter's name is returned return moving.getName(); } } /** * Returns the name of every BattleCharacter which can be targeted by the given move. * Note: Function should only be called from view when caster is friendly, so method does not accommodate for case * where caster is an opponent. * * @param moveNum integer representing which of the two Moves is being used. * @param casterName String representing the name of the given moving BattleCharacter. |
︙ | ︙ |
Added src/main/java/com/mg105/user_interface/AlertBox.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | package com.mg105.user_interface; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Modality; import javafx.stage.Stage; /** * AlertBox is a component that creates a new window and display a users a message. * This message is usually related to if an action the user performed was successful or not. */ public class AlertBox { /** * Displays a modal that must be resolved before switches to a different window * * @param msg the message to display` */ public void display(String msg) { Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); window.setTitle("Alert"); window.setHeight(400); window.setWidth(400); window.setResizable(false); Label label = new Label(); label.setText(msg); Button close = new Button("Close"); close.setOnAction(e -> window.close()); VBox layout = new VBox(10); layout.getChildren().addAll(label, close); layout.setAlignment(Pos.CENTER); Scene scene = new Scene(layout, Color.LIGHTBLUE); window.setScene(scene); window.showAndWait(); } } |
Deleted src/main/java/com/mg105/user_interface/Alerter.java.
|
| < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/user_interface/BattleMenu.java.
1 2 | package com.mg105.user_interface; | < < < < < | | | | | < | | > | > | > > > > | | | > | | > > > | | | | | | | > > > > > > | | | < | < | | | | | < | > | | | | | < | < < < | | > > > < < > > | | | | | | | | > > | < | < | | < < < < < < | > | > | < < | | < | < < | > > > > | | | > > | < < < | > | | < < | < > > > | > | < | | > > > > > > > > > > | | > > < | < < < | | < < < < < | < < < < < < < < < < < < < < < < < | < < | | < < < | < < < < | < < | < < | < < < < < | < < < < < | < < < < < < < < < < | < | < < < < | < < < < < < < < < < | | | | > > > > | > > > > | > | | < | > > > > > > > > > > > > > > > | > > | > | > | | > | | | | > > > | > > > | > | | < < | | | | < > > > > > < | | > > | > > > > > < < < < > | > > | > > > > > > | < | < > > > > > > > > > > > | | > > > | > > > < > | > > > > > > > < < < < < > > > | > > | > > | > | > > > > > | | > > > > > > > < | | > | | > > > > | > > | > > > > > < | < | > > | < < | < | > > | < > > > > > > > > > | > > > | | < | | | > > > > > > > > | > > > > > > > | > > | > | > > > > > | | | > > > > > > > > > < < < | | < < < < | > > | > > > > > | < < > | | < | < | < < | < < < > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | package com.mg105.user_interface; import com.mg105.interface_adapters.battle.BattleMenuInterface; import com.mg105.interface_adapters.battle.BattlePresenter; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.GridPane; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; /** * This class uses JavaFX and is displayed during an active battle. */ public class BattleMenu implements EventHandler<ActionEvent>, BattleMenuInterface, Toggleable { private final BattlePresenter presenter; private final String[] playerNames = new String[4]; private final int[] playerHealth = new int[4]; private final int[] playerDmg = new int[4]; private final String[] opponentNames = new String[4]; private final int[] opponentHealth = new int[4]; private final int[] opponentDmg = new int[4]; private final Label p0 = new Label(); private final Label p1 = new Label(); private final Label p2 = new Label(); private final Label p3 = new Label(); private final Label o0 = new Label(); private final Label o1 = new Label(); private final Label o2 = new Label(); private final Label o3 = new Label(); private final Button nextRound; private final Button forfeit; private final Button moveOne; private final Button moveTwo; private final Button targetP0; private final Button targetP1; private final Button targetP2; private final Button targetP3; private final Button targetO0; private final Button targetO1; private final Button targetO2; private final Button targetO3; private final GridPane grid; private final Scene scene; private String moving; private int moveNum; /** * Creates a new BattleMenu. * Sets every UI element, except for labels which are set when the view is toggled on. * * @param battlePres the BattlePresenter to refer to (following MVP pattern) */ public BattleMenu(BattlePresenter battlePres) { this.presenter = battlePres; presenter.setView(this); grid = new GridPane(); grid.setVgap(10); grid.setHgap(10); grid.setAlignment(Pos.CENTER); nextRound = new Button("Next Round"); nextRound.setId("Next Round"); nextRound.setOnAction(this); grid.add(nextRound, 10, 30); forfeit = new Button("Forfeit"); forfeit.setId("Forfeit"); forfeit.setOnAction(this); grid.add(forfeit, 10, 2); grid.add(p0, 1, 4); grid.add(p1, 1, 8); grid.add(p2, 1, 12); grid.add(p3, 1, 16); grid.add(o0, 18, 4); grid.add(o1, 18, 8); grid.add(o2, 18, 12); grid.add(o3, 18, 16); targetP0 = new Button("TARGET"); targetP0.setOnAction(this); targetP0.setVisible(false); grid.add(targetP0, 0, 4); targetP1 = new Button("TARGET"); targetP1.setOnAction(this); targetP1.setVisible(false); grid.add(targetP1, 0, 8); targetP2 = new Button("TARGET"); targetP2.setOnAction(this); targetP2.setVisible(false); grid.add(targetP2, 0, 12); targetP3 = new Button("TARGET"); targetP3.setOnAction(this); targetP3.setVisible(false); grid.add(targetP3, 0, 16); targetO0 = new Button("TARGET"); targetO0.setOnAction(this); grid.add(targetO0, 19, 4); targetO0.setVisible(false); targetO1 = new Button("TARGET"); targetO1.setOnAction(this); targetO1.setVisible(false); grid.add(targetO1, 19, 8); targetO2 = new Button("TARGET"); targetO2.setOnAction(this); targetO2.setVisible(false); grid.add(targetO2, 19, 12); targetO3 = new Button("TARGET"); targetO3.setOnAction(this); targetO3.setVisible(false); grid.add(targetO3, 19, 16); moveOne = new Button(""); moveOne.setOnAction(this); moveOne.setVisible(false); moveTwo = new Button(""); moveTwo.setOnAction(this); moveTwo.setVisible(false); scene = new Scene(grid, 800, 800); } /** * Sets the names of the player and opponent characters participating in the active battle. * * @param playerNames array of name Strings representing player characters. * @param opponentNames array of name Strings representing opponents. */ @Override public void setNames(String[] playerNames, String[] opponentNames) { for (int i = 0; i < 4; ++i) { //Check if any player characters have fainted. Opponent set will always contain four characters initially. if (playerNames.length <= i) { this.playerNames[i] = "FAINTED"; this.playerHealth[i] = 0; this.playerDmg[i] = 0; } else { this.playerNames[i] = playerNames[i]; this.playerHealth[i] = presenter.givenCharacterHealth(this.playerNames[i]); this.playerDmg[i] = presenter.givenCharacterDamage(this.playerNames[i]); } this.opponentNames[i] = opponentNames[i]; this.opponentHealth[i] = presenter.givenCharacterHealth(this.opponentNames[i]); this.opponentDmg[i] = presenter.givenCharacterDamage(this.opponentNames[i]); } } /** * Updates the display corresponding to the given affected character. * * @param character the character who needs to be updated on the screen. */ @Override public void updateCharacter(String character) { if (playerNames[0].equals(character)) { updateCharacterData(character, 0, p0, false); } else if (playerNames[1].equals(character)) { updateCharacterData(character, 1, p1, false); } else if (playerNames[2].equals(character)) { updateCharacterData(character, 2, p2, false); } else if (playerNames[3].equals(character)) { updateCharacterData(character, 3, p3, false); } else if (opponentNames[0].equals(character)) { updateCharacterData(character, 0, o0, true); } else if (opponentNames[1].equals(character)) { updateCharacterData(character, 1, o1, true); } else if (opponentNames[2].equals(character)) { updateCharacterData(character, 2, o2, true); } else if (opponentNames[3].equals(character)) { updateCharacterData(character, 3, o3, true); } } /** * Get the scene of this toggleable object. It is this scene that will be displayed. * * @return the scene to be displayed. */ @Override public @NotNull Scene getScene() { return this.scene; } /** * Set the visibility of this component. * * @param isVisible true if the Toggleable is now visible, false otherwise. If false the Toggleable is expected * to do nothing on ANY user inputs. */ @Override public void toggle(boolean isVisible) { if (isVisible) { presenter.startBattle(); //Will call setNames and update character data. setupCharacterLabel(p0, 0, false); setupCharacterLabel(p1, 1, false); setupCharacterLabel(p2, 2, false); setupCharacterLabel(p3, 3, false); setupCharacterLabel(o0, 0, true); setupCharacterLabel(o1, 1, true); setupCharacterLabel(o2, 2, true); setupCharacterLabel(o3, 3, true); nextRound.setDisable(false); } } /** * Handles button events. * NextRound will start the next round, which is handled in BattlePresenter. * The two move buttons represent a move to be selected, and will cause target buttons to appear next to valid * target characters and the move buttons to disappear. * The target buttons only become visible when the character they represent can be targeted with the selected move, * and pressing them will apply the move onto the character and make the target buttons disappear. * * @param event the event which occurred. */ @Override public void handle(ActionEvent event) { Object source = event.getSource(); if (source.equals(nextRound)) { nextRound.setDisable(true); moving = presenter.roundStart(); if (moving == null) { //Battle ended presenter.endBattle(); return; } //moving != null if (playerNames[0].equals(moving)) { int[] moveStats = presenter.givenCharacterMoveStats(moving); String[] moveNames = presenter.givenCharacterMoveNames(moving); grid.add(moveOne, 2, 4); moveOne.setVisible(true); grid.add(moveTwo, 3, 4); moveTwo.setVisible(true); moveOne.setText(moveNames[0] + "\n Hp: " + moveStats[0] + ", Dmg: " + moveStats[1]); moveTwo.setText(moveNames[1] + "\n Hp: " + moveStats[2] + ", Dmg: " + moveStats[3]); } else if (playerNames[1].equals(moving)) { int[] moveStats = presenter.givenCharacterMoveStats(moving); String[] moveNames = presenter.givenCharacterMoveNames(moving); grid.add(moveOne, 2, 8); moveOne.setVisible(true); grid.add(moveTwo, 3, 8); moveTwo.setVisible(true); moveOne.setText(moveNames[0] + "\n Hp: " + moveStats[0] + ", Dmg: " + moveStats[1]); moveTwo.setText(moveNames[1] + "\n Hp: " + moveStats[2] + ", Dmg: " + moveStats[3]); } else if (playerNames[2].equals(moving)) { int[] moveStats = presenter.givenCharacterMoveStats(moving); String[] moveNames = presenter.givenCharacterMoveNames(moving); grid.add(moveOne, 2, 12); moveOne.setVisible(true); grid.add(moveTwo, 3, 12); moveTwo.setVisible(true); moveOne.setText(moveNames[0] + "\n Hp: " + moveStats[0] + ", Dmg: " + moveStats[1]); moveTwo.setText(moveNames[1] + "\n Hp: " + moveStats[2] + ", Dmg: " + moveStats[3]); } else if (playerNames[3].equals(moving)) { int[] moveStats = presenter.givenCharacterMoveStats(moving); String[] moveNames = presenter.givenCharacterMoveNames(moving); grid.add(moveOne, 2, 16); moveOne.setVisible(true); grid.add(moveTwo, 3, 16); moveTwo.setVisible(true); moveOne.setText(moveNames[0] + "\n Hp: " + moveStats[0] + ", Dmg: " + moveStats[1]); moveTwo.setText(moveNames[1] + "\n Hp: " + moveStats[2] + ", Dmg: " + moveStats[3]); } else if (opponentNames[0].equals(moving) || opponentNames[1].equals(moving) || opponentNames[2].equals(moving) || opponentNames[3].equals(moving)) { //If opponent moved, re-enable nextRound button nextRound.setDisable(false); } } else if (source.equals(forfeit)) { presenter.endBattle(); } else if (source.equals(moveOne)) { moveNum = 1; displayTargets(); } else if (source.equals(moveTwo)) { moveNum = 2; displayTargets(); } else if (source.equals(targetP0)) { targetP0.setVisible(false); targetP1.setVisible(false); targetP2.setVisible(false); targetP3.setVisible(false); presenter.executeTurn(moveNum, moving, playerNames[0]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetP1)) { targetP0.setVisible(false); targetP1.setVisible(false); targetP2.setVisible(false); targetP3.setVisible(false); presenter.executeTurn(moveNum, moving, playerNames[1]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetP2)) { targetP0.setVisible(false); targetP1.setVisible(false); targetP2.setVisible(false); targetP3.setVisible(false); presenter.executeTurn(moveNum, moving, playerNames[2]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetP3)) { targetP0.setVisible(false); targetP1.setVisible(false); targetP2.setVisible(false); targetP3.setVisible(false); presenter.executeTurn(moveNum, moving, playerNames[3]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetO0)) { targetO0.setVisible(false); targetO1.setVisible(false); targetO2.setVisible(false); targetO3.setVisible(false); presenter.executeTurn(moveNum, moving, opponentNames[0]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetO1)) { targetO0.setVisible(false); targetO1.setVisible(false); targetO2.setVisible(false); targetO3.setVisible(false); presenter.executeTurn(moveNum, moving, opponentNames[1]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetO2)) { targetO0.setVisible(false); targetO1.setVisible(false); targetO2.setVisible(false); targetO3.setVisible(false); presenter.executeTurn(moveNum, moving, opponentNames[2]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } else if (source.equals(targetO3)) { targetO0.setVisible(false); targetO1.setVisible(false); targetO2.setVisible(false); targetO3.setVisible(false); presenter.executeTurn(moveNum, moving, opponentNames[3]); //Re-enable nextRound button after a move has been made. nextRound.setDisable(false); } } /** * Helper function for updateCharacter. * * @param character name String of the character to be updated. * @param position index of the character's data in the data arrays. * @param lbl Label object to be updated. * @param isOpponent boolean for whether the character is an opponent or not. */ private void updateCharacterData(String character, int position, Label lbl, boolean isOpponent) { if (presenter.givenCharacterFainted(character)) { lbl.setText("FAINTED"); return; } int[] hpData; int[] dmgData; String[] nameData; if (isOpponent) { hpData = opponentHealth; dmgData = opponentDmg; nameData = opponentNames; } else { hpData = playerHealth; dmgData = playerDmg; nameData = playerNames; } hpData[position] = presenter.givenCharacterHealth(character); dmgData[position] = presenter.givenCharacterDamage(character); lbl.setText(nameData[position] + "\n Hp: " + hpData[position] + ", Dmg: " + dmgData[position]); } /** * Helper function for moveOne/moveTwo button click events. * Removes the two buttons, retrieves targets based on the chosen move, displays respective target buttons. */ private void displayTargets() { moveOne.setVisible(false); moveTwo.setVisible(false); grid.getChildren().remove(moveOne); grid.getChildren().remove(moveTwo); ArrayList<String> targets = presenter.retrieveTargets(moveNum, moving); for (String s : targets) { if (playerNames[0].equals(s)) { targetP0.setVisible(true); } else if (playerNames[1].equals(s)) { targetP1.setVisible(true); } else if (playerNames[2].equals(s)) { targetP2.setVisible(true); } else if (playerNames[3].equals(s)) { targetP3.setVisible(true); } else if (opponentNames[0].equals(s)) { targetO0.setVisible(true); } else if (opponentNames[1].equals(s)) { targetO1.setVisible(true); } else if (opponentNames[2].equals(s)) { targetO2.setVisible(true); } else if (opponentNames[3].equals(s)) { targetO3.setVisible(true); } } } /** * Helper function to initialize the character labels. * * @param lbl Label object corresponding to the character. * @param position Integer representing index of character's data in data arrays. * @param isOpponent Boolean of whether the character is an opponent. */ private void setupCharacterLabel(Label lbl, int position, boolean isOpponent) { if (isOpponent) { lbl.setText(opponentNames[position] + "\n Hp: " + opponentHealth[position] + ", Dmg: " + opponentDmg[position]); } else { if (playerNames[position].equals("FAINTED")) { lbl.setText("FAINTED"); } else { lbl.setText(playerNames[position] + "\n Hp: " + playerHealth[position] + ", Dmg: " + playerDmg[position]); } } } } |
Deleted src/main/java/com/mg105/user_interface/IntroDisplay.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/user_interface/InventoryDisplay.java.
1 2 | package com.mg105.user_interface; | < < < | | > | | | < < < > | < < < < < < < | | | | | | < < > | < < < < | | < < < > > | > > > | < < < < < | | < > > | > > > > | | > > | | < > > | < > > > | < > > | > | | | | < > | | > | < > > | | < < | > > | > > > > > > > > > > > | > > > > > | > > < < < | | < < < < < < | < < < < | < | < < < < < < < < < < < < < < < < | < < < < < | < < < < < < < < < < | < < > | < < < < < < < < < < | < > | | < < < < < | < | < < < < | < < < < < < | < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | package com.mg105.user_interface; import com.mg105.interface_adapters.inventory.InventoryController; import com.mg105.interface_adapters.inventory.InventoryViewInterface; import com.mg105.utils.PartyConstants; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import org.jetbrains.annotations.NotNull; import java.util.HashMap; /** * A user interface class that displays the state of the inventory to the user and allows them to * perform actions that relate to the inventory and its items. */ public class InventoryDisplay implements InventoryViewInterface, Toggleable { private final HashMap<String, HBox> itemNameToInfo = new HashMap<>(); private final InventoryController controller; private Boolean isVisible = false; private VBox itemsDisplay; private String characterSelected = PartyConstants.ALL_PARTY_MEMBER_NAMES[0]; /** * Creates a new instance of inventory display * * @param controller an object that interprets user inputs to make changes about the inventory */ public InventoryDisplay(InventoryController controller) { this.controller = controller; } /** * Returns the character selected by the user * * @return the character selected by the user */ private String getCharacterSelected() { return this.characterSelected; } /** * Returns the dropdown where user can select a party member * * @return the dropdown where user can select a party member */ private @NotNull ComboBox<String> buildCharacterDropdown() { ComboBox<String> partySelector = new ComboBox<>(); partySelector.getItems().addAll(PartyConstants.ALL_PARTY_MEMBER_NAMES); partySelector.setOnAction(e -> this.characterSelected = partySelector.getSelectionModel().getSelectedItem()); partySelector.setValue(characterSelected); return partySelector; } /** * Returns the component that really has all the details necessary for the scene * * @return the component that really has all the details necessary for the scene */ private @NotNull VBox buildLayout() { this.itemsDisplay = new VBox(10); this.itemsDisplay.getChildren().add(new Label("Inventory")); controller.getInventoryDetails(); return new VBox(5, this.itemsDisplay, buildCharacterDropdown()); } /** * Returns the scene that displays the information for the Inventory * * @return the scene that displays the information for the Inventory. */ @Override public @NotNull Scene getScene() { return new Scene(buildLayout(), 800, 800, Color.LIGHTBLUE); } /** * Changes the state of the InventoryDisplay based on if the inventory display is shown in the ui * * @param isVisible true if the Toggleable is now visible, false otherwise. If false the Toggleable is expected * to do nothing on ANY user inputs. */ @Override public void toggle(boolean isVisible) { this.isVisible = isVisible; } /** * Removes an item from the inventory ui. * Precondition there must not be an items of the type name in the inventory * * @param name the name of the item to be removed */ @Override public void removeItemView(String name) { HBox itemInfo = this.itemNameToInfo.get(name); if (itemInfo == null) { return; } itemsDisplay.getChildren().remove(itemInfo); } /** * Opens a window displaying a message to the user * * @param msg the message to alert the user with */ @Override public void alert(String msg) { AlertBox alert = new AlertBox(); alert.display(msg); } /** * Adds the details of the item to the display * * @param name the name of the item to add * @param description the description of the item to add * @param isUsable true iff the item can be used by a user * @param quantity the number of items of this type in the Inventory */ @Override public void addItemView(String name, String description, boolean isUsable, String quantity) { if (!this.isVisible) { return; } Label nameLabel = new Label(name); Label descriptionLabel = new Label(description); Label quantityLabel = new Label(quantity); Button removeItem = new Button("Remove Item"); removeItem.setOnAction(e -> controller.removeItem(name)); HBox info = new HBox(10); if (isUsable) { info.getChildren().addAll(nameLabel, descriptionLabel, quantityLabel, getUseItemButton(name), removeItem); } else { info.getChildren().addAll(nameLabel, descriptionLabel, quantityLabel, removeItem); } itemsDisplay.getChildren().add(info); itemNameToInfo.put(name, info); } /** * Changes the details of an already displayed item and displays the changes * * @param name the name of the item to change details about * @param description the description of the item * @param isUsable true iff the item is usable * @param quantity the number of items of this type in the Inventory */ @Override public void changeItemView(String name, String description, boolean isUsable, String quantity) { HBox currentInfo = itemNameToInfo.get(name); if (currentInfo != null) { itemNameToInfo.remove(name); itemsDisplay.getChildren().remove(currentInfo); } addItemView(name, description, isUsable, quantity); } /** * Creates a use item button * * @param name of item to create use item button * @return the use item button */ private Button getUseItemButton(String name) { Button useItem = new Button("Use Item"); useItem.setOnAction(e -> controller.useItem(name, getCharacterSelected())); return useItem; } } |
Deleted src/main/java/com/mg105/user_interface/KeymapDisplay.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/user_interface/LoseMenu.java.
1 2 | package com.mg105.user_interface; | < < | | | | < < < | | < < | < | | | < < < < | | < < < | < < < < | | < < | < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package com.mg105.user_interface; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import org.jetbrains.annotations.NotNull; /** * LoseMenu is displayed when the player loses the game. */ public class LoseMenu implements Toggleable { private final @NotNull Scene scene; /** * Create a new LoseMenu * * @param replayButton the button that performs the replay action */ public LoseMenu(@NotNull ReplayGeneratorButton replayButton) { Button generateMapButton = new Button("Replay The Game"); //Clean Inventory generateMapButton.setOnAction(replayButton); @NotNull Pane layout = new StackPane(); layout.getChildren().add(generateMapButton); scene = new Scene(layout, 600, 600); } @Override public @NotNull Scene getScene() { return scene; } @Override public void toggle(boolean isVisible) { // Does nothing } } |
Changes to src/main/java/com/mg105/user_interface/MainMenu.java.
1 2 | package com.mg105.user_interface; | < < < < < < | | | | | < < < < < < < < | < | < < < < | < < < < | < < | < < < < < < | | < < < < < < < < | | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.mg105.user_interface; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import org.jetbrains.annotations.NotNull; /** * The main game menu. */ public class MainMenu implements Toggleable { private final @NotNull Scene scene; /** * Create a new MainMenu. * * @param startButton the button that starts the game. */ public MainMenu(@NotNull MapGeneratorButton startButton) { Button generateMapButton = new Button("Start Game"); generateMapButton.setOnAction(startButton); @NotNull Pane layout = new StackPane(); layout.getChildren().add(generateMapButton); scene = new Scene(layout, 600, 600); } @Override public @NotNull Scene getScene() { return scene; } @Override public void toggle(boolean isVisible) { // Does nothing, for now } } |
Changes to src/main/java/com/mg105/user_interface/MapDrawer.java.
1 2 3 | package com.mg105.user_interface; import com.mg105.interface_adapters.map.RoomInterpreterInterface; | < < < | | | | > | > > > > > > > > | > | | > | | | | | | | > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | package com.mg105.user_interface; import com.mg105.interface_adapters.map.RoomInterpreterInterface; import com.mg105.interface_adapters.map.RoomTileType; import com.mg105.utils.MapConstants; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import org.jetbrains.annotations.NotNull; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; import java.util.Objects; /** * MapDrawer draws the map as a grid of tiles. */ public class MapDrawer implements PropertyChangeListener, Toggleable { private final @NotNull RoomInterpreterInterface interpreter; private final @NotNull Scene scene; private final @NotNull Group group; private final @NotNull Map<RoomTileType, Image> tiles; private final @NotNull Map<String, Image> playerSprites; private final @NotNull Image missingTile; private boolean isVisible; /** * Create an instance of MapDrawer. * * @param interpreter the room interpreter used to format the data in an acceptable way for this class. */ public MapDrawer(@NotNull RoomInterpreterInterface interpreter) { this.interpreter = interpreter; group = new Group(); scene = new Scene( group, MapConstants.ROOM_SIZE * MapConstants.TILE_SIZE, MapConstants.ROOM_SIZE * MapConstants.TILE_SIZE ); isVisible = false; missingTile = new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/missing.png"))); tiles = new HashMap<>(6); tiles.put(RoomTileType.FLOOR, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/floor.png")))); tiles.put(RoomTileType.WALL, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/wall.png")))); tiles.put(RoomTileType.WALL_WITH_FACE, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/wall_face.png")))); tiles.put(RoomTileType.EXIT, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/exit.png")))); tiles.put(RoomTileType.CHEST, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/chest.png")))); tiles.put(RoomTileType.CHEST_OPEN, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/chest_open.png")))); tiles.put(RoomTileType.OPPONENT_SET, new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/tiles/battle.png")))); playerSprites = new HashMap<>(4); playerSprites.put("/sprites/A.png", new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/sprites/A.png")))); playerSprites.put("/sprites/B.png", new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/sprites/B.png")))); playerSprites.put("/sprites/C.png", new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/sprites/C.png")))); playerSprites.put("/sprites/D.png", new Image(Objects.requireNonNull(MapDrawer.class.getResourceAsStream("/sprites/D.png")))); // While in theory getResourceAsStream can fail, in practice this will never happen because the images are // bundled in the Jar. If this isn't the case then the NullPointerException is the least of your worries. } /** * Get the scene that will be used to draw to. * * @return the scene that the MapDrawer will draw to. */ @Override public @NotNull Scene getScene() { return scene; } /** * Toggle the visibility of map drawer. In this case we need to make sure the map drawing is up-to-date. * * @param isVisible true if the map is now visible, false otherwise. */ |
︙ | ︙ | |||
80 81 82 83 84 85 86 | } /** * Redraw the current room. This method only needs to be called if something has changed in the underlying * current room. */ public void updateRoom() { | | | < < < < < < < < < | > | > | | | < > < | < < < < | | | > > | | | < < < | | | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | } /** * Redraw the current room. This method only needs to be called if something has changed in the underlying * current room. */ public void updateRoom() { RoomTileType[][] room = interpreter.getCurrentRoom(); group.getChildren().clear(); for (int y = 0; y < MapConstants.ROOM_SIZE; y++) { for (int x = 0; x < MapConstants.ROOM_SIZE; x++) { ImageView tile = new ImageView(tiles.getOrDefault(room[y][x], missingTile)); tile.setPreserveRatio(true); tile.setX(x * MapConstants.TILE_SIZE); tile.setY(y * MapConstants.TILE_SIZE); tile.setFitHeight(MapConstants.TILE_SIZE); tile.setFitWidth(MapConstants.TILE_SIZE); group.getChildren().add(tile); } } Point player = interpreter.getPlayer(); ImageView playerTile = new ImageView(playerSprites.getOrDefault(interpreter.getCharacterSprite(), missingTile)); playerTile.setPreserveRatio(true); playerTile.setX(player.x * MapConstants.TILE_SIZE); playerTile.setY(player.y * MapConstants.TILE_SIZE); playerTile.setFitHeight(MapConstants.TILE_SIZE); playerTile.setFitWidth(MapConstants.TILE_SIZE); group.getChildren().add(playerTile); } /** * Update the current room based on evt. * <p> * Note that none of the properties of evt are used. * * @param evt A PropertyChangeEvent object describing the event source * and the property that has changed. */ @Override public void propertyChange(PropertyChangeEvent evt) { if (!isVisible) { // As per the specification of Toggleable, we do nothing if we are not visible. return; } updateRoom(); } } |
Changes to src/main/java/com/mg105/user_interface/MapGeneratorButton.java.
1 2 3 4 5 6 7 8 9 | package com.mg105.user_interface; import com.mg105.interface_adapters.Toggler; import com.mg105.interface_adapters.map.MapGeneratorInterpreterInterface; import org.jetbrains.annotations.NotNull; /** * MapGeneratorButton acts as the event handler for the actual JavaFX button that will generate a map. */ | > > | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package com.mg105.user_interface; import com.mg105.interface_adapters.Toggler; import com.mg105.interface_adapters.map.MapGeneratorInterpreterInterface; import javafx.event.ActionEvent; import javafx.event.EventHandler; import org.jetbrains.annotations.NotNull; /** * MapGeneratorButton acts as the event handler for the actual JavaFX button that will generate a map. */ public class MapGeneratorButton implements EventHandler<ActionEvent> { private final @NotNull MapGeneratorInterpreterInterface interpreter; private final @NotNull Toggler toggler; /** * Create a new MapGeneratorButton. * * @param interpreter the interpreter for the map generator button * @param toggler the toggler used to close the user interface once pressed. */ public MapGeneratorButton(@NotNull MapGeneratorInterpreterInterface interpreter, @NotNull Toggler toggler) { this.interpreter = interpreter; this.toggler = toggler; } /** * This method is called when the button is pressed. It passes control to the appropriate interpreter. * * @param event the event which occurred */ @Override public void handle(ActionEvent event) { interpreter.generateMap(); toggler.toggle(Toggler.ToggleableComponent.MAIN_MENU); } } |
Changes to src/main/java/com/mg105/user_interface/MinimapDrawer.java.
1 2 3 4 | package com.mg105.user_interface; import com.mg105.interface_adapters.map.MinimapInterpreterInterface; import com.mg105.interface_adapters.map.MinimapRoomState; | | | | | > > > > | > | > > | | | | | | < < < < < < < | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | package com.mg105.user_interface; import com.mg105.interface_adapters.map.MinimapInterpreterInterface; import com.mg105.interface_adapters.map.MinimapRoomState; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.shape.Line; import javafx.scene.shape.Rectangle; import org.jetbrains.annotations.NotNull; import java.awt.*; /** * Draw the Minimap. */ public class MinimapDrawer implements Toggleable { private static final int CANVAS_SIZE = 400; private static final @NotNull Color PATH_COLOR = Color.rgb(135, 160, 227); private static final @NotNull Color ROOM_COLOR = Color.rgb(205, 220, 255); private static final @NotNull Color CURRENT_ROOM_COLOR = Color.rgb(200, 150, 61); private static final @NotNull Color BACKGROUND_COLOR = Color.rgb(38, 44, 68); private final @NotNull MinimapInterpreterInterface interpreter; private final @NotNull Scene scene; private final @NotNull Group group; /** * Create a new MinimapDrawer. * * @param interpreter the MinimapInterpreter that will process room change data. */ public MinimapDrawer(@NotNull MinimapInterpreterInterface interpreter) { this.interpreter = interpreter; group = new Group(); scene = new Scene(group, CANVAS_SIZE, CANVAS_SIZE); scene.setFill(BACKGROUND_COLOR); } /** * Get the minimap scene. * * @return the minimap scene. */ @Override public @NotNull Scene getScene() { return scene; } /** * Toggle the minimap. * * @param isVisible true if the Toggleable is now visible, false otherwise. If false the Toggleable is expected * to do nothing on ANY user inputs. */ @Override public void toggle(boolean isVisible) { if (isVisible) { MinimapRoomState[][] map = interpreter.getMapSoFar(); Point currentPosition = interpreter.getCurrentPosition(); final int cellDimension = CANVAS_SIZE / Math.max(map.length, map[0].length); final int innerCellPadding = cellDimension / 6; final int topPadding = (CANVAS_SIZE - map.length * cellDimension) / 2; final int leftPadding = (CANVAS_SIZE - map[0].length * cellDimension) / 2; group.getChildren().clear(); for (int y = 0; y < map.length; y++) { for (int x = 0; x < map[y].length; x++) { // Shading for the current room if (currentPosition.x == x && currentPosition.y == y) { Rectangle r = new Rectangle(); r.setX(leftPadding + x * cellDimension); r.setY(topPadding + y * cellDimension); r.setWidth(cellDimension); r.setHeight(cellDimension); r.setFill(CURRENT_ROOM_COLOR); group.getChildren().add(r); } // Rectangle for each room if (map[y][x] == MinimapRoomState.EXPLORED) { // First we draw the middle square Rectangle r = new Rectangle(); r.setX(leftPadding + innerCellPadding + x * cellDimension); r.setY(topPadding + innerCellPadding + y * cellDimension); r.setWidth(cellDimension - 2 * innerCellPadding); r.setHeight(cellDimension - 2 * innerCellPadding); r.setFill(ROOM_COLOR); group.getChildren().add(r); // Now we draw the lines that sick out final int xMidpoint = leftPadding + x * cellDimension + cellDimension / 2; final int yMidpoint = topPadding + y * cellDimension + cellDimension / 2; final int strokeWidth = cellDimension / 10; final int strokeWidthCorrection = strokeWidth / 2; // Line coming out the top if (y > 0 && map[y - 1][x] != null) { Line l = new Line(); l.setStartX(xMidpoint); l.setEndX(xMidpoint); l.setStartY(topPadding + y * cellDimension + innerCellPadding - strokeWidthCorrection); l.setEndY(topPadding + y * cellDimension + strokeWidthCorrection); l.setStroke(PATH_COLOR); l.setStrokeWidth(strokeWidth); group.getChildren().add(l); } // Line coming out the bottom if (y < map.length - 1 && map[y + 1][x] != null) { Line l = new Line(); l.setStartX(xMidpoint); l.setEndX(xMidpoint); l.setStartY(topPadding + y * cellDimension + cellDimension - innerCellPadding + strokeWidthCorrection); l.setEndY(topPadding + y * cellDimension + cellDimension - strokeWidthCorrection); l.setStroke(PATH_COLOR); l.setStrokeWidth(strokeWidth); group.getChildren().add(l); } // Line coming out the left if (x > 0 && map[y][x - 1] != null) { Line l = new Line(); l.setStartX(leftPadding + x * cellDimension + innerCellPadding - strokeWidthCorrection); l.setEndX(leftPadding + x * cellDimension + strokeWidthCorrection); l.setStartY(yMidpoint); l.setEndY(yMidpoint); l.setStroke(PATH_COLOR); l.setStrokeWidth(strokeWidth); group.getChildren().add(l); } // Line coming out the right if (x < map[0].length - 1 && map[y][x + 1] != null) { Line l = new Line(); l.setStartX(leftPadding + x * cellDimension + cellDimension - innerCellPadding + strokeWidthCorrection); l.setEndX(leftPadding + x * cellDimension + cellDimension - strokeWidthCorrection); l.setStartY(yMidpoint); l.setEndY(yMidpoint); l.setStroke(PATH_COLOR); l.setStrokeWidth(strokeWidth); group.getChildren().add(l); } } } } } } } |
Deleted src/main/java/com/mg105/user_interface/MultiselectGrid.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/user_interface/ReplayGeneratorButton.java.
1 2 3 4 5 6 7 8 9 10 | package com.mg105.user_interface; import com.mg105.interface_adapters.ReplayGeneratorInterpreter; import com.mg105.interface_adapters.Toggler; import org.jetbrains.annotations.NotNull; /** * ReplayGeneratorButton acts as the event handler for the actual JavaFx button that will replay the game. */ | > > | > > > > > | < | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package com.mg105.user_interface; import com.mg105.interface_adapters.ReplayGeneratorInterpreter; import com.mg105.interface_adapters.Toggler; import javafx.event.ActionEvent; import javafx.event.EventHandler; import org.jetbrains.annotations.NotNull; /** * ReplayGeneratorButton acts as the event handler for the actual JavaFx button that will replay the game. */ public class ReplayGeneratorButton implements EventHandler<javafx.event.ActionEvent> { private final @NotNull ReplayGeneratorInterpreter interpreter; private final @NotNull Toggler toggler; private final @NotNull Toggler.ToggleableComponent componentToToggle; /** * Create a new ReplayGeneratorButton. * * @param interpreter the interpreter for the replay generator button. * @param toggler the toggler used to close the user interface once pressed. * @param componentToToggle the component that needs to be toggled */ public ReplayGeneratorButton(@NotNull ReplayGeneratorInterpreter interpreter, @NotNull Toggler toggler, Toggler.@NotNull ToggleableComponent componentToToggle) { this.interpreter = interpreter; this.toggler = toggler; this.componentToToggle = componentToToggle; } /** * this method is called when the button is pressed. It passes control to the appropriate interpreter. * * @param event the event which occurred */ @Override public void handle(ActionEvent event) { interpreter.replayGenerateMap(); toggler.toggle(componentToToggle); } } |
Changes to src/main/java/com/mg105/user_interface/SceneController.java.
1 2 | package com.mg105.user_interface; | < < < < < < < < < | < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | package com.mg105.user_interface; import com.mg105.interface_adapters.Toggler; import javafx.stage.Stage; import org.jetbrains.annotations.NotNull; import java.util.Map; import java.util.Stack; /** * SceneController acts as the central coordination mechanism for the user interface. */ public class SceneController implements Toggler { private final @NotNull Stage primaryStage; private final @NotNull Map<ToggleableComponent, Toggleable> components; private final @NotNull ToggleableComponent defaultComponent; private final @NotNull Stack<ToggleableComponent> activeComponents; /** * Create a new scene controller * * @param primaryStage the JavaFX stage to draw on. * @param components all the possible components in the system. Components should contain an entry for each * item in the ToggleableComponent enum. * @param defaultComponent the component that will be shown if there's nothing else to show. */ public SceneController(@NotNull Stage primaryStage, @NotNull Map<ToggleableComponent, Toggleable> components, @NotNull ToggleableComponent defaultComponent) { this.primaryStage = primaryStage; this.defaultComponent = defaultComponent; this.components = components; activeComponents = new Stack<>(); activeComponents.push(defaultComponent); } /** * Toggle the component. i.e. switch it between invisible and visible. * * @param component the component to toggle. */ |
︙ | ︙ | |||
77 78 79 80 81 82 83 | } if (activeComponents.isEmpty()) { activeComponents.push(defaultComponent); } components.get(activeComponents.peek()).toggle(true); | < | < < < < < < < < < < < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | } if (activeComponents.isEmpty()) { activeComponents.push(defaultComponent); } components.get(activeComponents.peek()).toggle(true); primaryStage.setScene(components.get(activeComponents.peek()).getScene()); primaryStage.setTitle("Mountain Group 105: " + activeComponents.peek()); } /** * Get the current visible component. * * @return the current visible component. */ @Override public @NotNull ToggleableComponent getCurrentComponent() { return activeComponents.peek(); } } |
Deleted src/main/java/com/mg105/user_interface/StandardComponentFactory.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/main/java/com/mg105/user_interface/Toggleable.java.
1 2 | package com.mg105.user_interface; | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.mg105.user_interface; import javafx.scene.Scene; import org.jetbrains.annotations.NotNull; /** * A user interface component that can be toggled on or off depending on its visibility. */ public interface Toggleable { /** * Get the scene of this toggleable object. It is this scene that will be displayed. * * @return the scene to be displayed. */ @NotNull Scene getScene(); /** * Set the visibility of this component. * * @param isVisible true if the Toggleable is now visible, false otherwise. If false the Toggleable is expected * to do nothing on ANY user inputs. */ |
︙ | ︙ |
Added src/main/java/com/mg105/user_interface/TutorialTextDisplay.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package com.mg105.user_interface; import com.mg105.interface_adapters.tutorial.TutorialTextController; import com.mg105.utils.TutorialTexts; import javafx.scene.control.Label; import javafx.scene.text.Font; /** * Returns the actual text that is displayed to the player */ public class TutorialTextDisplay { private final TutorialTextController tutorialControl = new TutorialTextController(false); /** * Constructor for a new TutorialTextDisplay ui */ public TutorialTextDisplay() { } /** * Check if specific action has been performed * * @param displayedText the String representing the current phase * @return the actual text displayed to the user */ public String showBottomText(String displayedText) { String tutorialText; int phase_idx = tutorialControl.allPhases().indexOf(displayedText); tutorialText = TutorialTexts.PHASES_TEXT.get(phase_idx); return tutorialText; } /** * Return a label that will show at the bottom of the screen. * * @return the label */ public Label tutorialLabel() { Label bottomText = new Label(); bottomText.setFont(Font.font(TutorialTexts.TEXT_SIZE)); return bottomText; } /** * Get a tutorial controller which is used to switch text * * @return instance of the controller */ public TutorialTextController getController() { return this.tutorialControl; } } |
Added src/main/java/com/mg105/user_interface/TutorialTextWindow.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | package com.mg105.user_interface; import com.mg105.interface_adapters.tutorial.TutorialTextController; import com.mg105.utils.TutorialTexts; import javafx.animation.AnimationTimer; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.CornerRadii; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.text.Font; import org.jetbrains.annotations.NotNull; /** * Create a window for the tutorial scenes */ public class TutorialTextWindow implements Toggleable { final TutorialTextDisplay tutorialDisplay; final Pane tutorialPane = new Pane(); final Label bottomText = new Label(); final Label helpText; final TutorialTextController textController; final Scene tutorialScene = new Scene(tutorialPane, TutorialTexts.HELPER_PANE_X, TutorialTexts.HELPER_PANE_Y); /** * Window for the tutorial * * @param textController the controller for the tutorial * @param tutorialDisplay the ui that displays the tutorial */ public TutorialTextWindow(TutorialTextController textController, @NotNull TutorialTextDisplay tutorialDisplay) { this.textController = textController; this.tutorialDisplay = tutorialDisplay; bottomText.setFont(Font.font(TutorialTexts.TEXT_SIZE)); helpText = tutorialDisplay.tutorialLabel(); helpText.setFont(Font.font(TutorialTexts.TEXT_SIZE)); helpText.setBackground(new Background(new BackgroundFill(Color.rgb(255, 215, 0, 1), new CornerRadii(80.0), new Insets(-100.0)))); tutorialPane.getChildren().add(bottomText); tutorialPane.getChildren().add(helpText); AnimationTimer timer = new TutorialTimer(); timer.start(); } /** * Get the scene of this toggleable object. It is this scene that will be displayed. * * @return the scene to be displayed. */ @Override public @NotNull Scene getScene() { return tutorialScene; } /** * Set the visibility of this component. * * @param isVisible true if the Toggleable is now visible, false otherwise. If false the Toggleable is expected * to do nothing on ANY user inputs. */ @Override public void toggle(boolean isVisible) { } private class TutorialTimer extends AnimationTimer { private long prevTime = 0; private double helpTimer = TutorialTexts.HELP_TIME; /** * This method needs to be overridden by extending classes. It is going to * be called in every frame while the {@code AnimationTimer} is active. * * @param now The timestamp of the current frame given in nanoseconds. This * value will be the same for all {@code AnimationTimers} called * during one frame. */ @Override public void handle(long now) { long timeChange = now - prevTime; // 1e9 is 1 second if (timeChange > TutorialTexts.TEXT_DURATION1 * 1e9 & textController.changeText()) { prevTime = now; tutorialDisplay.getController().nextPhase(); String tutorialText = tutorialDisplay.getController().bottomText(); bottomText.setText(tutorialDisplay.showBottomText(tutorialText)); } if (textController.getShowControls() & textController.isComplete()) { helpText.setText(TutorialTexts.CONTROLS); helpTimer--; if (helpTimer < 1) { textController.setShowControls(false); helpTimer = TutorialTexts.HELP_TIME; } } else if (textController.getShowControls()) { if (textController.getActionPerformed(TutorialTexts.MOVED)) { helpText.setText(TutorialTexts.DID_NOT_MOVE); } else if (textController.getActionPerformed(TutorialTexts.USED_ITEM)) { helpText.setText(TutorialTexts.DID_NOT_OPEN_CHEST); } else { helpText.setText(TutorialTexts.DID_NOT_BATTLE); } helpTimer--; if (helpTimer < 1) { textController.setShowControls(false); helpTimer = TutorialTexts.HELP_TIME; } } else { helpText.setText(""); } } } } |
Changes to src/main/java/com/mg105/user_interface/WalkingMenu.java.
1 2 | package com.mg105.user_interface; | < < | | | | | > > > | | | | | > > | | | < < | < < | | > | > | > > > | > | > > | | | > > | > > | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | package com.mg105.user_interface; import com.mg105.interface_adapters.WalkVisController; import com.mg105.utils.PartyConstants; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import org.jetbrains.annotations.NotNull; /** * This class uses JavaFX and is displayed when the user wants to change the walking character sprite. */ public class WalkingMenu implements EventHandler<ActionEvent>, Toggleable { private final WalkVisController controller; private final RadioButton radA; private final RadioButton radB; private final RadioButton radC; private final RadioButton radD; private final Button select; private final Scene scene; /** * Creates a new WalkingMenu with reference to a controller class. * Sets up UI elements. * * @param controller the WalkVisController to be referred to. */ public WalkingMenu(WalkVisController controller) { this.controller = controller; StackPane layout = new StackPane(); ToggleGroup group = new ToggleGroup(); VBox buttons = new VBox(); radA = new RadioButton(PartyConstants.ALL_PARTY_MEMBER_NAMES[0]); radA.setToggleGroup(group); radA.setSelected(true); radB = new RadioButton(PartyConstants.ALL_PARTY_MEMBER_NAMES[1]); radB.setToggleGroup(group); radB.setSelected(false); radC = new RadioButton(PartyConstants.ALL_PARTY_MEMBER_NAMES[2]); radC.setToggleGroup(group); radC.setSelected(false); radD = new RadioButton(PartyConstants.ALL_PARTY_MEMBER_NAMES[3]); radD.setToggleGroup(group); radD.setSelected(false); select = new Button("Confirm"); select.setOnAction(this); Label exitLbl = new Label("Press space bar to exit."); buttons.getChildren().addAll(radA, radB, radC, radD, select, exitLbl); buttons.setAlignment(Pos.CENTER); layout.getChildren().addAll(buttons); scene = new Scene(layout, 300, 300); } /** * Handles button events. * Pressing the select button updates the WalkingCharacter to represent the desired walking character sprite. * * @param event the event which occurred. */ @Override public void handle(ActionEvent event) { Object source = event.getSource(); if (source.equals(select)) { if (radA.isSelected()) { controller.changePlayerSprite("A"); } else if (radB.isSelected()) { controller.changePlayerSprite("B"); } else if (radC.isSelected()) { controller.changePlayerSprite("C"); } else if (radD.isSelected()) { controller.changePlayerSprite("D"); } } } /** * Get the scene of this toggleable object. It is this scene that will be displayed. * * @return the scene to be displayed. */ @Override public @NotNull Scene getScene() { return this.scene; } /** * Set the visibility of this component. * * @param isVisible true if the Toggleable is now visible, false otherwise. If false the Toggleable is expected * to do nothing on ANY user inputs. */ @Override public void toggle(boolean isVisible) { //The menu should ideally remain the same. } } |
Changes to src/main/java/com/mg105/user_interface/WinMenu.java.
1 2 | package com.mg105.user_interface; | < | | | > | > | < < < < | | < < | < | < | < < < > | < > > > | < < < < < < < | > | | < | < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | package com.mg105.user_interface; import com.mg105.utils.TutorialTexts; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.text.Font; import org.jetbrains.annotations.NotNull; /** * A menu that is shown to the player after they have reached the final room */ public class WinMenu implements Toggleable { private final @NotNull Scene scene; /** * Shows a button that congratulates you and lets you replay the game * * @param ReplayButton the button responsible for replaying the game */ public WinMenu(@NotNull ReplayGeneratorButton ReplayButton) { Label winLbl = new Label(); winLbl.setText("Congratulations on reaching the final room!!"); winLbl.setFont(Font.font(TutorialTexts.TEXT_SIZE_LARGE)); StackPane.setAlignment(winLbl, Pos.TOP_CENTER); Button generateMapButton = new Button("You Won! Replay The Game"); generateMapButton.setOnAction(ReplayButton); @NotNull Pane layout = new StackPane(); layout.getChildren().add(generateMapButton); layout.getChildren().add(winLbl); scene = new Scene(layout, 600, 600); } /** * Get scene of the WinMenu * * @return the scene that WinMenu is in */ @Override public @NotNull Scene getScene() { return scene; } /** * Toggle the WinMenu * * @param isVisible whether the menu is visible */ @Override public void toggle(boolean isVisible) { // Does nothing, for now } } |
Deleted src/main/java/com/mg105/utils/ColorConstants.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/main/java/com/mg105/utils/Textures.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/main/java/com/mg105/utils/TutorialTexts.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | package com.mg105.utils; import java.util.Arrays; import java.util.List; /** * Constants for texts related to the tutorial */ public class TutorialTexts { /** * Constant string for move phase */ public static final String MOVED = "moved"; /** * Constant string for attack phase */ public static final String ATTACKED = "attacked"; /** * Constant string for using item phase */ public static final String USED_ITEM = "usedItem"; /** * Constant int for x size of helper pane */ public static final int HELPER_PANE_X = 420; /** * Constant int for y size of helper pane */ public static final int HELPER_PANE_Y = 100; /** * Constant int for text duration per phase */ public static final int TEXT_DURATION1 = 3; /** * Constant int for size of the regular text */ public static final int TEXT_SIZE = 14; /** * Constant int for size of the larger text */ public static final int TEXT_SIZE_LARGE = 20; /** * Constant int for text duration of helper text (not in seconds) */ public static final int HELP_TIME = 250; /** * Constant array listing all the phases */ public static final List<String> PHASES = Arrays.asList("...", "story", "tell move", "tell attack", "tell use item", "exit room", "hotkeys"); /** * Constant string for story text */ public static final String STORY = """ Welcome to mountain climber. You must battle your way to the top of the mountain. Inside various rooms you will encounter enemies and find treasures."""; /** * Constant string for move text */ public static final String TELL_MOVE = "Move your character with the WASD keys."; /** * Constant string for attack text */ public static final String TELL_ATTACK = "Use the battle button [f] to attack the enemies."; /** * Constant string for open chest text */ public static final String TELL_USE_ITEM = "Open treasure chests using the [e] key.."; /** * Constant string for good luck text */ public static final String EXIT_ROOM = "Good luck on your journey!"; /** * Constant string for telling player the game controls */ public static final String CONTROLS = """ Hotkeys: Press K for help. Press WASD to return to game.\s Game Controls: Use WASD to move. Use battle key [f] to \s initiate battles. Open chests using [e]."""; /** * Constant string for telling the player the hotkeys */ public static final String HOTKEYS = "Hint: Press [WASD] to return to the game. Press K for help!"; /** * Constant array containing the actual text shown to the player */ public static final List<String> PHASES_TEXT = Arrays.asList("", TutorialTexts.STORY, TutorialTexts.TELL_MOVE, TutorialTexts.TELL_ATTACK, TutorialTexts.TELL_USE_ITEM, TutorialTexts.EXIT_ROOM, TutorialTexts.HOTKEYS); /** * Constant string reminding player how to move */ public static final String DID_NOT_MOVE = """ You haven't completed the tutorial yet ... You should return to the game and move you character with [WASD]! (Pressing WASD in this window will return you to the game.) """; /** * Constant string for reminding player to open chest */ public static final String DID_NOT_OPEN_CHEST = """ You haven't completed the tutorial yet ... You should go open a chest! Do this using the [e] key. (Pressing WASD in this window will return you to the game.) """; /** * Constant string for reminding player to initiate a battle */ public static final String DID_NOT_BATTLE = """ You haven't completed the tutorial yet ... You should go fight a battle! Use [f] key to initiate a battle. (Pressing WASD in this window will return you to the game.) """; } |
Deleted src/main/java/com/mg105/utils/UIConstants.java.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/main/resources/fonts/HomemadeApple-Regular.ttf.
cannot compute difference between binary files
Deleted src/main/resources/fonts/IBMPlexMono-Medium.ttf.
cannot compute difference between binary files
Deleted src/main/resources/fonts/Strait-Regular.ttf.
cannot compute difference between binary files
Changes to src/main/resources/tiles/battle.png.
cannot compute difference between binary files
Changes to src/main/resources/tiles/chest.png.
cannot compute difference between binary files
Changes to src/main/resources/tiles/chest_open.png.
cannot compute difference between binary files
Added src/main/resources/tiles/exit.png.
cannot compute difference between binary files
Changes to src/main/resources/tiles/wall_face.png.
cannot compute difference between binary files
Added src/test/java/com/mg105/entities/GiveTutorialTest.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package com.mg105.entities; import com.mg105.utils.TutorialTexts; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class GiveTutorialTest { @Test void testActionSetterGetter() { GiveTutorial newTutorial = new GiveTutorial(false, false, false); newTutorial.actionPerformedSetter(TutorialTexts.MOVED); GiveTutorial newTutorial2 = new GiveTutorial(false, false, false); newTutorial2.actionPerformedSetter(TutorialTexts.ATTACKED); GiveTutorial newTutorial3 = new GiveTutorial(false, false, false); newTutorial3.actionPerformedSetter(TutorialTexts.USED_ITEM); assertTrue(newTutorial.actionPerformedGetter(TutorialTexts.MOVED)); assertFalse(newTutorial.actionPerformedGetter(TutorialTexts.ATTACKED)); assertFalse(newTutorial.actionPerformedGetter(TutorialTexts.USED_ITEM)); assertFalse(newTutorial2.actionPerformedGetter(TutorialTexts.MOVED)); assertTrue(newTutorial2.actionPerformedGetter(TutorialTexts.ATTACKED)); assertFalse(newTutorial2.actionPerformedGetter(TutorialTexts.USED_ITEM)); assertFalse(newTutorial3.actionPerformedGetter(TutorialTexts.MOVED)); assertFalse(newTutorial3.actionPerformedGetter(TutorialTexts.ATTACKED)); assertTrue(newTutorial3.actionPerformedGetter(TutorialTexts.USED_ITEM)); } } |
Added src/test/java/com/mg105/interface_adapters/map/RoomInterpreterTest.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | package com.mg105.interface_adapters.map; import com.mg105.use_cases.map.RoomGetterInterface; import com.mg105.use_cases.outputds.RoomLayout; import com.mg105.utils.MapConstants; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import java.awt.*; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; public class RoomInterpreterTest { @Test void getLayout() { RoomTileType[][] expected = new RoomTileType[][]{ {RoomTileType.WALL, RoomTileType.EXIT, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL}, {RoomTileType.WALL_WITH_FACE, RoomTileType.OPPONENT_SET, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.WALL}, {RoomTileType.EXIT, RoomTileType.CHEST_OPEN, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.WALL_WITH_FACE}, {RoomTileType.WALL, RoomTileType.CHEST, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.EXIT}, {RoomTileType.WALL, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.WALL}, {RoomTileType.WALL, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.WALL}, {RoomTileType.WALL, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.FLOOR, RoomTileType.WALL}, {RoomTileType.WALL_WITH_FACE, RoomTileType.EXIT, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE, RoomTileType.WALL_WITH_FACE}, }; RoomInterpreter interpreter = new RoomInterpreter(new FakeRoomGetter()); RoomTileType[][] actual = interpreter.getCurrentRoom(); for (int y = 0; y < MapConstants.ROOM_SIZE; y++) { for (int x = 0; x < MapConstants.ROOM_SIZE; x++) { assertEquals(expected[y][x], actual[y][x]); } } } @Test void getPlayer() { RoomInterpreter interpreter = new RoomInterpreter(new FakeRoomGetter()); assertEquals(new Point(4, 4), interpreter.getPlayer()); } @Test void getSprite() { RoomInterpreter interpreter = new RoomInterpreter(new FakeRoomGetter()); assertEquals("/sprites/B.png", interpreter.getCharacterSprite()); } private static class FakeRoomGetter implements RoomGetterInterface { @Override public @NotNull RoomLayout getCurrentRoomLayout() { List<Point> closedChests = new ArrayList<>(); closedChests.add(new Point(1, 3)); List<Point> openChests = new ArrayList<>(); openChests.add(new Point(1, 2)); List<Point> opponents = new ArrayList<>(); opponents.add(new Point(1, 1)); List<Point> doorways = new ArrayList<>(); doorways.add(new Point(0, 2)); doorways.add(new Point(1, 0)); doorways.add(new Point(MapConstants.ROOM_SIZE - 1, 3)); doorways.add(new Point(1, MapConstants.ROOM_SIZE - 1)); return new RoomLayout(closedChests, openChests, opponents, doorways, new Point(4, 4)); } @Override public @NotNull String getWalkingSprite() { return "/sprites/B.png"; } @Override public boolean isFinalRoom() { return false; } } } |
Added src/test/java/com/mg105/use_cases/tutorial/TutorialInteractorTest.java.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | package com.mg105.use_cases.tutorial; import com.mg105.use_cases.PlayerGetsTutorial; import com.mg105.user_interface.TutorialTextDisplay; import com.mg105.utils.TutorialTexts; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class TutorialInteractorTest { @Test void testAdvancePhase() { PlayerGetsTutorial tutorialPlayer = new PlayerGetsTutorial(TutorialTexts.PHASES, 0); assertEquals(tutorialPlayer.currentPhase(), 0); tutorialPlayer.nextPhase(); assertEquals(tutorialPlayer.currentPhase(), 1); tutorialPlayer.nextPhase(); assertEquals(tutorialPlayer.currentPhase(), 2); tutorialPlayer.nextPhase(); assertEquals(tutorialPlayer.currentPhase(), 3); } @Test void testTutorialComplete() { PlayerGetsTutorial tutorialPlayer1 = new PlayerGetsTutorial(TutorialTexts.PHASES, 0); PlayerGetsTutorial tutorialPlayer2 = new PlayerGetsTutorial(TutorialTexts.PHASES, 0); tutorialPlayer2.setActionPerformed(TutorialTexts.MOVED); tutorialPlayer2.setActionPerformed(TutorialTexts.ATTACKED); tutorialPlayer2.setActionPerformed(TutorialTexts.USED_ITEM); assertFalse(tutorialPlayer1.getActionPerformed(TutorialTexts.MOVED)); assertFalse(tutorialPlayer1.getActionPerformed(TutorialTexts.ATTACKED)); assertFalse(tutorialPlayer1.getActionPerformed(TutorialTexts.USED_ITEM)); assertFalse(tutorialPlayer1.isComplete()); assertTrue(tutorialPlayer2.getActionPerformed(TutorialTexts.MOVED)); assertTrue(tutorialPlayer2.getActionPerformed(TutorialTexts.ATTACKED)); assertTrue(tutorialPlayer2.getActionPerformed(TutorialTexts.USED_ITEM)); assertTrue(tutorialPlayer2.isComplete()); } @Test void testTutorialBottomText() { TutorialTextDisplay tutorialDisplay = new TutorialTextDisplay(); int phase_num = tutorialDisplay.getController().getTutorial().currentPhase(); String phase = tutorialDisplay.getController().getTutorial().allPhases().get(phase_num); String tutorialText = tutorialDisplay.showBottomText(phase); String expected = ""; TutorialTextDisplay tutorialDisplay2 = new TutorialTextDisplay(); tutorialDisplay2.getController().nextPhase(); int phase_num2 = tutorialDisplay2.getController().getTutorial().currentPhase(); String phase2 = tutorialDisplay2.getController().getTutorial().allPhases().get(phase_num2); String tutorialText2 = tutorialDisplay2.showBottomText(phase2); TutorialTextDisplay tutorialDisplay3 = new TutorialTextDisplay(); tutorialDisplay3.getController().nextPhase(); tutorialDisplay3.getController().nextPhase(); int phase_num3 = tutorialDisplay3.getController().getTutorial().currentPhase(); String phase3 = tutorialDisplay3.getController().getTutorial().allPhases().get(phase_num3); String tutorialText3 = tutorialDisplay3.showBottomText(phase3); TutorialTextDisplay tutorialDisplay4 = new TutorialTextDisplay(); tutorialDisplay4.getController().nextPhase(); tutorialDisplay4.getController().nextPhase(); tutorialDisplay4.getController().nextPhase(); int phase_num4 = tutorialDisplay4.getController().getTutorial().currentPhase(); String phase4 = tutorialDisplay4.getController().getTutorial().allPhases().get(phase_num4); String tutorialText4 = tutorialDisplay4.showBottomText(phase4); TutorialTextDisplay tutorialDisplay5 = new TutorialTextDisplay(); tutorialDisplay5.getController().nextPhase(); tutorialDisplay5.getController().nextPhase(); tutorialDisplay5.getController().nextPhase(); tutorialDisplay5.getController().nextPhase(); int phase_num5 = tutorialDisplay5.getController().getTutorial().currentPhase(); String phase5 = tutorialDisplay5.getController().getTutorial().allPhases().get(phase_num5); String tutorialText5 = tutorialDisplay5.showBottomText(phase5); assertEquals(tutorialText, expected); assertEquals(tutorialText2, TutorialTexts.STORY); assertEquals(tutorialText3, TutorialTexts.TELL_MOVE); assertEquals(tutorialText4, TutorialTexts.TELL_ATTACK); assertEquals(tutorialText5, TutorialTexts.TELL_USE_ITEM); } } |