Assignment is the a3 file
CSSE1001 Assignment 3 Due 5pm, Friday 30th October 2020 1 Introduction In Assignment 2 you implemented a text-based version of the Key Cave Adventure Game. In Assignment 3 you will modify this game to a graphical user interface (GUI) based game. Your implementation should maintain the Apple model-view-controller (Apple MVC) structure used in Assignment 2. In this assignment, the View must be implemented using tkinter. The new version of this game is a single-player GUI-based game in which the player is presented with a grid of squares (represented by either coloured rectangles or images). The objective is for the ibis (the player) to collect the trash and take it to their nest. This game is full of adventure. The player can move either by key presses or by clicking on an on-screen keypad. 2 Tips and hints The number of marks associated with each task is not an indication of difficulty. Task 1 may take less effort than task 2, yet is worth significantly more marks. A fully functional attempt at task 1 will likely earn more marks than attempts at both task 1 and task 2 that have many errors throughout. Likewise, a fully functional attempt at a single part of task 1 will likely earn more marks than an attempt at all of task 1 that has many errors throughout. While you should be testing regularly throughout the coding process, at the minimum you should not move on to task 2 until you have convinced yourself (through testing) that task 1 works relatively well, and if you are a postgraduate student, you should not attempt the postgraduate task until you have convinced yourself (through testing) that task 1 and task 2 both work relatively well. Except where specified, minor differences in the look (e.g. colours, fonts, etc.) of the GUI are acceptable. Except where specified, you are only required to do enough error handling such that regular game play does not cause your program to crash or error. If an attempt at a feature causes your program to crash or behave in a way that testing other functionality becomes difficult without your marker modifying your code, comment it out before submitting your assignment. You must only make use of libraries listed in Appendix A. You must not import anything that is not on this list. You may use any course provided code in your assignment. This includes any code from the support files or sample solutions for previous assignments from this semester only, as well as any lecture or tutorial code provided to you by course staff. However, it is your responsibility to ensure that this code is styled appropriately, and is an appropriate and correct approach to the problem you are addressing. You must write all your code in one file, titled a3.py. You must only submit this file; you are not permitted to submit any other files. Your game must display (in the latest attempted mode) when your marker runs this file. This means that if you import code from previous assignments or previous support files, your code will not run when we try to run it. If you would like to use course provided code, this code must be present within your a3.py file. 3 Task 1: Basic Gameplay - 10 marks Task 1 requires you to implement a functional GUI-based version of game of Key Cave Adventure Game. To do this you will need to implement some View classes and make appropriate modifications to the Controller class from Assignment 2. Certain events should cause behaviour as per Table 1. 1 Event Behaviour Key Press: ‘w’ User moves up one square if the map permits. Key Press: ‘a’ User moves left one square if the map permits. Key Press: ‘s’ User moves down one square if the map permits. Key Press: ‘d’ User moves right one square if the map permits. Left click on keypad User moves in the direction shown on the rectangle they click. If they click on the keypad at a place that is not displaying a direction, nothing should happen. Table 1: Events and their corresponding behaviours. When the player wins or loses the game they should be informed of the outcome via a messagebox. After the user closes the messagebox the game may terminate, or may remain open (further actions will not be tested; i.e. your tutor will not try to continue playing the game). In task 1, entities are represented by coloured rectangles. You must also annotate the rectangles of certain entities with what they represent (as per Fig. 1). The colours representing each entity are: • Wall: Dark grey • Ibis (Player): Medium spring green • Banana (MoveIncrease): Orange • Trash (Key): Yellow • Nest (Door): Red Figure 1: Example game at the end of task 1. The following sub-sections outline the required structure for your code. You will benefit from writing these classes in parallel, but you should still test individual methods as you write them. 2 3.1 Model classes Model classes should be defined as per Assignment 2. You may add more modelling classes if they improve the code. You should at least include Entity, Wall, Player, Item, Key, MoveIncrease, Door, and GameLogic. Note that, though we’re now representing these classes with different concepts (e.g. the Door will be represented with a graphical depiction of a nest) you don’t necessarily need to modify these classes to modify how they’re represented in the graphical interface. You may choose to modify the names of the classes if this makes it easier for you to understand, but you won’t need to. 3.2 View Classes You must implement view classes for the game map and the keypad. However, because these can both be repre- sented by grids of rectangles and share a fair amount of functionality, you are required to create an abstract class to factor out this shared functionality. Appendix B outlines methods that may be useful to write in each of these classes. You may add additional methods if they improve the design of your classes. 3.2.1 AbstractGrid AbstractGrid is an abstract view class which inherits from tk.Canvas and provides base functionality for many of the view classes, as they share a fair amount of common functionality. Namely, they can be thought of as a grid with a set number of rows and columns, and they should all support creation of text at specific positions based on row and column. Though AbstractGrid is an abstract class, if it were to be instantiated, it would be as AbstractGrid(master, rows, cols, width, height, **kwargs) where ‘**kwargs’ signifies that any named arguments supported by tk.Canvas class should also be supported by AbstractGrid. Note that the number of rows may differ from the number of columns. 3.2.2 DungeonMap DungeonMap is a view class which inherits from AbstractGrid. Entities are drawn on the map using coloured rectangles at different (row, column) positions. You may assume that the number of rows will always be the same as the number of columns for the DungeonMap; i.e. the map is always a square. Your program should work for reasonable dungeon sizes (#rows ∈ [4, 15]). Some entities have their IDs written on their cells (see Figure 1). You must use the create rectangle and create text methods for tk.Canvas to achieve this. You should set the background colour of the DungeonMap instance to light gray by using the kwargs. The DungeonMap class should be instantiated as DungeonMap(master, size, width=600, **kwargs), where size is the number of rows (equal to the number of columns) in the grid, and width is the number of pixels for the width and height of the grid. 3.2.3 KeyPad KeyPad is a view class which inherits from AbstractGrid, and represents the GUI keypad. Each key is represented as a rectangle created on the KeyPad canvas itself, with text superimposed over it (also created on the KeyPad canvas itself). You must use the create rectangle and create text methods for tk.Canvas to achieve this. The KeyPad class should be instantiated as KeyPad(master, width=200, height=100, **kwargs). 3.3 GameApp GameApp represents the controller class. This class should manage necessary communication between any model and view classes, as well as event handling. You must also write code to instantiate this class and ensure that the window appears. Give your window an appropriate title, and (as per Figure 1) include a label with the game name at the top of the window. This class should be instantiated as GameApp(master, task=TASK ONE, dungeon name="game2.txt"), where TASK ONE is some constant (defined by you) that allows the game to be displayed as per Figure 1. The dungeon name is the name of the file to load the level from. Though this argument has a default value, all attempted features should work with other reasonable game files. 4 Task 2: Images, StatusBar, and File Menu - 6 marks Task 2 requires you to add additional features to enhance the games look and functionality. Figure 2 gives an example of the game at the end of task 2. Note: Your task 1 functionality must still be testable when the task parameter of GameApp is set to the TASK ONE constant. If you attempt task 2, you must define a TASK TWO constant which, when supplied as the task parameter for GameApp, allows the app to run with any attempted task 2 features included. There should be no task 2 features visible when running the game in TASK ONE mode. 3 Figure 2: Example game at the end of task 2. 4.1 StatusBar - 1.5 marks Add a StatusBar class that inherits from tk.Frame. In this frame, you should include a game timer displaying the number of minutes and seconds the user has been playing the current game alongside the clock image, as well as a counter of the number of moves remaining alongside the lightning image. You must also include a ‘Quit’ button (which ends the program), and a ‘New game’ button, which allows the user to start the game again (this must reset the information on the status bar, as well as setting the map back to how it appears at the start of a game). For full marks, the layout of the status bar must be as per Figure 2. 4.2 End of game - 0.5 marks When the player wins or loses the game the game timer should be stopped and the player should be informed of the outcome (including their score if they won) and prompted for whether to play again (see Figure 3). The score is the user’s game time (lower is better). If they choose to play again, a new game should be prepared, and all game information should be reset (this must be communicated on the status bar). If they opt not to play again, the game should terminate.