1 00:00:00,650 --> 00:00:02,860 Open Workspaces and you'll see the code for 2 00:00:02,860 --> 00:00:05,260 the Treehouse Defense game that's been written so far. 3 00:00:06,350 --> 00:00:08,890 Let's take a few minutes to dissect this code so 4 00:00:08,890 --> 00:00:11,278 we have a good understanding of it before we move on. 5 00:00:11,278 --> 00:00:16,310 This is 100% review, so I'll move through this rather quickly. 6 00:00:16,310 --> 00:00:19,560 Let's start by looking at Map.cs. 7 00:00:19,560 --> 00:00:22,190 This is the definition of the Map class. 8 00:00:22,190 --> 00:00:25,600 A map determines the width and height boundaries of a level. 9 00:00:25,600 --> 00:00:29,600 It's constructed by passing it a width and height value for the map. 10 00:00:29,600 --> 00:00:32,590 We also have an OnMap method which can be 11 00:00:32,590 --> 00:00:35,300 used to determine if a point is on the map. 12 00:00:35,300 --> 00:00:40,120 If we open Point.cs, we'll see a definition for the Point class. 13 00:00:40,120 --> 00:00:43,610 The Point class represents a coordinate on the grid, so 14 00:00:43,610 --> 00:00:47,050 it's initialized with the values for x and y. 15 00:00:47,050 --> 00:00:51,840 The Point class has two methods, both named DistanceTo. 16 00:00:51,840 --> 00:00:55,450 This first one will tell us the distance between the point object the DistanceTo 17 00:00:55,450 --> 00:00:59,890 method is being called on and the x and y coordinates being passed in. 18 00:00:59,890 --> 00:01:04,270 The second method is an overload of DistanceTo, meaning there are two 19 00:01:04,270 --> 00:01:08,050 methods with the same name, but they accept different parameters. 20 00:01:08,050 --> 00:01:12,180 This second method calculates the distance between the two point objects. 21 00:01:12,180 --> 00:01:16,820 The Point class is a very general purpose class to represent coordinates on a grid. 22 00:01:16,820 --> 00:01:21,542 We needed a class that was more specific to the Treehouse Defense game, so 23 00:01:21,542 --> 00:01:25,819 we subclassed the Point class and created the MapLocation class. 24 00:01:25,819 --> 00:01:29,210 We can see the MapLocation class in MapLocation.cs. 25 00:01:29,210 --> 00:01:32,460 Here we can see that MapLocation is a subclass of Point, 26 00:01:32,460 --> 00:01:34,660 because it says : Point here. 27 00:01:34,660 --> 00:01:38,410 Also, remember, a subclass of another class inherits 28 00:01:38,410 --> 00:01:41,250 all of the non-private members of the other class. 29 00:01:41,250 --> 00:01:48,000 So the MapLocation class also has x and y fields, and the two DistanceTo methods. 30 00:01:48,000 --> 00:01:51,020 Inheritance is one of the principles of object-oriented 31 00:01:51,020 --> 00:01:53,540 programming that we've learned about before. 32 00:01:53,540 --> 00:01:57,814 We'll get a lot more practice using inheritance in this course as well. 33 00:01:57,814 --> 00:02:01,880 The MapLocation constructor also takes x and y parameters and 34 00:02:01,880 --> 00:02:06,530 passes them up to the Point class constructor here where it says, : Base. 35 00:02:06,530 --> 00:02:09,670 It also takes a Map object as a parameter. 36 00:02:09,670 --> 00:02:13,520 The constructor verifies that the MapLocation being constructed 37 00:02:13,520 --> 00:02:16,420 is indeed on the map, because if it isn't, 38 00:02:16,420 --> 00:02:19,680 it can't rightfully be called a MapLocation, now, can it? 39 00:02:19,680 --> 00:02:23,943 The InRangeOf method determines if this MapLocation object is in range of 40 00:02:23,943 --> 00:02:26,472 the MapLocation passed in. 41 00:02:26,472 --> 00:02:30,730 This OutOfBoundsException is an exception type we made ourselves. 42 00:02:30,730 --> 00:02:32,185 We can find a definition for 43 00:02:32,185 --> 00:02:35,870 the OutOfBoundsException type in Exceptions.cs. 44 00:02:35,870 --> 00:02:40,687 Notice that the OutOfBoundsException is a type of TreehouseException, 45 00:02:40,687 --> 00:02:44,060 which, in turn, is a type of System.Exception. 46 00:02:44,060 --> 00:02:49,510 Remember, all exception types in C# must inherit from System.Exception. 47 00:02:49,510 --> 00:02:54,710 You'll remember that in Treehouse Defense, invaders march down the path and 48 00:02:54,710 --> 00:02:56,510 towers shoot at them. 49 00:02:56,510 --> 00:03:01,020 If an invader makes it past the end of the path, then the player loses. 50 00:03:01,020 --> 00:03:03,850 So we also have a class to represent the path. 51 00:03:05,050 --> 00:03:08,456 A path is simply a list of adjacent MapLocations. 52 00:03:08,456 --> 00:03:11,450 These MapLocations are stored in an array. 53 00:03:11,450 --> 00:03:15,500 We've made this array member variable private because users of this class 54 00:03:15,500 --> 00:03:19,540 don't need to know that it's an array or have direct access to it. 55 00:03:19,540 --> 00:03:21,840 They only need to know the length of the path and 56 00:03:21,840 --> 00:03:25,110 what the MapLocation is at any step in the path. 57 00:03:25,110 --> 00:03:28,640 So we've provided a public property for the length, 58 00:03:28,640 --> 00:03:33,370 which just returns the array's length, and a public method named GetLocationAt. 59 00:03:34,400 --> 00:03:38,520 The Path class is a good demonstration of another principle of object-oriented 60 00:03:38,520 --> 00:03:41,280 programming, that is, encapsulation. 61 00:03:41,280 --> 00:03:44,200 By making the array private and exposing the methods and 62 00:03:44,200 --> 00:03:47,530 properties that we want the user of this class to have, 63 00:03:47,530 --> 00:03:51,050 we've given ourselves the freedom to change the implementation details 64 00:03:51,050 --> 00:03:55,280 of this class in the future without affecting any users of the class. 65 00:03:55,280 --> 00:03:59,190 The public methods of a class are part of the class's interface. 66 00:03:59,190 --> 00:04:01,350 When designing a software application, 67 00:04:01,350 --> 00:04:04,950 we want to think of classes in terms of their interface. 68 00:04:04,950 --> 00:04:07,620 This greatly facilitates software design and 69 00:04:07,620 --> 00:04:12,490 development because the software designer, or sometimes called the architect, 70 00:04:12,490 --> 00:04:15,870 can focus on making sure that the interfaces are correct. 71 00:04:15,870 --> 00:04:20,390 And the implementation details can be left up to the individual developers 72 00:04:20,390 --> 00:04:22,550 who write the code for the classes. 73 00:04:22,550 --> 00:04:26,730 This also helps with maintaining the class over time and fixing bugs. 74 00:04:26,730 --> 00:04:31,630 So long as the public interface isn't affected, we can fix bugs all we want and 75 00:04:31,630 --> 00:04:34,880 there's less possibility of breaking the entire program. 76 00:04:34,880 --> 00:04:39,259 This is why encapsulation is such an important principle in object-oriented 77 00:04:39,259 --> 00:04:39,990 programming. 78 00:04:39,990 --> 00:04:43,590 We'll learn more about how to define interfaces between classes later in 79 00:04:43,590 --> 00:04:44,690 this course. 80 00:04:44,690 --> 00:04:47,790 The main user of the Path class is the invader. 81 00:04:47,790 --> 00:04:51,900 We can find the code for the Invader class in Invader.cs. 82 00:04:51,900 --> 00:04:55,340 Invaders keep track of their location on the path by storing it 83 00:04:55,340 --> 00:04:57,120 in the pathStep field. 84 00:04:57,120 --> 00:05:01,560 Location is a computed property that gets the MapLocation of the invader 85 00:05:01,560 --> 00:05:02,735 based on its pathStep. 86 00:05:04,046 --> 00:05:08,571 HasScored is another computed property that returns true if the invader has made 87 00:05:08,571 --> 00:05:10,810 it past the end of the path. 88 00:05:10,810 --> 00:05:13,660 Take note that HasScored and 89 00:05:13,660 --> 00:05:19,270 location are both computed properties, but they're written with different syntax. 90 00:05:19,270 --> 00:05:23,870 We could just as easily have written the HasScored property using the equal 91 00:05:23,870 --> 00:05:29,220 angle bracket notation or written the location property using curly braces. 92 00:05:29,220 --> 00:05:30,980 The result is the same. 93 00:05:30,980 --> 00:05:33,680 I've done both here to demonstrate both ways for 94 00:05:33,680 --> 00:05:36,110 you to use as a reference in the future. 95 00:05:36,110 --> 00:05:39,502 Health is a property with a public getter and a private setter. 96 00:05:39,502 --> 00:05:41,810 It's initialized to 2. 97 00:05:41,810 --> 00:05:46,990 An invader is neutralized if its health is less than or equal to 0, 98 00:05:46,990 --> 00:05:51,630 and it's active if it is neither neutralized nor has it scored. 99 00:05:51,630 --> 00:05:54,344 Finally, invaders have two behaviors. 100 00:05:54,344 --> 00:05:57,850 They can move and their health can be decreased. 101 00:05:57,850 --> 00:06:01,910 These are both methods using two different method syntaxes. 102 00:06:01,910 --> 00:06:06,280 We can tell that they're methods because of the opening and closing parentheses. 103 00:06:06,280 --> 00:06:10,315 The Move method uses the single line method syntax and 104 00:06:10,315 --> 00:06:15,090 DecreaseHealth uses the more traditional syntax with curly braces. 105 00:06:15,090 --> 00:06:16,670 The result is the same. 106 00:06:16,670 --> 00:06:22,290 Now that we've seen Invader, let's take a look at Tower in Tower.cs. 107 00:06:22,290 --> 00:06:26,590 The primary behavior of a tower is to shoot at the invaders. 108 00:06:26,590 --> 00:06:29,878 We initialize the tower with a location on the map. 109 00:06:29,878 --> 00:06:34,510 The FireOnInvaders method loops through the invaders and shoots at them. 110 00:06:34,510 --> 00:06:38,680 There are private fields in the Tower class for how far the tower can shoot, 111 00:06:38,680 --> 00:06:42,090 how much it can decrease the invaders' health, and its accuracy. 112 00:06:43,220 --> 00:06:46,230 We've made it possible for the tower to miss its target 113 00:06:46,230 --> 00:06:51,362 by using the Random class to give us a random number each time the tower shoots. 114 00:06:51,362 --> 00:06:56,050 The IsSuccessfulShot method determines if the tower hits its target 115 00:06:56,050 --> 00:07:00,690 by comparing the randomly generated number with the accuracy of the tower. 116 00:07:00,690 --> 00:07:03,950 Now that we've taken a look at all of the pieces of the game, 117 00:07:03,950 --> 00:07:06,890 let's take a quick look at how it's played. 118 00:07:06,890 --> 00:07:10,399 Let's start by looking at the main method for the program. 119 00:07:10,399 --> 00:07:13,650 We can find it in Game.cs. 120 00:07:13,650 --> 00:07:18,050 The main method in a program is known as the program's entry point. 121 00:07:18,050 --> 00:07:22,190 This is the first code that will be executed when the program starts. 122 00:07:22,190 --> 00:07:26,150 Treehouse Defense can have many different levels for the player to play. 123 00:07:26,150 --> 00:07:30,740 Each level could have a different sized map, a different path through the map, and 124 00:07:30,740 --> 00:07:33,880 a different set of invaders that move down the path. 125 00:07:33,880 --> 00:07:36,650 Typically, a game would read this information for 126 00:07:36,650 --> 00:07:38,830 each level played from a file. 127 00:07:38,830 --> 00:07:42,760 This would require us to write some code to open and read a file. 128 00:07:42,760 --> 00:07:45,110 That's beyond the scope of this course. 129 00:07:45,110 --> 00:07:49,890 We're interested in learning the ins and outs of object-oriented programming here. 130 00:07:49,890 --> 00:07:52,010 You can find a link to a course on reading and 131 00:07:52,010 --> 00:07:54,900 writing files in the teacher's notes of this video. 132 00:07:54,900 --> 00:07:57,340 Instead of reading the level details from a file, 133 00:07:57,340 --> 00:08:00,360 we're constructing the level here in main instead. 134 00:08:00,360 --> 00:08:04,250 I just want you to know that this is not typically how this is done. 135 00:08:04,250 --> 00:08:07,282 It does demonstrate how to construct various objects and 136 00:08:07,282 --> 00:08:09,670 arrays of objects programmatically, though. 137 00:08:09,670 --> 00:08:12,460 This is where we actually construct the level object and 138 00:08:12,460 --> 00:08:15,010 pass it the invaders that will be in the level. 139 00:08:15,010 --> 00:08:18,940 Now, if this game had a more sophisticated user interface such as a graphical 140 00:08:18,940 --> 00:08:23,430 user interface, we would allow the user of the game to use their mouse or 141 00:08:23,430 --> 00:08:26,830 touch display to pick the location of the towers. 142 00:08:26,830 --> 00:08:31,480 We're not concerned with how to create a graphical user interface in this course, 143 00:08:31,480 --> 00:08:34,030 so we're doing this in code instead. 144 00:08:34,030 --> 00:08:37,730 There are many ways to create a graphical user interface for a game. 145 00:08:37,730 --> 00:08:41,530 You can find a link to courses on how to do this in the teacher's notes. 146 00:08:41,530 --> 00:08:44,040 In this course, we really just want to understand 147 00:08:44,040 --> 00:08:48,140 how to use object-oriented programming in C# to write the code for our game. 148 00:08:49,160 --> 00:08:53,180 We call the Level's Play method to start the level and print out who won. 149 00:08:55,340 --> 00:08:57,910 Here we have the various catch clauses to catch and 150 00:08:57,910 --> 00:09:01,420 handle the various exceptions that we expect might happen. 151 00:09:01,420 --> 00:09:06,250 Finally, let's take a look at the level class in Level.cs. 152 00:09:06,250 --> 00:09:07,680 It's fairly simple. 153 00:09:07,680 --> 00:09:11,080 It contains a list of invaders and towers. 154 00:09:11,080 --> 00:09:13,440 The meat of this class is the Play method, 155 00:09:13,440 --> 00:09:16,530 which contains most of the logic for the game. 156 00:09:16,530 --> 00:09:20,350 Isn't it fascinating that once we have the types of object in our game modeled in 157 00:09:20,350 --> 00:09:24,550 code, the logic for the game boils down to just these lines? 158 00:09:24,550 --> 00:09:29,440 Ideally, the logic for a program can be read in coherent English. 159 00:09:29,440 --> 00:09:32,790 In our case, we can read the code like this. 160 00:09:32,790 --> 00:09:37,410 While there are remaining invaders, each of the towers will fire on the invaders. 161 00:09:38,450 --> 00:09:41,820 Each of the invaders that is still active can move. 162 00:09:41,820 --> 00:09:47,000 If they score, then the player loses, otherwise, the player wins. 163 00:09:48,700 --> 00:09:52,370 That's the entire Treehouse Defense game up to this point. 164 00:09:52,370 --> 00:09:54,490 I know we went through that rather quickly. 165 00:09:54,490 --> 00:09:56,936 Hopefully it's mostly review to you. 166 00:09:56,936 --> 00:10:01,291 We'll get to know this code even more as we alter it to make the entire game more 167 00:10:01,291 --> 00:10:02,100 extendable.