1 00:00:00,000 --> 00:00:11,870 2 00:00:11,870 --> 00:00:12,530 >> ROB BOWDEN: Hi. 3 00:00:12,530 --> 00:00:13,510 I'm Rob. 4 00:00:13,510 --> 00:00:15,140 Wondering how to implement this game? 5 00:00:15,140 --> 00:00:18,400 Well, let's break out the staff solution. 6 00:00:18,400 --> 00:00:21,890 >> So, let's first head down to the init functions that we told you to 7 00:00:21,890 --> 00:00:24,380 implement first. 8 00:00:24,380 --> 00:00:30,602 First one we'll take a look at it is init paddle. 9 00:00:30,602 --> 00:00:34,550 All right, so remember that we want the paddle to be exactly centered in 10 00:00:34,550 --> 00:00:35,870 the x-axis. 11 00:00:35,870 --> 00:00:39,000 So we need to figure out where that should go. 12 00:00:39,000 --> 00:00:42,650 >> Given the width of the board-- which is also hash defined up top-- 13 00:00:42,650 --> 00:00:46,380 we need to subtract out the paddle width and divide by 2, so that the 14 00:00:46,380 --> 00:00:48,960 center of the paddle is in the center of the board. 15 00:00:48,960 --> 00:00:53,170 Remember that the x-coordinate refers to the top left corner of the paddle, 16 00:00:53,170 --> 00:00:56,210 and so this is exactly where we want it to be. 17 00:00:56,210 --> 00:00:59,950 The y-coordinate doesn't matter as much because we can place 18 00:00:59,950 --> 00:01:01,800 it wherever we want. 19 00:01:01,800 --> 00:01:07,080 So we instantiating the paddle, we set the color black, we set fill to True 20 00:01:07,080 --> 00:01:11,240 so it's a filled in rectangle, and we then add it to the window and return 21 00:01:11,240 --> 00:01:12,170 the paddle. 22 00:01:12,170 --> 00:01:14,540 And that's it for initializing the paddle. 23 00:01:14,540 --> 00:01:17,480 >> It's going to be similar for init scoreboard. 24 00:01:17,480 --> 00:01:21,950 So we're going to initialize the label, we're going to set the color to 25 00:01:21,950 --> 00:01:25,180 light grey-- you can pick whatever you want-- we're going to set the font to 26 00:01:25,180 --> 00:01:26,700 sans serif 48-- 27 00:01:26,700 --> 00:01:28,630 could also pick whatever you want-- 28 00:01:28,630 --> 00:01:30,180 we'll add it to the window. 29 00:01:30,180 --> 00:01:34,760 Now this send to back isn't really necessary, it's just in case something 30 00:01:34,760 --> 00:01:37,010 else happens to overlap the label. 31 00:01:37,010 --> 00:01:40,680 Then when we use Detect Collision, Detect Collision will detect the other 32 00:01:40,680 --> 00:01:42,380 thing before it detects the label. 33 00:01:42,380 --> 00:01:45,670 But that really shouldn't affect us in this program. 34 00:01:45,670 --> 00:01:48,720 >> Finally, we have this Update Scoreboard function that we wrote. 35 00:01:48,720 --> 00:01:51,020 So let's take a look at that. 36 00:01:51,020 --> 00:01:54,590 Now, here we see something that's almost identical to what 37 00:01:54,590 --> 00:01:56,930 we saw in the label.c. 38 00:01:56,930 --> 00:01:59,100 So we have a label-- 39 00:01:59,100 --> 00:02:03,540 a character buffer of 12 characters, which is just enough to handle any 40 00:02:03,540 --> 00:02:05,920 integer, negative or positive. 41 00:02:05,920 --> 00:02:10,310 Then we use sprintf to copy the points into that buffer. 42 00:02:10,310 --> 00:02:14,290 So s this contains a string representing the number of points. 43 00:02:14,290 --> 00:02:18,180 >> Finally, we set the label to that string. 44 00:02:18,180 --> 00:02:22,820 And then we need to center the label in case we've gone from nine to 10 45 00:02:22,820 --> 00:02:24,920 points and we've shifted it. 46 00:02:24,920 --> 00:02:29,330 So we calculate the x and y-coordinates of the label which will 47 00:02:29,330 --> 00:02:30,765 get width and the height of the window. 48 00:02:30,765 --> 00:02:34,010 Although, we could also just use the constants Width and Height hash 49 00:02:34,010 --> 00:02:35,290 defined up top. 50 00:02:35,290 --> 00:02:38,220 We also get the width and height of the label and divide 51 00:02:38,220 --> 00:02:40,160 that by 2 to center. 52 00:02:40,160 --> 00:02:43,530 And then we use Set Location to actually put it in that location. 53 00:02:43,530 --> 00:02:45,830 So that's it for init scoreboard. 54 00:02:45,830 --> 00:02:46,320 >> OK. 55 00:02:46,320 --> 00:02:50,390 So init ball is going to be very similar to init paddles as well. 56 00:02:50,390 --> 00:02:55,700 We see here that we're using newgoval in order to instantiate a new ball. 57 00:02:55,700 --> 00:03:00,810 And here we're using 2 times the radius as the width of the ball, and 2 58 00:03:00,810 --> 00:03:03,140 times the radius as the height of the ball. 59 00:03:03,140 --> 00:03:07,240 Now, also for newgoval, the x and y-coordinate that we pass in is going 60 00:03:07,240 --> 00:03:10,220 to refer to the top left of the ball, which is actually 61 00:03:10,220 --> 00:03:11,910 outside the ball itself. 62 00:03:11,910 --> 00:03:15,510 So in order to get the ball exactly centered in the board, we need to pass 63 00:03:15,510 --> 00:03:20,730 width divided by 2 for the center, and then subtract out the radius to push 64 00:03:20,730 --> 00:03:23,350 the actual center of the ball into the center of the board. 65 00:03:23,350 --> 00:03:26,810 And we do the exact same thing for the y-axis, except using 66 00:03:26,810 --> 00:03:28,490 height instead of width. 67 00:03:28,490 --> 00:03:30,890 >> So that places the ball in the center. 68 00:03:30,890 --> 00:03:35,910 And this instantiates the ball, set the color to black, fill in the ball, 69 00:03:35,910 --> 00:03:37,960 then finally add it to the window and return it. 70 00:03:37,960 --> 00:03:40,700 And that's it for initializing the ball. 71 00:03:40,700 --> 00:03:44,420 >> So now let's take a look at init bricks which is slightly more 72 00:03:44,420 --> 00:03:47,840 complicated, but it's pretty similar to init paddle. 73 00:03:47,840 --> 00:03:51,400 Now, first we need to figure out the width of each brick. 74 00:03:51,400 --> 00:03:54,610 Remember that we have a constant called calls which specifies the 75 00:03:54,610 --> 00:03:56,860 number of columns of bricks that we have. 76 00:03:56,860 --> 00:04:01,010 So, we're going to determine the width of a single brick by taking the width 77 00:04:01,010 --> 00:04:04,340 of the whole board, subtracting out the size of our gap-- 78 00:04:04,340 --> 00:04:07,310 which is hash defined up top and refers to the number of pixels that 79 00:04:07,310 --> 00:04:09,490 should be between each brick-- 80 00:04:09,490 --> 00:04:14,910 and so we're going to have a total of gap times calls blank pixels in a 81 00:04:14,910 --> 00:04:16,360 single row. 82 00:04:16,360 --> 00:04:20,450 And that will also refer to some blank pixels to the left and right of the 83 00:04:20,450 --> 00:04:22,850 left column and right column brick. 84 00:04:22,850 --> 00:04:26,990 >> So subtract out those blank pixels leaves us with a number of pixels that 85 00:04:26,990 --> 00:04:28,530 bricks are actually using. 86 00:04:28,530 --> 00:04:32,900 And then we divide by calls to get the number of pixels per brick. 87 00:04:32,900 --> 00:04:37,800 So here we define an array that just specifies the colors we want for each 88 00:04:37,800 --> 00:04:39,140 row of bricks. 89 00:04:39,140 --> 00:04:42,680 If we had more rows of bricks than colors that we specified, we'll see 90 00:04:42,680 --> 00:04:45,980 that we'll just loop back around and use red again, and then orange and 91 00:04:45,980 --> 00:04:47,680 yellow and so on. 92 00:04:47,680 --> 00:04:52,490 >> So, as the p-set spec hints, we are going to loop over all the rows and 93 00:04:52,490 --> 00:04:54,590 columns of the bricks. 94 00:04:54,590 --> 00:04:58,490 But before we loop over the columns, we see here that we're specifying the 95 00:04:58,490 --> 00:05:02,030 y position of each brick in that particular row. 96 00:05:02,030 --> 00:05:06,410 We could also move this into the second for loop, but then we'd just be 97 00:05:06,410 --> 00:05:09,640 doing the calculation over and over again when we don't need to. 98 00:05:09,640 --> 00:05:13,810 >> So the y position of the brick is going to be margin, which is hash 99 00:05:13,810 --> 00:05:17,830 defined up top and just refers to the space between the top of the board and 100 00:05:17,830 --> 00:05:19,910 the start of all of the bricks. 101 00:05:19,910 --> 00:05:24,370 And we're going to add to that the row that we're on times the height of an 102 00:05:24,370 --> 00:05:28,420 individual brick plus the gap that is between each brick. 103 00:05:28,420 --> 00:05:31,640 So this is also a vertical gap between each brick. 104 00:05:31,640 --> 00:05:34,000 So that gives us the y-coordinate of the brick. 105 00:05:34,000 --> 00:05:38,170 >> So here we're going to calculate the x-coordinate of the brick. 106 00:05:38,170 --> 00:05:42,050 Now, we have gap divided by 2 since, remember before, I said that at the 107 00:05:42,050 --> 00:05:45,020 left side of the board, we're going to leave a little space. 108 00:05:45,020 --> 00:05:47,630 So gap divided by 2 is that space. 109 00:05:47,630 --> 00:05:51,950 And then we're adding to that the column that we're on times width plus 110 00:05:51,950 --> 00:05:55,150 gap, where width is the amount of space that a single brick takes up and 111 00:05:55,150 --> 00:05:58,510 then gap is the space between each brick. 112 00:05:58,510 --> 00:06:00,700 So that calculates the x-coordinate of the brick. 113 00:06:00,700 --> 00:06:04,890 >> Now we just need to instantiate the brick given that x and y-coordinate 114 00:06:04,890 --> 00:06:09,120 using width that we calculated for each brick, and break height which is 115 00:06:09,120 --> 00:06:10,800 hash defined up top. 116 00:06:10,800 --> 00:06:12,420 We set the color of the brick. 117 00:06:12,420 --> 00:06:15,790 Notice we're using our colors array and we're passing in the row that were 118 00:06:15,790 --> 00:06:19,760 on mod num colors which is going to make us wrap back around to red if we 119 00:06:19,760 --> 00:06:22,140 have more rows than colors. 120 00:06:22,140 --> 00:06:25,020 Finally, we'll fill in the brick color and add it to the window. 121 00:06:25,020 --> 00:06:26,440 >> And that's it. 122 00:06:26,440 --> 00:06:30,190 So, that's it for all of our initialization methods. 123 00:06:30,190 --> 00:06:33,200 Now we need to look at that while loop that you had to fill in. 124 00:06:33,200 --> 00:06:39,000 So here we see that this is our while loop that is going to continue until 125 00:06:39,000 --> 00:06:42,250 game is over, which either means we run out of lives or 126 00:06:42,250 --> 00:06:43,910 we run out of bricks. 127 00:06:43,910 --> 00:06:46,390 >> So first thing we have is a Wait for Click. 128 00:06:46,390 --> 00:06:51,380 So the game waits for us to actually click before the ball starts moving. 129 00:06:51,380 --> 00:06:53,340 And then we're going to decrement lives. 130 00:06:53,340 --> 00:06:56,710 So if we had three lives, now we're down to two lives, we're using our 131 00:06:56,710 --> 00:06:58,160 third life. 132 00:06:58,160 --> 00:06:59,920 We're going to center the ball. 133 00:06:59,920 --> 00:07:05,180 So now, this isn't really going to help us on the very first life we play 134 00:07:05,180 --> 00:07:07,910 since the ball is already going to have been centered from when we 135 00:07:07,910 --> 00:07:09,010 instantiated it. 136 00:07:09,010 --> 00:07:12,910 But we see when we end up losing the life and loop back around, then we're 137 00:07:12,910 --> 00:07:15,800 going to want to recenter the ball from the bottom of the board back to 138 00:07:15,800 --> 00:07:17,130 the center. 139 00:07:17,130 --> 00:07:21,840 >> So, now here we need to generate the x velocity of the ball. 140 00:07:21,840 --> 00:07:26,060 And, as per the spec, we're using d rand 48 to generate some random number 141 00:07:26,060 --> 00:07:27,820 to specify the velocity. 142 00:07:27,820 --> 00:07:31,130 We're adding one to that since we just want the velocity in the range of one 143 00:07:31,130 --> 00:07:33,380 to two instead of zero to one. 144 00:07:33,380 --> 00:07:37,415 Finally, we're using d rand 48 again in order to determine whether the ball 145 00:07:37,415 --> 00:07:40,490 is going to move to the left or the right to start. 146 00:07:40,490 --> 00:07:45,310 >> So d rand 48 returns a random number between zero and one, and so by asking 147 00:07:45,310 --> 00:07:50,330 if that's less than 0.5, we have a 50 50 chance of switching the velocity of 148 00:07:50,330 --> 00:07:52,740 the ball to be negative. 149 00:07:52,740 --> 00:07:55,790 Finally, we set the vertical velocity of the ball to just be some constant. 150 00:07:55,790 --> 00:07:57,550 We choose three. 151 00:07:57,550 --> 00:07:59,300 And now we have another loop. 152 00:07:59,300 --> 00:08:02,800 >> So this inner loop is going to continue. 153 00:08:02,800 --> 00:08:04,960 Notice here, while bricks is greater than zero-- 154 00:08:04,960 --> 00:08:07,100 so if we run out of bricks, we've won the game and we can 155 00:08:07,100 --> 00:08:08,770 break out of this loop-- 156 00:08:08,770 --> 00:08:13,140 and all Get y Ball less than height minus 2 times the radius. 157 00:08:13,140 --> 00:08:17,310 So what this is recognizing is if the ball happens to go past the paddle, in 158 00:08:17,310 --> 00:08:19,500 which case you've lost a life. 159 00:08:19,500 --> 00:08:23,500 >> Looking inside this for loop we have the checking for a mouse event. 160 00:08:23,500 --> 00:08:27,530 And so, if there is a mouse event, that means that we want to check to 161 00:08:27,530 --> 00:08:30,880 see if the mouse was moved, and if the mouse was moved, we want to have the 162 00:08:30,880 --> 00:08:33,210 paddle keep up with the mouse. 163 00:08:33,210 --> 00:08:38,789 So, to do that, we calculate the new position of the paddle, which is going 164 00:08:38,789 --> 00:08:42,900 to grab the position of the mouse-- which grabs the position using the 165 00:08:42,900 --> 00:08:44,890 event that we were passed-- 166 00:08:44,890 --> 00:08:48,940 and then we're going to subtract out paddle width divided by 2, so the 167 00:08:48,940 --> 00:08:54,240 paddle stays centered on the mouse instead of the left side of the paddle 168 00:08:54,240 --> 00:08:55,740 staying centered. 169 00:08:55,740 --> 00:09:00,750 >> So now we also want to be sure that we don't go over the left side or right 170 00:09:00,750 --> 00:09:01,740 side of the board. 171 00:09:01,740 --> 00:09:05,480 And so here we're just checking if the paddle would be off the left side of 172 00:09:05,480 --> 00:09:08,370 the board, just stick it to the left side. 173 00:09:08,370 --> 00:09:11,000 And here we're checking if the paddle would be over the right side of the 174 00:09:11,000 --> 00:09:13,600 board, just stick it to the right side. 175 00:09:13,600 --> 00:09:17,290 And finally, we actually set the location of the paddle. 176 00:09:17,290 --> 00:09:20,610 >> Now, if there wasn't a mouse movement, that means we're going to 177 00:09:20,610 --> 00:09:21,900 want to move the ball. 178 00:09:21,900 --> 00:09:24,260 And so we already have the x and y velocity of the ball 179 00:09:24,260 --> 00:09:25,560 and so we move it. 180 00:09:25,560 --> 00:09:27,750 But now we want to detect a couple things. 181 00:09:27,750 --> 00:09:31,950 So here we're detecting if we hit either the left or right side of the 182 00:09:31,950 --> 00:09:34,240 board, we want the ball to bounce. 183 00:09:34,240 --> 00:09:39,790 And so, in that case, we set x velocity to negative x velocity. 184 00:09:39,790 --> 00:09:43,900 >> If the ball hit the top of the board, then we also want the ball bounce. 185 00:09:43,900 --> 00:09:46,750 But now we want to change the y velocity. 186 00:09:46,750 --> 00:09:49,130 Notice we don't have a condition for the ball hitting the bottom of the 187 00:09:49,130 --> 00:09:53,230 board since that was already captured up here in this while loop. 188 00:09:53,230 --> 00:09:56,630 >> Finally, we want to detect some collisions where if the ball hit 189 00:09:56,630 --> 00:10:01,040 either the paddle or the brick, we want to do some special case things. 190 00:10:01,040 --> 00:10:06,590 So if there was a collision, in which case objects will not be null, then, 191 00:10:06,590 --> 00:10:10,950 if the object hit the paddle, we would just want to bounce the ball. 192 00:10:10,950 --> 00:10:16,110 And here, also, we set the location of the ball to just above the paddle. 193 00:10:16,110 --> 00:10:19,710 Notice we're taking the x position of the ball and just reusing that. 194 00:10:19,710 --> 00:10:23,250 But here we're getting the y position of the paddle and moving the ball 195 00:10:23,250 --> 00:10:24,620 above the paddle. 196 00:10:24,620 --> 00:10:28,070 >> This is a special case so that the ball doesn't hit the paddle and then, 197 00:10:28,070 --> 00:10:31,530 before it's able to move off the paddle, another loop goes around and 198 00:10:31,530 --> 00:10:34,830 it thinks it's still on the panel and so the y velocity gets set back to 199 00:10:34,830 --> 00:10:38,210 negative and then the ball just kind of sticks bouncing on the paddle. 200 00:10:38,210 --> 00:10:42,510 So, if we did not hit the paddle, then we also want to check 201 00:10:42,510 --> 00:10:43,930 if we hit the brick. 202 00:10:43,930 --> 00:10:47,030 And so this is how we can check to see if we hit a brick. 203 00:10:47,030 --> 00:10:50,250 >> We need to check for this because we may have actually hit the label and we 204 00:10:50,250 --> 00:10:52,320 don't want to remove the label. 205 00:10:52,320 --> 00:10:57,120 So if we hit a brick, we can remove that brick from the window, decrement 206 00:10:57,120 --> 00:11:01,170 our count of the bricks, increment our number of points, and now we need to 207 00:11:01,170 --> 00:11:05,410 update the scoreboard which is exactly the same as we saw before when we saw 208 00:11:05,410 --> 00:11:06,300 init scoreboard. 209 00:11:06,300 --> 00:11:08,790 But now we are just updating the scoreboard since we've changed the 210 00:11:08,790 --> 00:11:09,370 number of points. 211 00:11:09,370 --> 00:11:12,180 And it should now display that we hit one more break. 212 00:11:12,180 --> 00:11:16,320 >> And finally, if we hit a brick we also want to bounce. 213 00:11:16,320 --> 00:11:21,240 So finally, we pause just so that the ball isn't moving super fast and we 214 00:11:21,240 --> 00:11:24,360 can actually hit it with our paddle. 215 00:11:24,360 --> 00:11:25,910 And that's pretty much it. 216 00:11:25,910 --> 00:11:32,200 So now we would loop back to the top of this while loop and continue until 217 00:11:32,200 --> 00:11:35,700 either we lose a life or we run out of bricks. 218 00:11:35,700 --> 00:11:37,300 >> What happens if we lose a life? 219 00:11:37,300 --> 00:11:41,870 Then we're going to exit this while loop, and we'll see will loop back up 220 00:11:41,870 --> 00:11:45,110 to the top of the outer while loop. 221 00:11:45,110 --> 00:11:48,740 In which case, we're going to execute this set up again. 222 00:11:48,740 --> 00:11:52,010 And this set up is going to have us wait for a click, decrement our number 223 00:11:52,010 --> 00:11:56,060 of lives, recenter the ball, recalculate an x and y velocity, and 224 00:11:56,060 --> 00:11:57,670 then resume the game. 225 00:11:57,670 --> 00:12:01,490 >> And so, that will continue until either bricks ends up being less than 226 00:12:01,490 --> 00:12:02,540 or equal to zero-- 227 00:12:02,540 --> 00:12:04,630 in which case we won the game-- 228 00:12:04,630 --> 00:12:10,430 or lives is less than zero, in which case we have lost the game. 229 00:12:10,430 --> 00:12:15,190 So, once that's the case, we break out of that while loop, and we reach here 230 00:12:15,190 --> 00:12:17,660 where we're going to wait for click before exiting the game so that the 231 00:12:17,660 --> 00:12:20,140 game doesn't just immediately close on us. 232 00:12:20,140 --> 00:12:23,420 And finally we'll close the window and that's it. 233 00:12:23,420 --> 00:12:25,500 My name is Rob, and this was Breakout. 234 00:12:25,500 --> 00:12:30,592