1 >> John Nordlinger: Hello. Good afternoon. We're going to start back up. And for those of you remotely that are joining us, welcome back. This is Kelvin Sung. You may remember he's a professor from University of Washington Bothell, a dynamic speaker which you've already experienced, and now you'll find out the secrets to building one of the most popular games in history, Breakout. Let's welcome Kelvin Sung back. >> Kelvin Sung: Thank you, John. [applause] >> Kelvin Sung: So thank you for staying for this afternoon's session. So what we want to do here is, you know, if you go look at game design books, they actually teach you how to start designing a game and all that, and that's not what we're doing. What we're doing is we are going to base on what we want to build and analyze that. If the ultimate goal is to design teaching materials, this is the beginning, that you identify an application and understand how you want to build it in this environment. Once you get that going, once you understand how to build that, then what you would do is you will analyze the concepts that you want to teach and then map that to an application. Okay. So what we're going to do is we're going to build the application first, and if we can do that in fast enough time, then we look at how we can analyze concepts and map that to applications. So to do that, so what I'm going to do here, is if we look at the Block Breaker game and just put on our software developer had in terms of we all develop programs and then see what's involved in there, and this is what I'm doing. I'm going to bring up my Block Breaker game and play that game and see what actually happened is that there are my world and then there is my paddle, and my paddle I can move, and this guy behaves like those guys up there. These guys are the same, and then I have a ball that's bouncing around. Okay. And then, you know, this is -- what we're doing is we're taking somebody else's application and analyzing it and see how we can implement that. But in general if you do this for yourself -- we can talk about that. And so after that you realize that this is what you have, and I'll show you how I designed this game. And this is what I did. We are at section 3 now and I'm going to bring up my -- this is -- this is where we're working from, and we're in section 3 and Block Breaker, I'm going to bring up my design now and you guys will laugh at me. This is my design. I feel like Einstein. You know, I wrote something down and then I have to keep it and then show people that this is how my brilliant ideas come by. The reason I draw this in by hand [inaudible] on purpose, I want to illustrate the point that you don't need to actually sit down and write a design document or anything to actually start working on this. And because these applications are really trivial to do. In general, let me show you if we look at this as slightly more formal way, while formal, 2 slightly my respectable. I'm not sure if this is whole lot more respectable. And this is what I actually did when I wanted to do this. And I only showed you one of the first thing I started thinking, and the first thing I started thinking is the most dominant object in my world. And I'm not thinking about anything else other than the dimension. When you want to implement an interactive gaming application, interactive graphics application, the first thing you think about is dimension. And in this case, I started looking at this one block I have and look at it. And then the nice thing about the capability of designing your own world dimension, remember we can specify how big our world is, is that you are free to use anything that's convenient and do that. So notice they look at this, I go like, huh, the ratio of this I like it to be 2:1. Okay. Fine. So let's use that as my world unit. So I'll take the most dominant object in my world and define that my world according to that object -- for example, if I look at this room, I mean, if I need to design this room, I may start using the chair as my dimension because I know how many there are and will give me nice proportion based on this chair. So obviously that's one unit, and that's what I did. I said this is one unit. Alternatively, you can say this is one unit in dev.5. Today I just feel like doing that. So this is one unit. So now I've defined the size of my block, and then the next thing I started doing is the horseshoe disguise P. And then I say, well, you know, there will be like around 45 percent to 90 percent height. So this is what you do before you start coding. So 45 percent to 90 percent height, this is where my block will be. And then based on that, I say lower left corner is zero zero because it's convenient. If it's not convenient, one thing you can do is, for example, these guys can be minus one, minus one, where your object will be defined between zero to one, between zero zero and the rest, so what that means is that at the very border of your application there will be one unit that's outside, which is kind of nice, it gives you a border around your application. So you can do that without doing anything special other than defining these point position. Maybe we can try that at the end of this whole thing. And then -- so this is zero zero, and then now I'm thinking that if these guys is of size two and started counting one, two, three, I will have 15 of these in -- 15 columns of this, that means that my world is 30. So now I have an application that starts with zero zero, width of 30. Notice that I don't have to worry about Xbox or Zune or anything. This is my application, and dimensions will just be defined this way. So this is between zero to 30, and then I have -- so that's the first thing -- I'm done. And then after that I start looking at my hero. There's a dominant distributed object that takes up most of the world, and then I want to look at the behavior of my hero, and in this case, I'm sorry to say that I'll be the hero. So I'll look at my behavior. So I'm looking at this and saying -- and for every hero we have for the dominant object we have, is you can look at it as its behavior and its appearance. And for appearance, you start looking at texture and all that fancy stuff way, way, way back. We just start by 3 looking at appearance. The appearance is just, well, four circles, a radius. And I'm looking at how big should this thing be, and then if you draw it and kind of have some sense of it, a radius of .5 seem right. So radius of .5 is about the same size as the block. That seem okay. And then so that's what I'm going to have. And then I'm going to define behaviors, say this guy's shoot out by the user, he bounce off the window, he breaks block. And these are important behavior because what's going on here is I've identified class one object. Not only that, identified the class one object and [inaudible] the math it needs to have. So what I can do is now I can implement this entire behavior without worrying about the rest of the game. So if you identify each one of the objects you have, and this is really easy to do because the games that we're defining are so easy. And then you can map these to concepts later, and we'll see how we can try to map these two concepts. So now we have -- and then the next thing I'm going to worry about, now this is a little bit mathematics here, is that how fast should this guy be going. And then I look in my world and go like the world is about 30 units, the world's 30 units big, and I have a pong ball that's moving here, and I have a stopwatch and go like one, two, three, that looks like about enough time to -- for my ball to travel entire 30 units in about three seconds. So the speed is displacement over -- displacement over time. So the displacement I have here is 30 units -- or actually I have it here. But it seems like writing's better. So I have 30 units to cover, and I have three seconds to cover my 30 units, so this is my speed. Then I start to realize that how often do I update myself. How often do I update. And I'm telling you that it's a system constant that the update happens 40 times a second. So there's 40 updates, updates per second. And of course seconds cancels out. So my speed is 30 divided by 120. That's the speed I want my object to be traveling at. All right. And this -- I didn't pull it out from the blue sky, I want my ball to travel across my window in about three seconds' time. So that's my speed. Now I'm ready. I can start actually to code this thing now. And what you want to do is kind of write this stuff on the side, and then you can start writing your code. And of course if we're teaching student this, and then we start writing our design document and all that, which I never do. And the company I work for, we didn't do that either. We talked about some idea, that sounds cool, and we all went and just rolled it. Of course it didn't work very well. I told you which company I worked with, didn't I. Oh, man [inaudible]. It was a great environment. It was so much fun. And then I have my paddle here, and I'm looking at my paddle, I'm a big loser here, I can't play pong very well, so my paddle needs to be very extra long, and then I want this thing to be slightly smaller. And then this is a paddle. And then this guy has behavior. I like the -- this decorating objects out here. They don't have behavior, they just have appearance. The behavior here, this guy is controlled by the user and bounces the ball. Right? So we're done. 4 So now we have -- oh, actually, the -- I think I have one more. The last one I should have here is what is a block. You know, a block doesn't move and then it destroys by the ball. So what we have here is to identify the objects we have, and then we define their interaction, and then we are actually ready to implement. And then typically when I start implementing something like this, I start with the hero most interesting objects. Notice the way you start designing this application, I start from the most dominant one, you start to define the coordinate system. Once the coordinate system is defined, you figure out the most dominant object. I usually call this guy is the hero object. And then based on the hero object we define behavior. And then we define all the interaction between all these things. So that's it. So now what we can do now is we can start and implement this now. And let's start. What we'll do is we'll start with something that we have kind of worked with before. This is the simple circle library. And if we've come in here, let's just start working from here. This is simple circle library. So I'm in section 3B. And I'm just going to open up this simple X and A. And if we look at the source code that's given to us here, we're seeing that it doesn't have a whole lot of things in there. All I have here is that I have a circle that I'm going to use this as a pointer, and this kind of helps me a little bit. And then what I have done is, lo and behold, is I'm doing what I promise I would do in terms of I set up my world coordinates as such that my lower left corner is zero zero, and then my -- the application width is 30, and then I have this thing that I call point. I initialize it a 5-2 with a radius of 1. That's kind of just like an indication of that my application is running for me. And then I have my update world. In my update world what I'm doing here is that I let the user change whatever they want to do with the left arm stick. The left arm stick is mapped to I, J, M, K, so that's kind of annoying. It's not the keyboard, it's not a down arrow key. So, you know, if we compiled this, we run, we're going to see our very boring -- our very boring circle from before. I'm going to compile this thing, I'm going to run this, and I can move this with my I, J, M, K, and this is whole lot -- this is not interesting at all. And what I want to do now is I want to implement the behavior of hero. And the behavior and appearance of my hero, and I'm going to introduce a new file here. And there are many, many ways of doing that. The simplest way I found is that this is what you tell the student to never do. I'm going to click on a file, type control C and control V while I have another file. This window right here behaved almost identically like your Explorer. So now I have this file. And if you double click on this file, you're going to get exactly the same thing as you had before. Are we all there? And then what I'm going to do now is I'm going to come in here and delete everything because I just need a template to start working from. And the -- I'm going to call this thing my ball class. Be careful that you're are not working with the original game, .cs, you're working with copy of game1.cs. Okay. And then I'm going to change the file name here also. So you can rename the file into something interesting, so I'm going to rename this into my ball class, ball.cs. 5 The ID really spoils you. This is like eMax. Have you guys worked with eMax before? No, this is like eMax. Once you get into the ID, you don't go out anymore. Then you start with -- can I read my e-mail through this? I want to read my e-mail through this. Right? That's -- I don't use eMax. I think eMax users are evil. So, anyway, so the nice thing about doing things this way is you cut and paste, is that we have the entire template here. So this is -- the template's here and all nice and all that. So here's my ball class. I'll say something and then I won't do it. The right thing to do is if you think about it, if the ball is a circle, if the ball is a circle, we should subclass from the circle. Okay. And then I'm not going to do that because suppose [inaudible] some of this stuff is for CS1. So, anyway, so let's assume we don't know that we can subclass. I'm going to create a circle, and then my circle is -- I'm just going to call it a circle. And so I'm creating a circle. And then my circle has -- well, I want to know that if it can die, so I'm going to call it -- I'm going to give myself expire, so the circle can expire. And then so that's kind of it. Because my circle object has the velocity in there, and then I can just use that. So after that what I would do is let's just start providing ourself with a construct and all that. And notice that instance variable of my ball class, and what I've done here is I forgot to type in private. If you don't type -- if you don't provide it, by default they are private. So, anyway, so I'm going to have my construct now. My construct is public so that everybody can construct me. And I'm going to create my class ball. And I'd be mindful that the ball will appear where the paddle is. So during the construction -- in the construction what I want to do here is I want to let my user tell me where I should be constructed at. So I'm going to accept a parameter. And then I will instantiate all my variables, and then I'm going to create -- I want to create my circle, and I want to create my circle at a position where it's specified, and then I will have my design document beside me and my design document will tell me that my circle's radius is 0.5. And the -- this [inaudible] tells you that treat a number as a float, now it's a double. If you don't say that, a lot of times the compiler will complain. So I'm going to -- I have create -- I have instantiated my circle, and then after instantiating my circle, what I want to do is I want to set its -- so what this has done is instantiated my circle at this position with that radius. And then now I know that after my circle is created, because it's going to be my -- act as my ball, the central object there, it has a velocity. So I'm going to set this velocity. And here I'm just going to set its velocity direction and I will do this. I will type in the X and Y separately so we don't get too clustered. So here is my float. I'm going to set this X velocity. And I want to do something random because when you shoot this guy out you want it to go randomly. You don't want to go in a well-defined direction. So I need random number. And that is why -- the random 6 number is provided as part of the base class because almost anything you want to do that's slightly interesting, you want some random access. So I'm going to go into my -- I'm going to go into my base class X and A base, but I have random float function. So I went to my base class and these are static functions on the class so that you can access it from anywhere you want. This is a global functions, right, just like backdoor global function. So here I'm going to go random float and then what I can do is that these random number of random floats lets you -- gives you random number with ranges, right, so if you want just a simple random number, you just call it like that. If you want a random number between zero and some max number, we'll call it that way, and then if we call it with a minus five, minus 0.50.5 to 0.5, this will give you a random number between positive and negative 0.5. So and then I am going to get my Y to be one. So now I have a direction that's pointing upward, and then 0.5 -- positive 0.5, that's where my bubble shoot out. And I will assign that to be my velocity direction. So this is just a direction, this XY. So now I have -- my ball has a velocity going upward and kind of like in some random direction out there, and then I'm going to remember that I want my circle to have a speed, and speed of 30F over 120F. In real life you define all these to be constants, right? I mean, this is crazy to actually type in numbers like that. And then I will say my circle should travel. Now I'm done. So if I just instantiate my circle, I'm going to get a random circle just shooting upward. And we can try that. So I'm going to save this, and then I'm going to come back to my game1.cs. So what we have done here is we basically coded a behavior we want from my circle. And what we want to do now is that we want to say that if I press a shoot button, I will shoot on my circle. And how would I do that? I'm going to go back into my game1.cs. I think I should weight it a little bit. For those of you who are done, you can go back to game1.cs and shoot the circle out. Shoot the circle out from the point. We have a point in the -- we have a point in the main program. You can shoot circle from the main program. So I'm going to come into my game 1 now, and then what I will do here is that I'm going to pull in a new instance variable under the game 1 class and I'm going to call it ball and then M ball. So that's the ball I have. And then knowing that by default I don't have anything -- the ball gets created when you do something interesting. So inside my initialization, I'm going to set the ball to a now pointer. So ball is initialized to now. It's just new now. Need to talk to some of my students. I don't speak the language well, so in class students give me a lot of hard time telling me that pronounce things -- I shouldn't say that. I have a student here -- telling me that I'm pronouncing things wrong. So I'll say this is now, they'll say it's not. And then it's -- my daughters do that also, pound and -- like a water 7 pond. Yeah. And then how heavy are you pound. I'm getting it down. I'm, okay, now. Oh, man, my daughters love that. It's like hey, dad, you can speak. >>: [inaudible] >> Kelvin Sung: Okay? >>: Yes. >> Kelvin Sung: Thank you. >>: Somehow it doesn't like my float. [multiple people speaking at once] >> Kelvin Sung: Okay. So we are going to? What we have done is that we come to the game class. We create a blowup, we declare a [inaudible] here. And then during initialization we send it to now. And then inside the update world, what we're going to do is we're going to check for a button A click. When you press the button A what we will do is we will create a ball. And then he asks you for position, where do you want to create your ball at. And what we're going to do is we're going to create it at my point. So this is a point that I can move around, and I'm going to create my ball at that position. And if you compile this and it should run. So I'm going to compile and run now. And so here is my -- here is my app. And sorry. I'm blocking you. So just want to check if A button is clicked. If it is, then you will instantiate a new -- instantiate a new ball. And any of you got -- start -- has your ball bouncing around? Not bouncing around, flying around. I'm hoping some of you have that flying around. If you have it flying around, press A many times. And you're going to see many balls, what's going on. So if you press, oh, my, God, look at that. Do we have balls flying now? Yes. >>: So I was wondering, all these balls, who is holding the set? >> Kelvin Sung: Yeah. >>: [inaudible] >> Kelvin Sung: The library's holding the set. >>: So then what if later on somewhere I want to refer to the M ball object, is it the most recent one? >> Kelvin Sung: Yeah. The one you have is the one that just got created and it's a real problem that they're flying all over the place. >>: Right. Is there any way to get to the set? 8 >> Kelvin Sung: Yeah. We have to remove it. >>: [inaudible] >>: [inaudible] [multiple people speaking at once] >> Kelvin Sung: Okay. Let me just -- one thing. I wonder if you have [inaudible]. [multiple people speaking at once] >> Kelvin Sung: If you are done with this, let's have a little bit of fun before we start fixing a problem. Let's bound the circle. Now we have a circle. We're shooting circle all over the place, right? Let's bound -- or, no, we're only going to bound the last one. So let's come into the ball class and if you remember the behavior of the ball that we talk about, so if you remember what we're talking about here, we want our ball to bounce off window. So what we're going to do now is in the ball class we're going to have an update function. In that update function we are going to bound ourself. So I'm going to come to the ball class here, and then I'm going to add in a function called updates. So here I'm going to have a public function called update and I'll type a little bit fast so that I can finish typing and come around and see how we're doing. In my update function what I'm going to do here is I want to bound my circle so it bounces around within the bound of the application. So what I'm going to do here is that I'm going to say during my -- my update function needs to have a type, it returns void, and then what I'm going to do here is that I'm going to say bound collides, bound collides status, status, and then this status will be a status between X and A base dot world dot clamp. I'm going to clamp my circle at the world bound. Let me -- so I'm clamping my circle at the world bound. This is the code we have done before, and then I'm going to switch on -- make sure that -- make sure that my circle stays in there. So bounds status dot collide bottom. If I collide the bottom or if I collide with the top, I'm going to switch my Y direction. So I'm going to collide with bottom, and then I'm also going to collide with the top. So if I have bound or top collision what I want to do is I want to change my velocity's -- I want to change my velocity's Y component. So this is something we did before the break. I'll break here. Otherwise, what I will do is that I'll check for a left and right. And for left and right, I will change the X direction. Velocity X. I'll [inaudible] X velocity's direction. And that's what I need to do in update. So when I want to update, I will either flip the Y direction or the X direction. And then what I will do is that I will call this update function from within my update world. And I will do that only if my ball exists. So here I'm going to say if now it's not equal to my ball, what I want to do is I want to tell the ball to update itself. Okay. Now the ball will bounce within the bound. And then you will only get created 9 when we're ready. You have a question? >>: Is there not some kind of container that we can add the ball to and then it will just -its update will get called regularly? >> Kelvin Sung: That's an interesting -- that's ->>: [inaudible] added the ball to the sprat [phonetic] batch, wouldn't it invoke update and draw automatically? >> Kelvin Sung: Sprat batch can include the ball. The -- now you asked me a philosophical question. The short answer is no. But in -- I am doing some of that work. Oh, man. No, no. It's a good question. Every time I talked about this thing, people ask me a question, I go, man, why didn't I design it that way. Because you work that way. That's a good question. And if people understand the question, how come I have to call this update every time. That's absolutely true. I shouldn't. And I'm doing some of the work in update anyway because of the fact that the circle can move around, I'm updating it. And here I'm just calling explicitly. So next version of library, I'll put this into the -- yeah, because I can't have that anyway, right, because ball is not derived from primitive. If ball is derived from primitive, then I can do it that way. >>: [inaudible] >> Kelvin Sung: Okay. Let's not go there. So if we are confused, that's okay. We had a sidetrack -- excellent question, though. But then -- but then what we can do here is that the ball now has an update function and then the update function is call inside game, and then if we compile this and run we will see that you can shoot balls out and all over the place and then the last one we'll -- the last one you shoot we'll just bounce around forever. And then if you shoot a lot of them, only the last one will bounce around. Because the other ones don't know that they belong to the ball. Okay. So what's going on is this thing. I'm going to bring up my -- the update here so you can look at the update if you want to. There's the library. And then here's your code. Your code has an object -- this is ball. And ball creates a circle. This is the circle. Circle is actually owned by the library. So whenever you create an object it's owned by the library, this guy is called an auto draw set. Everything in this set gets automatically redraw. Now, C# is a managed system. So what that means is that when I say ball create another one, what happens is that my -- I should draw my -- this way. My ball actually referred to an object that's created inside the library. When I allocate the new ball, what happened is that I just reassigned this pointer. This is my new circle. This is the new ball I've created. This guy is still in the set. That's why it's still being drawn. However, the behavior of this guy -- the behavior of this old guy, because there's no more reference from my code, I can't control it anymore. And I'm controlling the one that I'm 10 referring to currently. So for that reason, if you have more than one of these guys going, this is gone, this is memory leak. It's still referred by the library. So what you need to do is when something is out of the bound of you don't need it anymore, you actually have to delete it explicitly. And that's what we're going to do here, is that when you want to create a new ball, instead of just creating a new one, you need to check if you have an existing one. If you have existing one, you have to tell it to go away. So what I'm going to do here is I'm going to tell the old ball to go away. So I'm going to check if now is not equal to M ball, what I'm going to do here is I have to tell the ball to delete the draw circle. And that's the math that we don't have yet. So I'm going to come out here and say M ball dot delete circle. And we'll go implement this method inside ball, and here I'm just going to -- I just came over to the ball function and here I'm just going to delete the circle. And this is how I delete a circle. Public, void, delete circle. And then all I need to do is tell the circle to remove itself from the auto draw set. So this last function that I call line 59 tells the circle to reprove itself from this set. So it's not here anymore. So before you create a new ball, you tell the old one to remove itself from the set. Okay. Now, this is the price you pay for having things happening automatically. You create an object, you always draw itself, then when you don't want it to draw itself you have to let it know. It kind of takes away the nice thing about C# in terms of memory management. We kind of have to do a little memory management here. The good thing about this thing, though, is that your students don't need to know anything about this. So if we compile this and run, what we're going to have is we're going to have my circle now. And then when I shoot it, then I only have one of these guys instead of having many one of these. Because I always remove the existing ones. So what I'm going to do now is I'm going to show the update function. And then I walk around a little bit for those of you who are trying to follow and [inaudible] stuck. I wonder if I can help. Yeah. >>: So if you are not planning to come and see, there is no requirement that we need to [inaudible] the ball. >> Kelvin Sung: Yeah. >>: [inaudible] >> Kelvin Sung: Yes. >>: [inaudible] >> Kelvin Sung: Absolutely. You have to have a list of looking at all of them. Otherwise you will lose track of them. >>: [inaudible] >> Kelvin Sung: Because you're not [inaudible]. 11 >>: [inaudible] >> Kelvin Sung: [inaudible] so if you go to game1.cs [inaudible]. >>: [inaudible] update world? >> Kelvin Sung: Oh, you are. You're calling the update function. >>: Okay. So where did I go wrong [inaudible]? >> Kelvin Sung: No. You are always setting [inaudible] yes. You want to initialize that. You okay? Okay. Are you okay? Okay. So what we have here is actually we have this ball bouncing in our environment. And then we want to know that when the ball collided with the bottom right here, the first condition, we -- when that happened, we just wanted the ball to go away. So when that happened what we want to do is we actually want to just delete the ball. Delete the circle I mean. So I'm in the ball class right now, and then there's one special case for the delete circle -- for the bouncing, is that if I touch the bottom, I just want the ball to go away. So what I have right now is that every one of the -- every one of the sites are fair play except the bottom. If you touch the bottom, the circle just go away. So that's the indication for us that the circle has [inaudible] and then in the Block Breaker game, that's exactly what you want. And there we have it. We have the behavior of the ball. And if you remember our -when we start working with the ball and say how the ball should behave, that's all we say, that you will bounce around from the side. If he touches the bottom, he dies. And then one more behavior we don't have is the interaction of the ball with the rest of the object, with the paddle. So that is one thing we don't have. And that's what we're going to call next. Do we have a bouncing ball? If you don't, you're not going to let me know, right? Are we okay? Okay. Cool. So what we're going to do now is that now that we have the ball class, what we will do is that we -- let's define the paddle class. And instead of trying to salvage what you have done so far, let's work with the next version of the code so that you don't have to work with what you have done so far. I hope what you have done so far is that you see that you have a ball bouncing in the environment and then let's go to the next source code. So what we have done is that we have implemented a wall class, and we're going to implement a block and paddle class. Okay. And then after block and paddle class, then we're basically done. So just bear with me. We have two more examples, and then we have the Block Breaker game. That's all we have. We have like three objects, we define our world, we have the world, and the ball. Now we can get the block and paddle working. Then we are good. So I'm going to take this away, and then I am going to go to my source code, and we are done with B -- we're done with C here. This is the ball class we have. The next one we want to go to is we want to come and look at the block and paddle class. And what we 12 want to do, though, is that we will open up source code C and start from C. We are building towards D. So if you open up source code as C and if you open that up, what you'll have is you'll have a ball class and looks very similar to what we have done except that it's a little bit prettier because we have our radius, we have our speed, and then it has an expire, it has a count. And then if you look at the code, it's the same thing as what we have done before. The only thing that's slightly different is my ball has a more beautiful color than what we've seen on it. I gave you a label. Also that's slightly interesting, is that I gave some randomness to the ball I'm shooting out, about 30 percent randomness. So it doesn't cover the region in three seconds exactly. There's a -- it's somewhere between two to four seconds, so that we have some randomness in the system. So here's my ball class. And it knows how to count itself, it can let you have access to its velocity, it tells you where it is and then it tells you its radius. And then if you look at the update function, that was the time -- that was the function that we kind of spend a little bit of time in there, we see that it has an expire flag, it tells itself that it has expired. And then for the expired, what we do is that we will remove it from the draw set. That's it. And nothing interesting. And then you can delete the ball, and we've seen that working. And if you just compiled this source code that we just opened up and run this, so what you have is -- I'm going to run it now. It's exactly what we saw just now, the behavior in terms of -- so you can shoot this guy up there in red color. And if they reach the bottom, they go away. So what we want to do now is to -- we want to include paddles for this so that we can bounce this ball. Actually, even before we do that, if we want to just bounce the ball around right this time, this is our paddle. We can use this as our paddle. So how do we do that. And let's just see this working. So what we can do here is we come into update. I'm going to come into update into the game1.cs, that's my main loop place. In my game1.cs, I'm going to keep my initialized world closed for now inside the update world. We can manipulate the pointers, so I define regions so that we can hide the code that we don't want to look at. I can manipulate the pointer. The pointer is just changing the center of my circle that's called endpoint. That's fine. And then here's my ball's behavior. If we look at the ball behavior, nothing spectacular. We've seen this before. If you click the button A, if the ball already exists, I'll tell the ball to go away and create a new one and count. And then I will also say if the ball is now now, if the ball exists, I will update it in the it has expired, I'll just delete it. So these are the -- these are the behavior we've seen before. And then I print messages out from here. These are some messages I can print out for the user. So what I'm going to do here is that I'm just going to add in a couple of lines of code to give the ball some behavior here. So what I'm going to do now is I'm going to say if my point -- this is the point, collided with my M ball dot get circle, so if my point -- this is the point I have, if that collide with 13 my circle, inside the ball, and I know that there's syntax error because we don't have that function yet, the get circle function, if there's a collision, what I want to do is I want to change the ball's direction, just bounce it upward. So I'm going to say M ball dot velocity -- okay, because of syntax error, it will not let me -- the intelligence is messed up. So what I'm going to do now is I'm going to go to the ball class and define this get circle function so we can work with that. So I'm going to come back to the ball class and just define the get circle function. And the get circle function is right here. I'm going to say public [inaudible] circle, this function will return a circle, and then you will just return the reference to the circle that I have. So I'm going to just return that. And that's going to return that circle. So that's done in the ball class. So the ball lets the rest of the world see the circle. Yeah. >>: A quick typo in that [inaudible]. >> Kelvin Sung: Really? Get circle? >>: There you go. >> Kelvin Sung: You know, the problem with intelligence is that you don't notice these things anymore because they just go all over the place, and after a while you don't know how to spell circle anymore. I have a real problem with that. I didn't know how to spell circle to begin with. No, I really don't. So now what I can do is that I can come up here and change the ball's velocity, and so here I have my ball I can get at this velocity -- I'm going to flip its velocity. Oh, gee. Don't tell me that, please. So I'm flipping the ball's velocity. Man. This is -- I'm doing realtime programming here, and I shouldn't. I thought I can just show you something for fun very fast. In order to do this, what we need to do is that we need to get an instance of it and then flip the value and then send it back again. So this is what we need to do. I'm really sorry that I did this. So I'm going to get the -- get an instance of the velocity, and then assign it. And now what happened is you can use the point as a collider to actually bounce the ball up. >>: [inaudible] now or does that go away on its own? >> Kelvin Sung: It's going to go away on its own because it will be garbage collected. [inaudible] reference to it. It will be gone. To switch from C++ or C to this was very difficult. It's like, man, should I create an instance of this, am I okay? I always have the problem with that. But what we can do now is that we can actually start bouncing the -oh, what happened? Why is there no pointer? 14 >>: [inaudible] >> Kelvin Sung: Oh, thank you very much. M ball may not be defined. M ball needs to be shot. So if I want to use it, I have to check if now is equal to M ball, if not equal to, then I will shoot the -- I don't even need -- if it's not equal -- now it's note equal to M ball, then I can shoot -- I can do the collision. The ID really helps you in terms of formatting and all that. You get in this really bad habit of not formatting yourself. So what we can do now is we can shoot one of these guys and then hey, what's going on? So I can bounce it. But I can bounce it and start playing the pong game now. But then when I shoot, what's going on? >>: [inaudible] because they're overlapping. >> Kelvin Sung: Yeah. Look at that. Is that like a bug? >>: Yeah. [laughter] >>: It's a feature. >> Kelvin Sung: No, no, no. It is. I was trying to solve this problem in the library, and then I realized I don't know what the user wants. You can't decide users' behavior. But then I also realized that that's a really good bug to show the student and explain to them that hey you want to be careful because I'm creating my circle inside the ball after I create it and I start colliding it immediately, there is collision. And when there is collision I change its Y component, so the ball started bouncing around. And if you're not [inaudible] it's going to stay there forever. It's nice that we have X direction velocity so it moves away. Otherwise it's just going to stay there forever. So now we have solve that problem. But in any case, at this point, we have like a slightly -- not a really fun but it's like a -- so anyway, so we have something working. And what we want to do now is we want to replace this functionality here with a paddle. Are there any questions or anything? Anything I can help with? So if we want to create paddle, the thing that we notice is that a paddle is just a block. A paddle is just a block, a block that can't move. So what I want to do now is that I want to create my block. I want to create my paddle as a subclass from block. So I'm going to copy the ball class and do the trick again, and then this is my copy of ball. I'm going to call this my block. And I'm going to create a block class now. Then this is my new block class, and then I'm going to delete everything in between, and then I'm going to delete everything between here's my ball class, I don't want it anymore. And then I'm going to define the behavior from my block. And my block is nothing other than a rectangle. So inside my block I'm going to create a [inaudible] rectangle. So inside my block, that's what I'm going to do. I'm going to raise this to the top so we can see it. In the block class I'm going to create something called rectangle, and then I will have an instantiate -- I will have a construction for my block, and block, because I want to put them everywhere in the world, so in its constructure, I 15 will have its X and Y -- I will have its X and Y -- I will have the specified position. And then inside here, all I do is I'm going to instantiate my instance variable that is my rectangle. And what I'm doing here is I'm going to figure out my rectangle's position, my rectangle's position is defined by the -- so in the correction, the first thing I'm going to do is I'm going to define my XY position for my rectangle, that will tell me where the center is. And then the next thing I'm going to do is I'm going to specify the width and the height of the rectangle, so this rectangle's constructure let me specify center, the width and the height. And if you remember, the width and the height for the central piece of our entire coordinate system and width is of size 2, height is 1. So here I'm just going to specify 2 and 1. So that's kind of easy. Because that's what my rectangle is. That's why my blocks are. And since my block don't move, I don't need to do anything else. I just instantiate a rectangle. And blocks, all it does is that it knows how to interact with my ball, so what a block needs to do is that I have a public -- it will collide with ball. This is the main thing that a block needs to do, collide with ball. And a ball, I will pass in a ball B, and then the block will know how to collide with it. And it will return a Boolean telling me if a collision indeed happened. The reason why there's the red underlines is because the ID complaints are not returning anything. Not yet, at least. Okay. And then now I want to implement collide with ball, and then luckily the collision is very simple because all I need to do is I will collide my -- I will collide my rectangle with a circle, and then those guys know how to collide with each other. So I'm going to declare a Boolean variable to remember the status, the hit status. I'm going to say hit, and that is the same as -- that's a result of having my rectangle collided with my ball's circle. So I'm going to get the circle out here. And that's my hit status, whether there's a real collision. Okay. And then one other thing I wanted to do that's slightly detailed is that -- is that the -- if my circle hits my block on the side, I want it to bounce this way. If my circle hits the block from the bottom, I want it to -- so if my circle hits the block from the bottom, I want to refract this way. And if my circle hits the block on the side -- so basically I want my circle to behave differently, depends on how it hit the block. Otherwise you have a Block Breaker game that's kind of not a whole lot of fun because you can't collide it from the side. So I want to do a side collision. And this is what I'm doing. I'm going to get reference to my circle. I should have done that earlier, but that -- pardon me. So I'm going to get a -I'm going to get a local variable that points to my actual -- I'm going to get a circle. Because my circle is going to interact with my rectangle very often now. So I'm going to get an instance of that. And then I want to check how did I collide with the -- how am I colliding with the block. 16 So I'm going to say if indeed I hit the block, then I want to test. So if my circle -- my circle touched my rectangle, then I'm going to check whether this type of situation is mapping. And if it is, I want to react accordingly. So how do I check that? So if there is a collision, I'm going to say I'm going to check if my circle, which C in this case is to the right of the rectangle. So if my circle is on the right side of my rectangle -- I'm checking this condition. If my circle is on the right side of my rectangle, what I want to do is that I want to detect if this is happening. If this happening, I want my reflection to go in this direction and what I will need to do is I will need to flip the X component of the velocity. So I'm going to check. If I am on the right side of the rectangle and my circle's velocity in the X -- velocity X is pointing towards the -- oh, my God, I didn't think about this, pointing towards the left, so if it's less than zero, then what I want to do is I want to flip the circle's velocity. So I want to flip that. So there are conditions you need to check so that you collide the block from the sides so that things looks cooler, and else the reverse is -- else I can check the reverse. If my circle is towards the left of my rectangle and my velocity -- if I'm approaching the left and my velocity is towards the positive X direction and my velocity is of -- my X velocity is greater than zero, then what I want to do is I want to flip my X velocity again. So these are the only tricky lines for block, that I want to be able to handle the ball colliding from the side. If you don't have that in your code, the Block Breaker games do work. It just looks a little bit weird. And then, finally, if I'm not on the left or I'm not on the right, then I'm just going to shut my eyes and flip my Y direction. And then I will tell what happened to me to whoever calls me. So one option I think I can do is I will just present this stuff. Isn't that a whole lot more boring, if I just save this? So what I have -- what we have done here is we have defined a block class that knows how to collide with a ball. Not only does it know how to collide with the ball, it knows how to tell the ball how to behave after the collision. Because we're messing around with the ball's velocity. And we will tell ourself the collision status afterwards. >>: [inaudible] >> Kelvin Sung: Yes. >>: Just to be one of those troublesome students, so if we have a collision and the circle is to the right of the block, could there ever be a case where the velocity of the circle is not less than zero? >> Kelvin Sung: Oh, you know, if this were in the physical world, it will not. But then this kind of things can happen. And, by the way, these are great -- what happened when student asked a request is you talk about stuff you like to talk about. And then you don't teach them the stuff they need to know. 17 So this is where this circle is towards the right of the block. Okay. Notice that there's some collision. And then the circle can be traveling in any direction at this point. If this can happen because we work in the discratized [phonetic] world because the circle's position may be out here. In the previous update, these guys were traveling really fast, in the next update you got to here. Or the circle can be like -- so in this case, you don't want to bounce off that way, but then if the circle were out here before and you want an update that comes out to here. Now, if this collision happened and you bounce off that way, then that doesn't look right. Right? So you want to -- you know, that all the circle can come in any direction. It's a real problem. That's why -- okay. So if we're okay with the ball and -- anyway, and then so what I want to do now is that our block is actually done. I mean, that's all we want to do with the block. The block doesn't move. And they just collide with the ball, and that's all we care. And then the next thing we want to do here is that we want to define the paddle class so that we can actually paddle the ball around. So I'm going to copy the block function and paste block. What I did was I just copy and paste block. Okay. And then I'm going to work with the block class and I'm going to call this my paddle class. And my paddle class will be a subclass of block. I think I made a mistake somewhere. My paddle class is a subclass of block. And then I'm going to delete everything in this file so that I will define a new behavior for my paddle because paddle's behavior is slightly different from the block. So now I have a new clean file to work with. And I think it's my block -- oh. I didn't save it. That's all. And that's my ball class. Okay, that's good. So here's my paddle class. My paddle class I will subclass from the block and then I don't have any instance variable because my behavior depends on the rectangle that's in the block. So I don't need to have anything certain here. All I need to have is some behavior that's slightly different from my parent, so I'm going to have an instance, I'm going to have a constructor here. Now, the paddle is -- unlike a block, you don't create those things on the fly. You only have one of those things. So the paddle as constructed doesn't need to have -- the paddles constructed, we do not need to have -- we do not need to have a parameter. And then what we're going to do is that we're going to call our base class constructor, and our base class constructor's a block. And block constructor expects you to tell you where it is. And I'm going to create my paddle in the middle of the screen, and then height. My paddle is like somewhere -- I don't know, I'm going to give it like 0.5, 0.8 above the bottom. So this is the location of my paddle. So my paddle is a block. And then what else I'm going to do here, is that I'm going to -- after I create this thing, I'm going to make my paddle slightly bigger and slightly narrow -- slightly bigger, longer and narrower. So what I'm going to do here is I'm going to change its width to -- I think I want it to be five, and I want to change its height of the width and height that is on the rectangle. So I'm going to change the rectangle's width and the rectangle's height to be 0.8. 18 One thing is the block needs to let the paddle see the rectangle. So this guy right here must be protected, not private. So the paddle can actually see the -- the paddle can actually see the rectangle. And the paddle can move. So I'm going to come out here and define a function void so that paddle can move. And the paddle will move by according to users command, so you will have an input parameter X so that I can change the paddle's center position. So the paddle's behavior is that you will move in the X direction and I will let the rectangle -- I will change the rectangle center position accordingly. And I'm actually done. Now we can have a paddle that I can bounce a ball around. It looks kind of weird, but it works. So I'm compiling here. And I will run my program. And of course you see that it doesn't work because I don't have a paddle. Where's my paddle? I didn't create it. So I'm going to come into my main function, I'm going to create my paddle. So here is my paddle. I'm in my instance variable. I'm going to create paddle, p-a-d-d-l-e, paddle, I'm going to call it M paddle. And then I will instantiate during initialization -- in the world initialization. So here I'm going to go M paddle -- wait. M paddle, get new paddle. So I've created a paddle for myself. Yeah. >>: In your previous iteration of this, you had a big circle down there, and that was your MPT. >> Kelvin Sung: Yeah. >>: So can't you reuse that instance variable and then just bind it? You know, instead of having now both M points as your paddle ->> Kelvin Sung: Yeah. It's through here. The M point's a circle. The paddle is a rectangle. >>: [inaudible] >> Kelvin Sung: Yeah. That's what I should do. Yeah. I can -- you're saying that I should just delete this guy. >>: Because you won't allow the logic based on endpoint that you want to translate ->> Kelvin Sung: Oh, I see what you're saying. Yeah. Let's do that. So this is what Barb is suggesting there, now I have instantiated my paddle, and then I will come down to the [inaudible] oh, right, right here. This is the place where I'm colliding my point with my paddle -- my point with my ball, and I can just do it right here, right? The thing, though, is that my paddle is a whole lot smaller than this circle. Because what my paddle knows how to do is my paddle is a block that knows how to collide with the circle. So I have more sophisticated behavior, so I can do my M paddle dot collide with ball. How about that? Ball -- oh, sorry. So I'm colliding with the ball actually, right? 19 >>: Right. >> Kelvin Sung: How cool is that. So if the ball is there and I'll collide with it, and what if I collided with it? I don't really care. If I collided with it, I'm fine. Because my collision function is so smart that you would actually flip the ball direction for me. So that's all I need to do. Now I can actually do something smart. Right? So I can shoot out the ball. My paddle can actually bounce the ball for me. So if we come out here and then -- oh, look at that. Hey, I can't move my paddle, man, because I forgot. So what I need to do of course is that I have to say my paddle M paddle dot -- I can say dot move, move by what? Let's move it with our right thumb stick. So I'm going to move this with my game pad dot thumb stick dot right, I'm going to use the X movement to move my paddle. So now I can do this thing. Oh, it moves. I can use the left thumb stick to move my ball, and this is the shooting point. And then boom, I can shoot the circle. And then when the circle comes around, I can bounce it with my paddle. I can do this all day. That's not funny. So, hey, let me show you this. So we can let the ball go away and then it behaves properly. That's kind of cool. And here's the problem: I'm going to shoot the ball out now from this point, it doesn't make sense. I'm going to shoot the ball out from my paddle here. Right? So I'm going to come in here and the behavior is such that I just opened up the ball behavior, is that if you press your button A here, if ball's not known, I'll create one. If the ball is new, I'll create a new ball, and the new ball position should come from my paddle. And my paddle -- oh, this is the part where I'm going to get the position of the paddle. Hey, notice that when I inherited my paddle, I didn't say how I'm inheriting it. So it's inheriting as a private. So what I need to do is I think I need to do this. So what I've -oh, no. Wait. I need to make my paddle class public or else I can't get access to the block. Because what I want to do here is that I need to get my -- okay, now I'm stuck. What I want to do is I want to get the block's position so that I can shoot the ball. Now, why can't I get at the position? Somebody knows C# here? >>: So you just want to access your block? >> Kelvin Sung: Yeah, I want to access blocks. And I thought what I need to do is I need to make my -- when I'm inheriting block, I need to ->>: [inaudible] block public? >> Kelvin Sung: Okay, thank you. Okay. There we go. So block needs to be public. That's the problem. So at this point I can access the -- hold on. Okay. So what are we missing here. I should be able to get access to the blocks ->>: [inaudible] >> Kelvin Sung: Oh, no, it's not defining here. I need to get a block's position. Sorry, sorry, sorry. So block needs to be able to return to its position so that we can actually get 20 access to it. I'll return it from the paddle. So paddle will return position. So here what I can do is I'll return the position of public vector too and I will return its position that I can create -- I can create the ball and this guy will return the position of the rectangle center. So now I can in my game when I want I can get the block's position. This is impossible to follow, isn't it? >>: No. >>: It might not be impossible for people in this room, but if you're a CS 1 student ->> Kelvin Sung: Oh, no, no, no, no. >>: Is that what you're talking about? >> Kelvin Sung: No, no, no. No, I'm saying for people in this room. If you are CS 1, this is way out of -- you will not be doing any of this. What we want to do here is we want to collide -- hold on. Sorry. I am inside my -- I'm inside the -- when the A button's clicked, I want to bounce the -- I want to bounce the ball -- I want to create a new ball and then based on the paddle position, and we have that. And I think the -- it's -- wait. So this is what's it's complaining about, that there's no access to this. I will think -- did I make ball public? I keep on forgetting to make my classes public. And then when that's passed around, it gets confused. So now I'm going to shoot my ball out from the paddle, and then we can see that it gets stuck in the paddle. And we know that that problem with that is because of the -- is because of the -- it's because of overlapping in collision. So if you run this -- well, whenever you try to create, boy, it's gets stuck in the paddle. And sometimes it goes up, sometimes it doesn't. So what that means is that during collision, besides figuring out where the objects collide, for paddle areas we're interested in knowing that the ball is not inside the paddle. The ball should never be inside the paddle. Okay. So what we do is that for the paddle collision we define new function for paddle, and we can call this function public, and then we can -- public [inaudible], so for paddle's collision with ball, we're going to go collide with ball, so paddle knows how to collide with ball. And in paddle's case, what you would do is you would test to see if you are hitting the -to see if you're hitting with the ball by calling the base classes collide. So we'll call the base class collide with ball. If there is a collision for paddle, we need to do something special. If there is a collision for paddle, what we want to do is we want to push the ball outside of the paddle. So what we can do here is I'm going to get an instance of a -- I'm going to get a circle from the ball. So what I want to do is that if the paddle and the circle collide, 21 what I want to do is I want to push the circle outside of the paddle, literally push it out. Yes. >>: [inaudible] when you start it up, why not just start it a little bit higher in the first place? >> Kelvin Sung: Because it doesn't just happen when you start it up. Because what's happened -- in discratized world, this happens all the time. If your ball is traveling down this direction and then -- well, we can try that. If the ball is traveling down in this direction and then if my paddle -- if I'm out here in one update and then by the next update if that happens, sometimes the ball gets stuck. No. But that's a good point. So we can try that. So if we just return my base class -- so instead of returning the center position, this is what we're suggesting. Sorry. We're going to get my -- plus my height divided by 2. Oh, I guess yeah, I can't be too lazy. >>: [inaudible] >> Kelvin Sung: I'm just going to compute the Y position so that it's right on top of the rectangle. So here I'm going to add my right Y position by the height divided by 2, and I'll return this P. So what this is is that as suggested when you press the A button, what I'm going to do now is I'm going to look at a paddle, I'm going to look at the center position, and that's what this is, that's the center position, and then what I'm going to do now is I'm going to push the Y value up by the height divided by 2. And I guess I need to actually know the circle. So I'm going to return this position. And that won't work either because what's going to happen is now the circle we created right here. So it's still going to overlap. So if I cheat a whole lot, this is cheating a little bit. Because I know the circle's radius, so if I come out here and go P dot Y, plus equals to 0.5, that's the circle's radius. Now, that's going to push you out and then this will work now. I didn't push it far enough. Almost. Rectangle's height divided by 2. Well, I wonder what's going on, why is that not enough. Now we're really hacking. Now this will work. There we go. It works now. But then if you hit the circle at the right angle, you're going to see the circle get unstuck again, just like this situation can happen. Well, that's why I quit. >>: Cut it right on the corner. >> Kelvin Sung: We can try to make [inaudible] happen again, but then we all know it can happen. So we won't -- oh, there we go. So that can happen. That's why you want to kind of push it out and make sure that that -- it doesn't actually lap. The -- and I'll save the code for that. The next thing we can do is -- and I won't do that 22 anymore, for some reason something's not going right here. [inaudible] sightly smoother than this. I really apologize. Yes. >>: [inaudible] >> Kelvin Sung: Yes. Yes. >>: Is it different for [inaudible]? >> Kelvin Sung: See, what we want to do is that -- the behavior is slightly different in terms of the paddle, and after the collision the paddle is still alive, versus the block. Once the block touches the ball, it goes away. So whether after -- the behavior afterwards you don't care. That is why the paddle will actually have a different behavior. That is why here after the collision you want to make sure that the ball doesn't overlap the paddle anymore. So that's what I was going to put in the code here. I will not test your patience. So what I'll do next is I won't just go through this code and type all these things out. I will just tell you what happened next. And like I say, I apologize. I'm not sure why this is not going as smooth as it should be. But then -- and happen in classroom also. And let's pretend it's just a really bad class. The important thing that I hope you will walk away is that this -- to work with game-type situations, you want to create your object and you want to update the state. The engine should be somehow just calling your update. And if the engine is slightly more sophisticated, you will call your draw function also. So it's initialize update draw. It always works that way. Okay. And then if you have that in your mind, remember when you want to see something moving, don't write a 4 loop around it or don't write a [inaudible] loop around it. That's something that's very difficult for me in the beginning. Just let it happen, because you will. So update things incrementally. So if we're okay with that, the afternoon session, the past one and a half hours that seemed like five years, is that I'm trying to explain to you that when you want to write a single graphics application, draw it out on the paper first. Figure out the dominant object. Define your coordinate space based on that dominant object. It makes that world a whole lot easier. Okay. And then typically because we're not doing very sophisticated graphics programming, we typically have a central object that's dominating, that's our hero. Interact would allow a bunch of supporting things. Implement, define that central object first like we're doing for our ball. And typically it's not very difficult. So implement that object define that object, and then define just what we're doing that seems just like the past four years we're doing this thing, did fine the paddle that to interact with. And then when you have that working, the application basically works. And that's what we have here. It's limping a long here but it basically works. 23 The next thing we want to do is in the you will believe me that block is actually there, that you can interact with the ball. We actually see that it knows how to interact with a ball. All we need now is to have an array. We need to have another array to put blocks out here. And because we did so so carefully, that the blocks, there are 15 positions of this thing. And then the first position is position 1, 2, 3, 4 -- you know, this is 15 of this same because we defined these guys so carefully. So we just go through a two-dimensional array and lay these guys out and we are done. So [inaudible] showed you the code for that and then we don't have to suffer through this. And if you will still let me speak, I will tell you a little bit more about how we design assignments around these things. So what we have here, I'm compiling this thing and I'm running and then -- oh, sorry. I started the wrong one. This is the one that we're building. So I'm going to come out a set of blocks, and we can see that all we need is a set of these guys. And so I'm compiling a set of blocks. And that's what we have. So instead of just creating the blocks all the time, I have a random number, say between zero to eight. If a number is between zero to eight, I will create a block. If the number I got is bigger than 0.8, I won't create a block. So, again, a random number between zero to 1. If the number is less than 0.8, I will create a block 80 percent of the time the blocks are created. That's why we have this. So every time when I regenerate this, I whether get a different set. And then what I can do now is I can move my paddle and then the paddle will just interact with each one of the -there's no new in functionality here. All I have is I go through an array of this stuff. Okay. So this is the last part. And then this part, what we have, I want to see that this is your Block Breaker game. So we are almost there. And I don't want to try my luck, give you the last class that I -- I'll show you the code a little bit, show you indeed it's really, really, really trivial. >>: [inaudible] work on a keyboard or the pad? >> Kelvin Sung: Yeah, yeah. So at this point because this is running from our library, I can move this thing -- I can -- you know, I can shoot the ball out. And I think G will recreate it. Because we are updating this thing every -- I can recreate how I want. And students always ask me this is not fun because you can never lose. And I'll say, yeah, I'm not writing this for fun, I just want to see if I can do this. This is the code that I want to show -- we didn't write. This is the code that we didn't write. And this is the blockable probability where we don't -- we want to create -- it's 70 percent of the time we want to create, and here is the data structure of all the blocks I have. And then when I want to initialize the block, the first thing I do is I will delete all the 24 ones before, making sure that I'm not in the draw set anymore, and then I will create a new one. And to create a new one, like I said, I'm going from zero to 15 in the horizontal direction. I'm going to zero to 8 in the vertical direction. And then here I'm computing the coordinate position of my block. It's C times 2 plus 0.5. That tells me where my blocks are. And this tells me the Y positions of [inaudible] so it's not at the very bottom. And then after you create them you put into the set, and then when the block -- the block set knows how to interact with the ball, so break blocks -- the update function, we'll call this break block, and all we do is we do a linear search through my array colliding with the ball. If there is a collision, I delete it. And when -- because whenever a block collided, I can delete it. I don't have to worry about behavior afterwards. So the collision is much easier. And if there's a collision, I just remove it. So that's the last part of the code that we didn't type in. I guess if I were a little bit more coherent, we could do that. So, anyway, so this is the game that we didn't build. I promise you we will. We didn't. The thing that after that is that you can start putting in file texture. We know how to put in file texture. You can start putting audio effect. And then what you do, to compare the last one we see this with one. This is the actually very, very last one. And then if you look at this and you look at the one we saw earlier, this looks more fun. And if you put in sound, then this is actually indeed more fun. The point I'm trying to make is that the last version, the one we're seeing here and then the one without a texture and the sound, they're identical. There's no conceptual difference whatsoever. And then if you give student this assignment, they are much more motivated. They'll actually spend time working on it. So I have about half an hour more I guess. Yeah. I have about half an hour more. I will go through something really quickly to show you how this stuff is made into assignments, and then maybe we can have some discussion. And I apologize for this. I don't know what happened in the last hour or so. Maybe it was the food. I think pasta is not good for my brain. I can usually -- I'm [inaudible]. So, anyway, so here I just want to show you the -- developing a simple game theme application -- when -- develop a simple game theme application. This is kind of a summary of what we just went through. And this is where on the second day of the workshop where we will be organized into groups and we'll write our own games. And then the goal is to implement a game like the Block Breaker game we have seen and this is how the task will be separate -- will be divided. And whenever you develop interactive application the first time, interactive graphics application the first time, it's important to recognize the logic part from the graphics part. You want to minimize the logic. The logic is the behavior of objects in your application. You really want to minimize that and you want to maximize the graphics. So you want to concentrate on working on the graphics part. Because in game AI or the behavior of the object, what we have, the behavior of your objects, it's our bouncing ball. It's really straightforward. And you want to keep that. You don't want to have like object 25 A is moving around and object B knows how to follow object A or object B knows how to locate object A as object A is moving around. Those things are really difficult to implement if you have never done it before. If you look at the map, it's actually not that bad. But if you've never done it before, it can be very tricky to implement. So if you want to do this in class, do those things last. Do the things that are easy to implement. Use randomness. And then what you want to do is you want to choose some kind of a game type. Now, for example you want to choose -- here we tried to separate out in three categories, these have graphics pictures, animation with visualization, and more interactive graphics. Let me show you what I mean. And graphics pictures are things that show -- your game type will respond to user's command and you will draw something static that's not interactive. And then if you want to have something with the animation or visualization, you can have like a ball that drops and bounces around. And you can visualize random samples. So these are all graphical visualization of what you will do anyway. And for interaction, what you did is after initial objects set up, you will have one or multiple objects interact, and one of those will be under your users' control, your students' control. And let me show you this. So, for example, what you can do is you can set things up like card games or you can set things -- define board games or interactive games. So let me show you this is a snake and ladder. And so what this, this is a programing assignment on two-distributional array. So this is two-dimensional array of objects. And then what you will do is that you will -- what we have done is we've developed this so that your user -- your students do not need to worry about the graphics. Actually, our assertion is that you don't even need to worry about the graphics. If you use this assignment in class, this is an array of objects assignment. All the graphics is provided for you. And all you need to do is give the assignment. And all student needs to do is be able to reference to objects, delete objects or create objects based on the offset that's given to you. And so I think -- that's moving. And then if I come to a goal, I will take the goal. And so on. So these type of assignments are for practicing, just like a CS 2 assignment. And then let me show you a couple more. So here is -- you guys play Othello? So here you can -- so now you just play [inaudible]. I don't know how to give sound to this game. So at night it was like 3 o'clock in the morning, I was really tired of looking for sound effect, so I go [makes noise]. That was me. That was me. That was my blip just because I was so tired looking for effects. It's just what the hell, I can do this myself. And then there are others. And so those are like term based, nothing happened in between. User press a button, you make something happen and then you stop. And then these type of assignments are slightly more difficult to implement where -- so this is a hierarchy. This is object hierarchy where we want to students to see the difference between a rock. So this is a 26 rock. Those are all me. And then this is a -- this is a firework. That was too far. This is a firework. So and if you look at the behavior of the rock and the firework, they are the same. So this assignment is for students, to give students some framework and they have to look at the behavior of a rock. And it's actually a [inaudible] object and they have to implement rock and fireworks to -- and that's what this assignment's about. And, finally, let me just show you this, and maybe we can all go. This is alphabet hero. This is -- this is binary search tree. Right. So there I have my binary search tree, and then all the flying guys are insert command. So now I'm going to come in and get a Q insertion. And he tells me Q is duplicated. Q is duplicated and these guys are search commands. So I'll come here and touch V, V found V. Now, if you don't have the binary search tree behind the game, nothing works. All the graphics and everything is there, just nothing works. But then you have binary search tree, then it works. And in this case what you can do is you can I think duplicate the tree is X, so I can clone the tree. So what the students do is implement a cloning of a binary search tree. If it's not done correctly, then this will not show up correctly. And finally you can balance a tree. So here I'm balancing the tree. And students can implement all those. And if you look at this assignment, when I was a student when this assignment was given, I have a character screen and if you type in A, they say input a character, you put C and then say print it out, you print it out, they say C. That was not very satisfactory. And you can argue this is not very satisfactory either. When student use this type of assignment, they spend a lot of time making work, and then after it's working they all get angry because they can not improve it. We have a very tight definition so that students can't change too much, and that's by purpose. Because what studies have shown is that when you have this type of assignment in class, those two dominant students that you have in class that knows the world anyway, they're going to build a gigantic game and then show it to everyone in class. And the rest of students in class is going to look at that and go like I should just kill myself. So what we've done is we provide them with this really tight interface. You can't can do anything else. Implement this thing. And those good students, they get so angry in the feedback form, you really affected our score. So when we write papers, we can't lie about this stuff. So we have to say student satisfactory is not that high. And our papers don't get accepted anywhere because of it. [inaudible] but then if you look at the amount of time students spend on an assignment, it's giganteus. They spend so much time on the assignment and their projects don't have bugs. Because when they start playing this game, if it crashes, they know, they test it really, really well. Okay. Whoever will listen, I'm not sure, I think half of audience here really don't care about what I'm saying. But whoever will listen I'll say it because they won't let us publish this and we can't show students we're really excited about this thing. So there' a 27 balance somewhere. If you use this stuff [inaudible] to entice student, watch those couple of alpha students that's going [inaudible] rest of the World. But then the if you watch too hard, students get angry, and they are really resentful. That's what we learned. So, in any case, so and we went through this exercise, we want to draw the world. And then so this is all there anyway. I just go -- I promise you in about five minutes we'll be all done, and I really apologize. Typically my presentations are of slightly better technology. So what we have here is what I showed you is that at the very last I give you a proposal of what you can do yourself. And then what we have done is we come up with guidelines to kind of work for you, if you really want to do these things, we give you steps that you can follow. And that's what these guys are. These are steps that we are recommending what you can do if you want to do this stuff in your class. And then here are guides to design your own assignments. And I won't brother with those things. Are there questions? I feel really bad that the past hour was -- I should stop apologizing. But John is here. He's not going to fund me for the rest of my life. Yeah. Yeah. >>: What text would you use if you were going to incorporate this and make your 161 or 162 ->> Kelvin Sung: What would I use? >>: Yeah, fully game centric. Would you use [inaudible]? >> Kelvin Sung: This is a preset question. My view is that -- and my view is the right view, is that -- why is that funny? No -- is that concepts in textbook are independent. All the textbooks are teaching the same concept. And we're trying to demonstrate that in our work and we're not completely done yet. When we are done, this will be what we see. So I'm going to come here and show you -- so here is the release of the work that's online. And here we describe what we are doing and everything. Let me show you there. Like I said, we have all these examples, and then here's a basic IO display of screen output sequence structure and stuff like that [inaudible]. We map all these example to three textbooks. We're still mapping that out. This is the first example. It maps to PLD. I'll show you what that is, C# for programmers, C# for whatever. So there are three textbooks. Same example. So if idea is that if you use any of this textbook it doesn't matter. And if you use a textbook that's text based, all the better. So students can see how this is presented normally and they can see an extra example. So this material works really well if you teach your regular class in the regular way, and then just give this to student to go play with it. And then what happened is that in here we have step-by-step guide on how we implement this stuff anyway. So what your student can do is look at this and go like, oh, this is quite a bit of reading. And then they can go like, okay, and then we show them where are the code put, and then we describe what's going on. And then the source code is given. So they can just compile this in run. 28 And then if you look at the actual code, it's like three lines of code you need to change. So the idea is I don't think you need to have a textbook for this, but we are fishing for publishers that we can publish stuff as textbook, and we would like to. But that's way down the line. So thank you for the question. Are there any excellent questions like that that I can show more of the work that we have done? I really thank for your patience. And are there any other questions? >> John Nordlinger: I have one. >> Kelvin Sung: Please. >> John Nordlinger: Kelvin's being a little bit too modest. When he said papers don't get accepted, he's actually been accepted [inaudible] conferences. So if you wanted to pull up his papers [inaudible]. >> Kelvin Sung: Yes. We have our hits and misses. So some of the works are published. And people's reaction to this is actually quite positive, that wow, this is interesting. So I should be careful with what I say in terms -- especially in the public. It's like, oh, everybody hates me. I'm not sure if that's true. They may. Well, I got to stop anyway. So thank you very much. Thank you for your patience. Thank you. [applause]