字幕列表 影片播放
Hey, guys, my name is Frank.
I'm starting a series on how to program a tile based platform and game called Rabbit Trap.
It will feature tile based collision detection in response, scrolling maps, loading levels, Sprite animation and interactive game objects.
In this first part of the series, I'll be talking about how to build a strong foundation for the game.
The concepts I'm going to explain are strongly rooted an object oriented programming and could be used in any program to improve organization of modularity.
This might seem boring, but if you use this approach, it can save you hours of editing and frustration and leave you more time to focus on fun stuff like level design and graphics.
So be sure to watch this video in this video.
I'm gonna talk about the model view controller approach to organizing a program and how the different components of this example work together in the main Js file.
Then I'm gonna talk about how this structure increases, maintain ability and modularity, as always, feel free to use the comments section and be sure to check out the links to the source code and working example in the video description And if you learn something, give this video alike.
So basically, what I have here is just an example of a model view controller architecture where you separate out your game logic from your display logic, and you also separate out your controller logic.
So I have my game logic stored in the game class display logic in the display class in the controller logic in the controller class, and each one of these handles its own business, and it's totally separate from the other.
So I'm not gonna run into any issues with having references to the game logic inside of the display.
I'm not gonna have the controller logic reference inside of the game.
I'm gonna have all these different components interact with each other through their public methods inside of the main Js file context.
And by the way, each one of these classes defined in its own individual file.
You don't need to have your own individual files, but it makes it a lot easier to just used these different things and other applications.
If I choose to, for example, the engine, I might want to use this fixed time step engine inside of another application at some point, so it's nice to just store in its own file.
But anyway, what all this code does for this example is basically the game Class controls color value right here.
That's the color variable from the game class, basically just increments the different red, green and blue channels inside of a color value.
So change these different colors that you're seeing on the screen.
And then it will talk to the display class, which governs things like the canvas and re sizing the canvas with screen re sizes and rendering.
And the game will hand a color value to the display in the display will render it on every frame, and the engine takes care of frames.
As for the controller, I didn't really have anything cool, Dude, the controller for this example.
So all it does is take user input from the keyboard until the user which key here?
She pressed.
So, for example, I just pressed the a key.
That's key 65.
So basically what I'm trying to say is, I want to keep things as organized as possible for this rabbit trap game, and I want you guys to kind of think about organization of code before you start developing a game.
Because if you just jump into things and try toe mesh all this together in one big file with references going between different components, it's gonna get very messy very fast.
And here's an example of that that I want to show you.
So I define all my components.
I defined my engine, is gonna run at 30 frames per second, and I'm handing in the rendering up the function down at the bottom of my main jazz file.
I'm gonna start my engine, and that's gonna execute the render an update function 30 times per second until I stop my game engine.
So the render an update functions.
I define up here and these air them right here.
So the update function is just gonna tell the game to change that color value.
And that's what the update function.
The game does just increments this color value in a random direction gradually to change the color.
Now, the render function is also gonna be called in every frame of my game loop and inside.
I'm actually gonna be communicating the game's color value to the display, and I'm gonna have the display object draw that color value to the onscreen canvas.
So here is a great example of why this is so good.
So I could just as easily right object liberals to govern my display logic and my game logic.
And you've seen that if you've you've washed my other tutorials, I'm kind of sloppy.
I just throw stuff together with object liberals here.
I'm not doing that.
If I had written object liberals, I could put a reference to game dot color directly inside of the displays.
Render color function.
Or better yet, I probably wouldn't have even had her under color function.
I would just have a render method that handled rendering the entire thing.
The reason I have to hear is because render color draws a color to a buffer canvas and then displayed out Render renders that buffer canvas to the final answer in campus that you see.
So the old version of how I wrote my code or just the sloppy way that I write my code would just be to put to object liberals on the main Js file and what would be displayed won't be game, and I would have a reference to game dot color inside of my render, function and display would just draw that color directly to the campus.
Now the reason this is bad is because, say, I want to change the name of my color variable to Hugh if I go ahead and I have a reference to game dot color inside of my display and I changed the variable color to Hugh inside of my game object.
Now, all of a sudden I'm editing my game class or my game object to change that value to Hugh, and I have to go into my display object and change all the references to game dot color to game dot Hugh.
Now that's a pain.
I don't wanna have to do that, and it's unnecessary, so I don't see why I do it anyway.
With this method, the M V C approach, you don't actually have to have any internal references to any other components.
The display on Lee has references to itself inside of itself.
The game only has references to things that it controls.
So how do they communicate?
They communicate just like this?
They communicate through public methods so display can only communicate with other objects like game and controller through public methods that it has.
So if I come into the display object here and take a look at render color, you can see that just takes a color value, and inside of it does exactly what I said.
It just changes the buffers Phil style to the specified color and draws that color too.
The buffer campus.
And then here's the render function, and all this is gonna do is draw the buffer canvas to the final display canvas.
I'm not gonna get too much into detail on that, but you get what's going on here now.
I could have just as easily gone like this inside of this function and said Game dot Color had I made these object liberals instead of classes.
But that's actually really bad practice because, like I said, if I change something inside a game, it might break my display object and prevented from working.
So that's twice the editing that I'm gonna have to do because I'm gonna have to change all the values in display as well as all the values in game.
So this is just a much cleaner way of doing things so Basically, this is how you want your different components interact and just take a look at this main Js file.
It's really short.
Everything is super clean.
I just have my two functions here.
Render an update that a hand into my game engine and here I'm defining everything.
This is super clean.
I don't have huge object liberals to take care of.
Just sprawling out across my screen here and my editor and to instead she ate everything.
It's real simple.
I just add my event listeners for the screen resize and the keyboard inputs.
And I just resize my screen initially, So my canvas fits the screen.
When I start up and I start my engine, everything runs the way I expected to.
So using the NBC approach or just separating out the different components your game until logical groups is a really great way to keep your code maintainable and modular, and I'm gonna get into why in the next part of this video.
So now I want to talk about how this approach makes things more modular and more easy to maintain.
So obviously right off the bat, it's a lot more organized.
You can see that clearly I have my different components reference here and in Stan Shade here in one single line each rather than having big, sprawling object liberals to find.
And by separating these things out into their own classes, I have the option of putting them into their own files, which makes things even more organized, because I could have all of these different classes right on top of each other in one big file.
Or I could separate them like I did into their own files.
And now, if I want to edit the game logic, I only have to deal with 42 lines of code, apparently, instead of having to search through one big file.
So that's obviously one way that this technique lends itself to easy maintain ability.
Then there's the other thing I mentioned where you don't have internal references toe one component inside of another component.
And like I said, then it's a lot easier to just work with public methods and have your components communicate via public methods.
Kind of like is happening right here in the render function Display is interacting with game through a public method called render color, rather than having an internal reference to game dot color, which would be a lot harder to maintain.
Because if I change game dot color in the game object, I'm gonna have to go through display and edit all of those references to game dark color.
So this is another way it lends itself to maintain ability.
Now, what about modularity?
Okay, well, I've got a engine class down here, which is basically a fixed time step engine.
Now, I can use this engine in any application that I want to.
And it's very easy for me to do that because this is a totally self contained class that I store in its own file.
Now I don't have to store in its own file, but by storing it in its own file, I can very easily just reference that single file in another application and then all of a sudden, bam, I have a perfectly good game engine for a whole another game, and I didn't even have to write code for I already had it on hand.
But if I were to have that game engine integrated into all my other components, it would be a lot harder for me to extract the the engine components from, say, the game logic.
And that just isn't very modular.
The wet have it set up now is very, very modular.
And it will save me a lot of time in the future when I need a game engine object.
So sometimes I write my code this way for most of my tutorials.
I just throw stuff together in one file because I want everything to be there for you guys to see upfront.
I don't wanna have to bring things in from other applications, but this is how I would go about writing a more structured application.
And that's what I'm trying to do.
I'm trying to write this game rabbit trap, And I just wanted to be very structured, and I want everything go smoothly.
So using the M V C approach and separating my game logic from my display logic and my controller logic is just gonna make everything go super smooth throughout this whole process.
So anyway, I hope this is been a good explanation of how everything is gonna be for this rabbit trap thing.
And I hope you guys are interested in what's gonna come because I expected to be a really cool game before I wrap things up, I want to talk about my HTML for this example.
So I actually am going to do a whole bunch of parts in this series.
And rather than having to upload the spreadsheet for this example 1000 times my get home page or have remained parts I have I don't want to upload this multiple times my get home page because I don't wanna waste memory space.
So I'm just gonna use the same graphics.
I'm gonna use the same html five and CSS file, and I'm just going to write new JavaScript files as need be so that's gonna keep the memory footprint on my get hub.
Paige a little bit smaller for this whole, uh, Siri's that I'm doing.
So anyway, the way I'm going about that is inside of my HTML.
I'm dynamically determining which job script files to load based on a U.
R l variable specifying the part numbers.
So when I come into my actual html page here and I look at my your l to the rabbit trap that each team will file at the end of it, there is a question mark and a one which is the part number for this example.
Now, if I wanted to get the part too, I would just come in and type two.
I haven't actually made typed Part two yet, but that's how you would access Part two.
So I'm accessing these different parts with a girl variable.
That is just the part.
And I have a default toe where if you don't specify anything, it just brings you part one.
So that's what I'm doing and this big chunk of code in the minimal.
The middle of my HTML file is taking care of that for me.
So it just it defines all the sources I'm gonna use.
And that's just these files.
Here.
It gets the girl variable or that part number from my girl that no one after the question mark and then it goes ahead checks to see if the viable part, if there is no part specified, it just sets it to part one, and then it just loops through an adds a script tag for every single job script file in the application.
So I'm always gonna have controller display engine game Maine and manifestos just my script for the video, and I'm just gonna add a new script for each one of those, and I'm gonna at it.
I'm gonna parts together the u R l or the source attributes to match whichever parliament.
So hopefully that was a good explanation of how I'm actually getting these things in.
And if you have any questions about why my HTML was weird like this, that's the reason I'm just trying to save memory space on my get help.
Paige so being cheap.
But I kind of figured out this cool little script to just import a job.
Script files based on what?
Parliament.
So anyway, that is an explanation of that.
This party is going to be on adding a player object to the screen and controlling him with the keyboard.
This is a vital component of any game.
So stay tuned to find out how it's done in this video, I'm gonna talk about the example program what it does and how the program has changed since part one.
Then I'm gonna show you the specific code that handles creating the player, controlling him and drawing everything to the screen.
Finally, I'm gonna show you my implementation of a fixed time step game loop and how it works if you have any comments or questions post, Um, and if it ain't point while you're watching this video, you get the sensation that you're learning.