Game Development with Lua and LÖVE: Create an RPG from scratch! | Kyle Schaub | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Game Development with Lua and LÖVE: Create an RPG from scratch!

teacher avatar Kyle Schaub, Software Engineer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Introduction

      1:23

    • 2.

      Installation and Setup

      6:43

    • 3.

      Player Movement

      8:47

    • 4.

      Sprites and Backgrounds

      4:23

    • 5.

      Animations

      14:08

    • 6.

      Level Design and Tiled

      7:32

    • 7.

      Camera

      9:49

    • 8.

      Physics

      9:44

    • 9.

      Collisions

      13:36

    • 10.

      Wrapping Up

      2:41

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

384

Students

1

Projects

About This Class

For beginner and experienced programmers alike, one of the best tools to learn game development with is LÖVE (also known as Love2D), an open-source game engine that allows users to write the logic of their games in Lua, an easy to pick up scripting language. These hidden gems of the development industry are perfect for learning the basic concepts, as well as applying them to create full-scale applications. Additionally, all of the software is open-source and free!

This class walks through the process of setting up your development environment, getting all the necessary software downloaded, and jumping right into creating a game! We will be creating the foundation for an RPG-styled game with a main character that can move with the arrow keys, has animations for each direction, and a camera that follows the player wherever they move. Additionally, we will discuss how to use Tiled, a fantastic level editor that allows you to easily design maps and levels that can be imported into your project.

Although you can follow along with the videos without having any previous experience coding, I do recommend having some familiarity with Lua, just so you have some extra context on how everything works. If you're interested, I do also have a Lua Programming class on Skillshare, which requires no prior experience at all.

Meet Your Teacher

Teacher Profile Image

Kyle Schaub

Software Engineer

Teacher
Level: Beginner

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Welcome to the game development with Lua and Love class. Throughout these lessons will be discussing the process of creating games from scratch, using love, also commonly called Love 2D. And we'll be doing all of our coding in Lua. The class is project-based. The goal is to create this game here, which could act as the foundation for any RPG style game. This type of game is a perfect introduction since it involves player movement, reading keyboard input, adding sprites, animations, collisions with physics and level design using tiled. While working on this project, we'll talk through all of the core fundamentals of using love so that you are capable of creating unique games of your own or building onto this one. You don't need any familiarity with game development or love to de, to take this class. We'll talk through how to get everything installed and setup on your computer and then go from there. I do recommend that you have some experience coding though. If you've used other programming languages besides Lua before, you'll probably be able to pick up on the language pretty fast. However, if you are brand new to coding or you just want to get a feel for Lua. I have another Skillshare class called introduction to Lua programming, which assumes no prior knowledge and will completely prepare you for this love 2D class. Whenever you're ready, we'll start things off by installing love and getting things set up to code our games. Go ahead to the next lesson. 2. Installation and Setup: Hello folks. In this video, I'll go through the steps of installing the game framework. Love to de, to your computer and also show how to set up new projects and how to run them. Installing love is very easy. You just go to love to d.org. And the download links are right here in the middle. If you're on Mac, you can just download this file and install the application. And if you're on Windows, I recommend the installer. While you're going through the Windows setup, makes sure that you keep track of this path right here, the destination folder. We are going to be using that in just a second. Once the installation completes, I recommend creating a shortcut to love on your desktop. If you're on Mac, you can just add the love application to your doc on Windows. We're going to visit that installation path from just a moment ago. In my case, it is here in C Program Files, love. And if we take a closer look, and we'll find this love dot EXE file, right in this folder. If you don't see the dot EXE part, you can go up to View and then choose this file name extensions. And that'll show the extension of every file. So we want to create a shortcut to this love dot EXE. So I'm gonna go down to Send to desktop. And then we'll see that there is a shortcut right here. I'm going to go ahead and rename this to love. Once this is ready, you can go ahead and double-click it to start. Or if you're on Mac, just run the application and you should see a window that looks something similar to this, just some weird-looking animation. It might look slightly different depending on what version of love you're using. But this is the screen that shows when love is running, but no game is found. And if you see something like this, that means everything's good so far. The next step is to install some text editor that you'll be using to code. You can use anything that you're comfortable with. But I highly recommend Visual Studio Code, which is why I use in these videos. And it's completely free. You can get it from code dot Visual Studio.com. And the download links are right up here. Just download the correct one for your operating system. Once you've downloaded and installed Visual Studio code, go ahead and start it up. In this program, we'll be able to edit and create files for our game. To do that though, we'll need to create a new love project. Projects and loved to D have a very simple structure to make one. You're just going to create a new folder anywhere on your computer. And my case, I'll just make my on the desktop so I'll right-click and choose New Folder. And I'm going to call this folder my game. So now I just have a folder called my game on the desktop, or this folder can be anywhere on your computer. Then back in Visual Studio code will want to open that folder. And we can do this with File. And then Open Folder. And I created my folder on my desktop and right here, so I'm going to select this folder and choose Select Folder. So now our folder is open. We can see the my game name in this section and the upper left corner right here. Now that we're here, the next step is to create our first Lua file. And we can do this using this new file button. You might have to hover over this section to see it, but click New File and we need to name this file main dot Lua. It must have this exact name. And once you press Enter, the file will be created and it should open up this new tab over here. It says main dot lu up. It's just an empty file right now. And this is it. This is the simple structure of that all loved to DIY projects start with simply just a folder that contains a file called main that Lua. Of course, you'll be adding more to this folder, but just having this alone allows us to run the project through love. There's a few ways that you can run a project. Here I have my project folder, just my game. And as we just saw, it just contains this main.py file and that we just created. And one way that we can run this code is by taking the project folder and dragging it onto a love shortcut. And if it's successful, it should pop up. A love window might say untitled, and it's just a big black screen. If you see this, then that means that it worked. Since our main.py file is empty, this is expected an empty game. Once we add code to this file, the window will start showing whatever we choose our game to be. As a side note, you can drag and drop folders from anywhere on your computer. It does not have to be specifically from the desktop. Now although dragging and dropping is easy, we can make it even easier by running our project through Visual Studio Code. To do this, we just need to install an extension. And extension is just a plug-in that makes VS code do something specific. So in this Extensions tab right here, we're going to search for the specific it's essential that we want, which is called loved 2D support. So when you search for this, you should find this love to do Support plugin. So you can go ahead and install that. And once you see the Disable and uninstall buttons, you know that the extension was installed successfully. From here though, we do need to configure it a bit. So using this gear icon, we can go down to extension settings. And then in here, we need to verify that this path, the love 2D path, is accurate. Earlier when you install love to D, We went to the path where it was installed in order to create the shortcut. That same path is what we need to include here. If you're on Windows, the path that is shown right here, which is C Program Files, love, love, dot EXE. This path is probably correct. And if you're on Mac, if you installed the love app to your applications, the path will probably be this path that's onscreen. But always be sure to double-check where you actually installed and put that same path in here. And once you have this path specify, we can go ahead and close out of these tabs and test it out. And you can just go back to your main dot lower tab at the top, or go up to File Explorer portion and double-click on main.py. So once we're here, we can run the project by using a command. On Windows, the command is Alt L, and if you're on Mac, the command is Command L. So using that command, I'm going to run Alt L. And it starts our game. It took whatever code was in this my game folder and runs it through love. The same exact thing is if we dragged and dropped the folder. However, this is a lot quicker and easier. So be sure to keep this command in the back of your mind whenever you want to run your project. At this point, you're all set up to begin coding your game. You'll start by putting code into this main.py file. And as you develop, you can add more files to your project folder. 3. Player Movement: Hello folks. In this video, I'll go through how to make a simple player character in love to d, where you can move them around the screen with the arrow keys. Once you're ready, I have a brand new project ready to go. It's just a folder called my game and inside of it as a file called main.py. That's the foundation for any love project. And we can go ahead and run this file as is. And we will see a black screen which is expected since our main.py file has no code in it yet. The resulting gain that runs as just a black window. The first thing that we should do with any game is to put in the three main functions that we use for all love projects, which is function loved dot load. Then function loved dot update with DT in the parentheses. And then function loved dot draw. And using these three functions, we'll create our player object and add some controls to it so that it can move around. A quick note before we start, the load function happens right when the game starts. The update function happens every single frame. So it will act as our game loop. And the draw function is what displays our graphics to the screen. Don't worry if you're not fully clear on all this. Once we have some code in place, it'll make a lot more sense. To start, let's create our player table, which will take place in love dot load. We will do player equals, open and close curly braces. Now keep in mind that in Lua, curly braces tend to refer to tables. So since we're doing an open and close curly brace right here, that means that player is being set to be an empty table. Next up, we'll give it some properties. So let's say player dot x equals 0 and player dot y equals 0. These will act as the position values. The game world is like a big grid where the x-axis goes left and right, and the y-axis goes up and down. Our player is going to start at position 0, 0, or the origin of the screen. Next, let's use the player object to draw something to the game window. All drawing takes place down in the love dot draw function. So in here, let's go ahead and draw a circle that will act as the player for now. We'll say loved graphics dot circle. And then in the parentheses we have four different parameters we need to provide. First is the mode. We have two options. We have Phil or line, so fill, so our circle will be filled in. Then we need the exposition, which is going to be player dx. Then we need the y position, player dot y, and then the radius of the circle. You can make this whatever you want. I'll make mine 100. So to recap, this line right here is going to draw a circle at position 0, 0. The radius of the circle is going to be 100 and it's going to be filled in. Now if we save our file and then run, we will see that we have a cutoff circle in the upper left corner. Now the reason it's cut off as because the circle is at position 0, 0, and 000 is the upper-left corner of our game window right here. Let's change the position of our player to position, let's say 400, 200. So now our x position is 400 and our y position is 200. If we save and run now, our circle is completely in the game window and now we can see it completely. More specifically, the circle moved to the right, 400 pixels over to this point right here, and then down to 100 pixels so that the center of the circle is at position four hundred, two hundred. And keep in mind that the higher your y-value is, the more down the screen you go. So since we said 200 here, that means we go down to a 100 pixels. Now that we have a player object that's being displayed on screen, we can now work on making it move. This logic is going to take place in the love dot update function because lambda update runs every single frame. So to start, let's do something simple. We'll do player dot x equals player dot x plus one. So in other words, every frame player dot x is going to increase by one. If we save and run, we will see that our circle is now moving slowly to the right. Specifically is moving one pixel every single frame. I like to call this the illusion of movement. Every frame it's updating a little bit, which makes it look like it's moving. Similarly, if we were to change this one to a three, that means now we're changing the exposition by three every frame. And if we save and run, it's still moving to the right, but it's moving faster now, specifically, it's moving three pixels every frame, so that's three times as fast. Now our task is to do this same kind of movement, but make it correspond to the arrow keys that the player presses. You can read keyboard input very easily, and we can do this using an if statement. We'll say if loved Schottky board, dot is down. And then in the parentheses here we need to specify what key we're checking for is down. And we'll start with right, or in other words, the right arrow key. Then. And we'll indent this line and put an end at the end of the if statement. So here we're asking, is the right arrow key press down. And if so, we're going to move the player to the right by three pixels. And this happens every single frame. So it's constantly checking for this. If we save and run now, the player isn't moving, but as soon as I press the right arrow key, he moves. And it's only going to do that when I have that arrow key press down. Now let's do the same thing, but for a different direction. We'll keep it easy and start with the left direction. So this time instead of increasing by three, every time, we will decrease by three. Because the smaller the x value is of the player, the more to the left of the screen it will be if we save and run now, if I hold right, he moves right. But if I hold left, player is now moving to the left. So now we have both of the horizontal directions working. Next, let's make the player be able to move down. If we copy this section again and paste it right in here, let's check for is down the down arrow key. This time we don't want to update the players exposition because we want to move vertically. Moving vertically means we have to update the players y position. So player dot y equals player dot y and we want to move down. So that means we're going to add three. If we save and run, if I hold down, the player moves down. And finally we have one more direction to do. If we copy this, we want to check for up. And if we want to move up, we just decrease by three. And with that, we should have all four directions left, right, down, and up. And it's actually more than just the four directions. If I hold down to arrow keys at once, we move at a diagonal. And this is because both the x and the y properties could be updated at the same time, which results in diagonal movement. Before we end the video, something that we can clean up is that we have plus 3 written on four different lines. This is generally bad practice because if I wanted to change the players speed or how fast he's moving, I would have to change this three on all four of these lines and that gets kind of annoying. It would make more sense if we created a new property for the player, let's say player dot speed, and we'll set it equal to three. Now I can take this and instead of writing three in all these places, I can do player dot speed. And now whenever I want to update the player speed, I just have to update this value right here. Let's say I wanted to increase it to five. Now my player is moving at five pixels per frame. So if I save and run, now, we are moving faster and it's a lot easier to manage. And one final thing I want to mention is this d t or delta time. You can use this value to make your game run and feel the same regardless of the frame rate. Just wanted to give a heads up about that. It is not at all urgent when you're just starting out. Will be building on to this a bit more. In the next video, I'll show how to draw real sprites into the game, rather than just a plain circle like this. 4. Sprites and Backgrounds: Hello folks. In this video, I'll show how to add your sprites or real artwork, as well as backgrounds to your game in love. To show this off, I'm going to be building onto the code from the player movement video. Basically we have this player table. And using its properties, we go down to the draw function and draw a circle at the player's position. And then in our update function, we have these if statements that control the player with the arrow keys. And in the end, we have a circle that we can control around and move when we press the arrow keys. Now a plane circle with a black background isn't too interesting. So we're going to use actual art assets or sprites. Instead. You can use any images you want. You can draw something up yourself, or I'll be using this simple parent image as well as this grassy background dot PNG. If you'd like to use the same images as me, you can go to the Projects and Resources tab underneath of this video and find the resources on the right. You can download parrot dot PNG and background that PNG from there. The other resources will be used in later lessons. When you have your file is ready. We'll actually want to move them to our project folder. So go ahead and copy these files. And then in your actual project folder next year, main.py, we're going to create a new folder. I'm going to call it sprites. And inside this folder we're going to paste in those two images, one for the background and one for the player. And once you have this down, you'll notice that back in Visual Studio Code we now have a sprites folder. And inside we have background up PNG and parent dot PNG or whatever names you gave them. Now the next step is we need to include these images into our code. And we'll start with the player sprite. We'll make this easy and organized by putting any property for the player table. We'll say player dot sprite equals love dot Graphics, dot-dot-dot new image. And then the perimeter here is the path to where we have this file stored and which we have stored in the sprites folder slash parrot dot PNG. And that's our Player sprite. And now that we have this image loaded into player dots sprite, we can use it down in the draw function. So instead of drawing a circle, we'll get rid of this. And instead we'll say love dot Graphics dot draw. And the first parameter is what we want to drop, which is player dot sprite. Next is the position dot x and player dot y. And with this in place, if we save and run it, we'll see that our player is now represented by our sprite. In my case, it is the parrot. Next up we'll get the background drawn in same deal. We need to load in that image into a variable. So we're going to put in background equals loved at graphics, that new image. And the path is sprites slash background, PNG. So now that we have it stored into background, we can use this once again down in the draw function. I'm going to put in love dot Graphics, dot draw. We went to draw background and we're going to draw it at position 0. 0. Now the position that we provide for any of these draw function calls actually represents the upper left corner of the image that we're drawing. So since our background is a big square or rectangle, putting its position right at 000, we'll align it perfectly with our game window, since 00 is also the upper left corner of the window. If we save and run, we'll see that our grass background is now in place. But you'll notice that the players suddenly disappeared. Here's the problem. The player is still there and is still being drawn, but the background is being drawn over top of it. So it's just not visible to us anymore. For drawing sprites, the order that you draw them in matters. So in our case, we drew the player sprite, but then we do the background after it, which results in the background being placed on top. If you want to fix this, we just need to switch this order around. If we draw the background first, that means that the background will be drawn and then the player sprite will be drawn over top of it. So in the end, when we save and run now, we will see our Player sprite drawn over top of our grassy background. And that about covers the basics of drawing sprites. From here, I'd like to change this bird spray into more of a human with walking animations, which is pretty easy when we use some open source software. We'll talk about this in the next video. 5. Animations: Hello folks. In this video, I'll show how to add animations to your player character, where they face and walk in whatever direction that you're moving. I'll be utilizing these sprites which were created and provided by width the love on opening game art.org. You can download this file player sheet dot PNG from the projects and resources tab down below. Or you're free to use any other sprite sheet that you'd like to use. Taking a quick look at this image, you'll see that there are four rows, each representing a different direction. Our goal is to use each individual frame from a particular row in order to create the animation. When each frame has played in quick succession, it'll give the illusion that the player is walking. Once you have your project ready, go ahead and create a sprites folder next to your main.py if you don't already have one. And inside, go ahead and paste in this player sheet dot PNG. Once that's done back in Visual Studio Code, you should see that in your sprites folder you have a player she dot PNG, which means everything's ready to go. We just need to include that file into our code, which we can do that the same as any other sprite. I'll make it a property of the player object, and I'll call it player sprite sheet equals loved that graphics, that new image. And then we need the path which is the sprites folder. And the name of the file is player dash sheet dot PNG. Now that this is imported, will want to work on turning this into an animation. This will be accomplished using some open source software. In particular, we'll be using this product here called Animate. Although this repo is a few years old now, It's still very reliable and works great for implementing animations in love to D, There were a few ways to get this code included into your project. If you have Git installed, you could go over to this code drop-down, copy this HTTPS, and then do a git clone. Or the other way to do this is to download the zip. And once this zip is downloaded, you can go ahead and extract it. And then in here we will find an animate dot lou a file. You're going to want to copy this. And back in our project folder, we're going to create a new folder, I'll call it libraries. And in this folder we're going to paste in that animate dot Lua. Once you have that, paste it in and you can see it over here, will want to go ahead and import this into our code. I'm going to do this right at the top of love dot load. And we're going to say animate equals require libraries, which is that folder we just created. And then the name of the file is animate. Now, all of that animate that little code is stored in this global variable called animate. At this point, we can start creating our animations. The first step is to create a grid which helps the library to split your spreadsheet into its individual images. You can check animates GitHub page for more details about all of this stuff. So let's start by creating a grid for the player object. I'm going to call it player dot grid equals animate dot new grid. And in these parentheses here, there are several parameters we need to define versus the width and height of each individual frame. And in our case, each frame is 12 pixels wide and 18 pixels tall. If you look closely at the spreadsheet we're using, you'll see that each individual frame has a bit of a gap around it. But when we include that gap, each image is 12 by 18. Then after redefine that dimension, we need to give the width and height of the full spreadsheet, which we can get very easily. We'll say player dot spreadsheet. And then we can say colon, get width. So this line here is going to get the width of our sprite sheet. And similarly, we want to get the height for the next parameter, player dots, sprite sheet, call and get height. So that is the entire thing we need to define our grid. We have the width and height of our individual frames and the width and height of the full sprite sheet. And in the end, that gives us our grid. Now using this grid, our code will know how to split our spreadsheet into the individual images. And with that, we can create our animations. So we're going to store all these animations into a new table. Actually, I'm going to call it player dot animations equals new empty table. And let's start with this one simple animation. We'll do player dot animations dot down. This will be the first animation. Then we'll implement the down direction. And to create an animation, we do animate dot new animation. And in these parentheses we need to define what frames from that sprite sheet we want to include. And we do that using the grid. So we'll say player that grid. And then in these parentheses, we need to define what rows and columns we want to include. The first parameter here is the columns we want to include, which is columns one through four. Because we have four frames going from left to right. So we say one through four in single quotes just like this. Then we're gonna put a comma. And then after this, we want to define what row we want this to come from, which in our case, the down direction comes from row one. So we'll just put one here. And then after we define our player grid information, we put comma. The next parameter is the time in seconds between each frame. So again, our frames are going to be playing one after another in quick succession, but we needed to find how quickly we want them to go. I'm gonna say something like 0.2 and you can adjust this smaller or bigger. This means that the frame is going to change two seconds for our animation, which is pretty quick, but you'll see that it looks really natural when we play the animation back. So this is everything we need to define our animation and it's being stored in this player dot animations dot down. So I'm going to actually copy this and now we need to update this animation and draw the animation. So in update after all of this code, I'm going to put in play that animation is dot down colon update. And this update requires us to pass in DT. And again, d t comes from right here. In love to update, we're simply passing this perimeter down into our animation update. And then after that is updated, we can go down here and I'm gonna get rid of our circle draw. Or you can also get rid of any other drawing that you're doing besides the background. And I'm going to do player dot animations, dot down colon draw. And the first parameter here is the spreadsheet that we use to draw this animation, which is player dot sprite sheet. Then after this is the position that we want to draw this animation, which is player dot x and player dot y. And that should do it. We should see the animation playing. So let's save this file and start. And one problem, but you'll notice immediately is that this animation is way too small since I went with some retro graphics, this sprite is actually only 12 pixels by 800 pixels, which is very small, but we're able to scale it up a little bit. So let's go ahead and in this animation is draw. There are some additional parameters very similar to the regular loved our graphics to draw function. The next parameter here is the optional rotation field. We don't want to rotate the image. So let's do nil, meaning don't change the rotation. And then after nil as our scale X factor. So we can put in something like 10. And that means the scale of our animation is going to be increased by ten times. And putting in a value for scale x means that scale y will also adopt that value since we didn't specify anything for it. So with this, we should expect our sprite to be 10 times bigger, or I should say our animation. So let's go ahead and start. And there it is. It is much bigger, but a notable problem is that it is blurry. We can prevent our scaling from blurring the images if we go up to the top. And we'll do this right after our animate import. We'll do love die graphics dot set default filter. And the values here are nearest, nearest. So with this line in place, it'll make it so that when we scale up our graphics, it doesn't do any blurring. It's just simply takes the pixels and scales them up. And now when I start, we see our animation working and it looks pretty good. And since it's tied to the player dot x and y values, we can move around normally, but now our next task is to get the other directions working we have down, but none of the other ones. So let's go ahead and get those implemented. We'll do them in a very similar way that we did down. I'm actually going to copy this entire line right here. And we're going to do the next one. We'll say left. Now the left direction is on the second row. I'm going to change this one to row two. Next up we have right now, right is on row three. And then finally, we have up and up is on row four. Now all of these animations are very similar. They just take place on different rows. Now comes the challenge of changing between the animations. Because right now our animation is being drawn and updated by manually picking out player dot animations dot down for both here and here. When in reality, we don't know what to look for animations we want to use. We can keep track of this with a new property. I'm going to call it player.com. And we'll set it equal to some animation, let's say player dot animations dot left. So now our player, that property contains player to animations that left. So we can use this to track our players animation. So instead of updating manually, animations died down. We're instead, according to update player dot enum. And same with our draw. We're just going to do player dot A&M draw. This way, whatever animation we have assigned to this value, that's the one we're going to see. So right now we have player to animations that left assigned to it. So if we save and run, we see that the left facing direction is now the animation that we see here. At this point, we just want to change the players animation to match whatever direction they are moving. This can be done by adding to our movement controls and the update function. For example, here we are holding down the right arrow key. That means we probably want to change the animation to be player dot, animations dot, right? So it right in here. I can go ahead and do that. I'll say player dot nm equals player animations dot, right? And similarly, we can do this exact same thing in all four of these directions. So this one is left, this next one is down. And finally this last one is up. So with that in place, if I save and run, whenever I changed directions, the players animation gets updated to match that direction. It works pretty well. The only remaining problem here is that the player continues to walk in place even after they stop. And ideally they're animation would also stop and change to a standing still position. Essentially, we want to change the player's image to this frame, the standing one, when no arrow keys are pressed down. You'll notice that these standing frame is the second image and each of these rows. So when no arrow keys are pressed, will force the animation to stick with this second frame. This again will happen in our update section, we're going to need to check to see if no arrow keys were pressed that frame. So we'll track this with a very simple local variable. At the start of the frame will create a local is moving. And we'll set this to false. Then we want to change this is moving to true. If any of the arrow keys were pressed down this frame. And we can do this again, right in this is down IF statement, we can just simply say is moving equals true. Because if the right arrow key is pressed down, that means we are moving. So we need to change this value. And I'm just going to copy this line and put it within all four of these if statements for each of the four directions. So at the end of our update method, we will know that is moving is going to be either false if nope arrow keys were pressed down or true if any of them were press it out. And if none of them are pressed down, and let's see. If is moving is equal to false. Then at this point in this if statement, we want to change the players animation to be that second frame where they're just standing still. And this is done with player.com. And there's a colon go to frame function. And the frame we want to go to is frame number two, that's standing still frame. If we save and run now, the player is standing still. As soon as I move, he starts walking again in all four directions. And when I stop, they change back to a standing still. And this works for all four directions. 6. Level Design and Tiled: Hello folks. In this video I'll be showing the basics of using tiled, a fantastic level editor that is a must have for game frameworks like love 2D, which does not have any kind of built-in editor, will go through the process of adding a style sheet, designing a map, and an importing our level into a love 2D game. First, you'll want to have a tile set to use for this. This is just a large image with a bunch of individual pieces that we'll be using to design our level. You can download this tile set dot PNG from the projects and resources tab down below. Once you have it ready, I like to keep my stuff organized. So in my game project folder, I'm going to create a new folder and I'm going to call it maps. And then right in this maps folder, I'm going to paste in that tile set dot PNG image. Next up you'll need to download tiled. Note that this is a name your own price tool. So although you can download it for free if you do find it useful, I highly recommend paying some amount of money to support the developer. Once you have tiled installed, go ahead and start it. And we can create a new map by going up to File new, new map. And in this window, sorry, it's a little bit smaller. This text does not scale well here, but the top portions up here can all stay at their default values that's orthogonal CSV and write down. Next is the map size. We can choose how many tiles wide and high our map will be. I think this default, 30 by 30 is okay here. And then finally, we need to specify our tile size, which is the size of each individual tile. This is dependent on what tile set you're using. But with mine, each tile is 64 pixels wide and 64 pixels tall. And then we'll click Save As you're going to want to navigate to your game project folder. And I'm going to save this in the maps folder. And Alice simply call this Test map and click Save. Once that's saved, the tiled editor should pop up, which is where we'll be designing our level. First, we need to import our tile set though. This happens down in this bottom right corner with this new tile set button. First, we need to give it a name again, sorry, this is small. I'll name this test tiles and then make sure you have embed in map turned on. Then we need a toot, our source, which if we browse, we're going to navigate back to our maps folder and find our tiles, that image. Then again specify our tile width and height, which in our case is 64 by 64, and then margin and spacing. You can adjust these values if there's any gaps between or around the tiles. But in my case, all of the tiles are right next to each other with no gaps in between. So the spacing is going to be 0 and there's no margin around the border of the tile set. So the margin is going to be 0 as well. And what's the other configured? Go ahead and click, Okay. And in the bottom right you should see your tile set pop up. Now at this point you're able to click on any of these individual tiles and use them to draw in parts of your map. And you can use this to design your level. I'm actually going to start by putting in a baseline of this grass image. And I'm going to use this paint fill tool to put grass in all around. Then from here I can choose individual tiles and use the stamp tool to draw in like my individual paths for the rest of the level. One thing you might notice while designing is that if you tried to make, say, one of these trees and put it right here, it kind of deletes the grass underneath of it. So and this is because the surrounding portions of the tile is transparent. So it replaces the grass around it with that same transparency. We can get around this by making a new layer. Right now we're working off of this tile layer 1. Well, we can create a new tile layer and I'll call it trees. Now if I go back to this tail air one and replace this tile with crass. As soon as I go back to the trees tile air. Now anytime that I put will be put on this new layer. So the stuff on tile, everyone isn't going to get replaced. So this fixes that issue. And while we're at it, I might as well replace this name with something like ground. And then from here it's just a matter of designing your level. So go ahead and go through and design your level however you want. I am keeping this very simple for now, but whenever you're done with your map, you can go ahead and save the project and then go to File Export As so now we're going to export our project. So then navigate to your game project folder. And again, I'm going to put this export aversion into our maps folder. And you'll see at the bottom that we're saving it as a Lua file. I'm going to call it test map. So this is very convenient since love today uses Lua that makes the process of converting it over pretty simple. So go ahead and save. And our map is now export it as a Lua file. Now to get this map into our love project will need to utilize some open source software. You can use this URL to reach the GitHub page for the library simple tiled implementation. This library will read that exploited map and help withdrawing all of those tiles in game. So to get this code, you can either clone this repo if you know how to do that, or if you don't know how to do that, you can go to code and we'll just download the zip file. Then once it's downloaded, you're going to want to extract the zip file and then navigate into these folders. And what we really want is this STI folder. Sti stands for simple tiled implementation. Of course. Now going to copy this folder and then go back to our game project folder. I like to keep all of my open source code into a library's folder, but you can organize it however you want. I'm just going to paste in that STI folder. And once you have that STI folder ready, we can include it into our code with love dot load. But at the top of love that load I'm going to put in STI equals require. And then in these single quotes, I'm going to put the path to that folder, which was libraries slash STI. And that import all of the STI code into this STI variable. And then after this, we can create our map or load it into the game by storing it in a variable. I'll call it game map equals STI, parentheses. And in these parentheses we need to provide the path in single quotes to our exported map file, which that was in the Maps folder, slash test IMAP dot Lua. Since our map was exported as a Lua file. And now that this map is loaded into game map, all that's left to do is to draw it. So down here and draw function, we're going to get rid of any other background that we're drawing. And instead I'm going to do game map, colon, draw. And that's it. One very small note is if you're using the sample project, I'm going to change this scale of the player down to six as opposed to 10, just so it matches the tiles a little bit better. But whenever you're ready, go ahead and save the project and run. And it worked. We have our tiles in place and we can play the game as normal. That covers the basics of using tiled and importing maps into your love 2D projects. A notable problem though is that we're stuck in this upper left corner of our game level. So there's no way we can actually see the rest of it. In the next video, we'll add a camera that follows the player around that will let us explore the entire space. 7. Camera: Hello folks. In this video, I'll show how to add a camera to your love 2D games so that it'll follow the player around and you can explore more of your levels. All you need in order to start as to some project where you have something that you want the camera to follow. In my case, I have this player object and player dot x and player dot y represents the player's position. If I run the game as is, this is what it looks like currently. But of course there's no camera, so I can't really explore the whole space. Same with many tasks. We can add a camera very easily by utilizing some open-source software. Go to this URL to reach the GitHub page for hump, which stands for help or utilities for massive progression. Hump is a collection of several different tools, including this camera.capture file. Go ahead and clone this repo. Or if you're not sure how to do that, you can go ahead and go up to code and then download this as a Zip. Then you'll just want to extract this zip file. And then inside the folder we'll just find this camera.capture file. Go ahead and copy that. And then back in our game project folder, inside the library's folder, I'm going to go ahead and paste in this camera dot lou a file. If you currently don't have a library's folder, you can go ahead and create one just right next to your main dot Lua and call it libraries. Once that's added in, go back to your code and we're going to get this camera code imported up in love dot load. I'm simply going to do camera equals require. And inside the single quotes, I'll do the path to the camera.capture file, which is libraries slash camera. So now the camera.capture file is loaded into this camera variable, and we can use this to create an actual camera object. I'll call this cam equals camera. So calling this as a function essentially generates a camera object and is being stored inside of CAM. So whenever we want to work with the camera, will be calling this cam variable. Now that this has created, we can change our draw sections so that everything is viewed through the lens of this camera. We do this by, at the start of the jaw section. We'll do cam colon attach, and then we'll indent everything else. And then after everything is drawn, will do cam colon detach. Like that, can attach marks the point where we start drawing things from the camera's perspective. And CAM detach is the point where we stopped looking through the camera. So in this case, everything is being drawn from the camera's perspective. Now if you're drawing a tiled map using simple tile implementation like I'm doing right here. We actually can't use this game map colon drauf notation anymore. This unfortunately conflicts a little bit with a camera. So what we need to do is actually draw each layer of our tile map individually. If you take a quick look at my tiled map, I have two layers. I have ground and have trees. So we need to draw each of these layers individually. And I can do that by getting rid of this game map colon jaw. And instead I'm going to do game map colon drawing layer. And inside the parentheses we need to specify the layer we want to draw will draw the ground layer first. So we get that with a game map, dot layers. And then in square brackets we need to specify the string name of our layer, which is ground. And same deal, I'm going to copy this and we're gonna do the same thing, but for trees. So at this point we have all of our game map layers being drawn, as well as the player being drawn inside the perspective of the camera. If we were to save and run now, the game probably won't look any different. And that's because our camera is motionless at the moment. We need to change it so that it's always following. The player will do this back in our code in the update sections. So in loved update, probably at the bottom of love dot update. After all of this, I'm just going to put in CAM colon. Look at, we'll put it at position player dot x and player dot y. So every frame is going to move the cameras position to match wherever the player is located. If we save and run now, it's working. The camera is now following the player. He may notice a bit of an offset issue though. The player is a bit off center, he's a bit down and to the right too much. And this is because the camera is currently following player dot x and player dot y, which at the moment is representing the upper left corner of our players image. By default, all animations and all sprites will draw at its upper left point. And in this case, we actually would prefer to be drawing from the center of the image so that our camera is centered with everything. So back in our code, we'll go down to where we draw the player which is right here. We're drawing our animation. And we need to update those offset variables. So here we have our rotation, then we have our scale x. And then after scale x is the scale y, which will put as nil. But after scale y is 0 x and 0 y, which is what we want to specify. For OX, we want half the width of the sprite, which is 6, since the width is 12. Then for the offset, why we want half of the height, the height is 18, so we'll put in nine. So with that in place, if we save and run now, we'll see that our camera is now centered and the player is directly in the center of our camera shot. The last thing that you can address, and this is completely optional, but you can stop the camera from showing this black off-screen background that goes beyond where our map is, all we have to do is stop the camera from moving when it reaches too far and near the border. Let's start by addressing the left border first. So in our update function, right after we do our cam look at, we're going to do an if statement where we check the width and height of the screen. So first let's get the width of the screen and we'll store it in a local W variable. And we get the width by doing loved died graphics and dad get width, and this will get the width of our game window. Then we'll do local h equals loved Ag graphics dot getHeight. And this will get the height of our game window. Now when we need to do is check the camera's position and compare it with this width. So we're going to do an if statement. We'll say if cam dot x or the x position of our camera is less than half the width, meaning that we are just at the border, but we don't wanna go any farther. Then. We just want to change cam dot EXE to half the width. Half the width puts the camera just far enough away from the edge of our screen so that it doesn't show that black background. And if we save and run now, if I go too far to the left, we'll see that the cameras stops as soon as we reach that border. It's not showing that black background anywhere on the left side of the screen. Let's do the same thing for the upper border. We do this in a very similar way. I'm just going to copy this. And instead of checking Campbell x, we're going to be checking kim dot y in both of these spots and also checking h. We're checking the height of our game window this time. If we save and run now, we'll see that we can no longer go pass this upper border. It does not show the black outline. Then for the right and bottom borders at a little bit trickier because we need to get the width and height of our background. So here after all of this stuff, I'm going to get a, another local variable. I'm going to call it local map W, as in the width in pixels of our game map. This is done with game map dot width times nmap dot tile width. And what this represents is the number of tiles wide. Our K-map is, this represents how many pixels wide a tile in our K-map is. As you mentioned, that this part is only possible if you are using a tiled map. If you're using a regular background, then this would just be the backgrounds with not any of this calculation right here. We'll do the same thing for the map height. Map h equals game map dot height times game map, dad, tidal height. So now we have the width and height of our map in pixels. And I'll go ahead and show you the final code. If we have mapped wn map height, we use this to calculate where cam and cam, why should go whenever they reach the right and bottom borders? For the right border, we put it equal to the width of our map, which is this variable right here, minus half of our game windows width. And that puts us right at the border where it doesn't show anything off screen. Same idea with the cam. Why we get the height of our map. So all the way at the bottom, we subtract half of the height of our game window, which puts the camera right at the border where it doesn't show any of that black background. If we save and run now, if I walked down to the bottom right, it stops at the right border, and it also stops at the bottom border. So now at this point, our camera cannot go off screen at all. One last thing I want to demonstrate for the camera is if you wanted to have a HUD or something that just appears in front of the camera. You do this by drawing something outside of the can detach. So for example, let's just test this out with a love die graphics dot print. And I'll print hello. And this will be printed at position 10. 10. Although it's very small, you can kind of see that little hello. And the upper left corner, and it stays there no matter where the camera goes because it's being drawn outside of the cameras perspective, it acts like a HUD. In the next lesson, we'll discuss the basics of physics, which is something that we need to be familiar with before we can implement actual collisions in this game. 8. Physics: Hello folks. In this video I'm going to cover the basics of using physics within love 2D and how we can quickly create colliders that interact with each other and optionally respond to gravity. You don't need anything to get started with this any love 2D project, we'll do even a brand new one if you're following along with the previous lessons, this video provides some extra information we need to cover before continuing on with that. Now for physics, there's a module for this built directly into love, and it is very powerful. Unfortunately, that means it's also complicated. But there are open source libraries out there that make working with physics a lot easier. The most popular is wind field. When field provides a bunch of really easy to use tools for us to use that make getting started a lot quicker and your code will be easier to write. I personally uses library for all of my games, even though it has been archived recently, it is still fully reliable with the latest versions of love. And it really does make a huge difference. To get this code included in your project, you can either clone the repo if you know how to do that, or you can go ahead and go to code and download the zip. Then you'll just want to extract the folder. And then inside we want to find this wind field folder that's right next to the Read Me. So go ahead and copy this and then navigate to your game project folder. In my case, I'm using a brand new projects for this demonstration. It's just a main.py file. I'm going to create a new folder. I'm going to call it libraries. Since I always put my open source code in a library's folder. I'll go in here and then I'll paste in that wind field folder. Now go ahead and open up your main dot Lua. And for this demonstration I'm starting with an empty file. So to start, I always put in the load update and draw functions like I did here. And the first thing we'll do is import that wind field folder that we just copied into our libraries. So we'll do that with WWF equals require. And then in these quotation marks, we'll do the path to that folder which was libraries slash wind field. Keep in mind that we are importing a whole wind field folder and it's going to be put into this WWF variable. And that's imported, we can use it to start working with physics. The first step to working with loves physics is to create a world. Someone were to say World equals WWF dot new world. A world is simply a space where physics objects exist and we use the world to actually create our objects. Like for instance, let's create a player object. Player equals world colon. And we'll make it a rectangle. We'll say new rectangle collider. Then these parentheses except a few parameters. The first is the position that we want our player to start at. So I'll put them at position 354 x, and then 100 for Y. Then we want the width and height of our rectangle. I'll make it with AT and height 80. So now our player is a rectangle collider and it's being stored in this player variable. And when I say collider, I'm referring to a physics object that exists in our world. Part of what when field does is it makes colliders so easy to work with. Normally with the standard loved physics library, you need to define a body of fixture and a shape and then keep track of everything separately. A collider from wind field though, is a combination of all three in one place, making it so much simpler. Before we save and run the game, we should add two quick things. First, we want to add world colon update. So this makes sure the world is updated and all the physics gets updated. Then in draw, I'm going to put in world colon draw. Now what world colon draw does is it draws the shapes of all of the colliders in our world. So I'm gonna go ahead and save and run. And there it is, this rectangle object right here is our player collider. It's not doing anything though. One thing that we could do is give this world some gravity. This new world function right here actually accepts a few optional parameters, the first two of which is the gravity definition. So if I do 0, Let's try 100. This would be gravity going downwards. This is the x value for what our gravity is, and this is the y-value. So since we just have a positive value for y, positive means going downwards. So all of our physics objects to be affected by a downwards gravity. So if we save now and run, we will see that our player collider is now falling downwards. It was falling pretty slowly though. So what we could do is bump this 100 up to 500. This makes the gravity more intense. Therefore, our player falls at a faster rate. Not all objects need to be affected by gravity though. Let's demonstrate this by creating a platform for our player to land on. We'll call it ground, and we'll do world colon, new rectangle clutter. And its position. I'll put it at one hundred. Four hundred is its position. And then the width will be 600 and the height will be 100. So if we were to save and run now, we see our ground, but it also follows with gravity. In order to make the ground less prone to gravity or ignore gravity altogether, we need to change its type. We can do ground colon set type to static. So if we save and run now, our ground is static, meaning it is not affected by gravity and the player lands on it. And just now I mentioned that there are forces that you can apply to colliders. Let's make our player jump by using an impulse. So down after all of this stuff, I'm going to put in a function loved our key pressed. And in here we're going to check to see if key is equal to AP, meaning we press the up arrow key, then we will apply our impulse. We're going to say player colon apply linear impulse. And the impulse we will apply is 0. And let's try negative 5000. Now, a linear impulse is just a quick force pushing on the collider. In this case, we applied a negative y value being applied to the player. Since this negative 5000 is in the y position, that's going to push the player upwards because negative goes up. If we save and run. When I press the up arrow key, the player does a little hop because we are applying that linear impulse. There are lots of other actions you can apply to a collider. Let's make the player move left and right by using a force this time as opposed to an impulse. So we'll do this in our update function, and then we'll tie this to the arrow keys will say, if loved, that keyboard dot is down and we'll say left. So when the left arrow key is pressed, then we will apply a force, will say player colon apply force. And we'll do negative 5000 in the x position this time. So it's going to move us to the left. And then we'll say else, if loved our keyboard that is down for right. And in this case, we will do the same thing. Apply force, but we'll do positive 5000, which will move us to the right. And that should be enough if we save and run, where if I press left, I start moving left, and if I press right, I start moving right, kind of slide along the ground. The thing to note about forces though, is that the keep stacking and growing more intense. Why the player accelerate so much when moving left and right. If you wanted to limit this, you could only apply a force at the player is not already moving at max speed. We can close out of this. So we're going to apply this force here only if the player needs it to get to the max speed. Otherwise we don't want to apply it, otherwise there'll be going too fast. So first to get the players actual speed as it is in this frame, we can do local PX, PY equals player colon, get linear velocity. And this function here is going to grab the players velocity and put its x value in p x and its y value in PY. So now we can check the P x value here to determine if we want to actually apply this force. So here on this line I'm going to say, and px is greater than negative 300. So we'll make it so that negative 300 is the max speed that we can go. So we're only going to apply the force if we are below that threshold. Same thing for the right. We will say, and P x is less than positive 300. So doing negative 300 for the left direction, moving left and positive for the right direction. Also, to make things a bit more snappy, I'm gonna change this 5000 here to 8000. That will make us accelerate a little bit faster. So if I save and run now, if I hold left, I've moved left, and if I hold right, I move right. But you'll notice that I don't end up going too fast like I was doing before. Overall though, this game that we created just now could be the start of a full platforming project. And we were able to set it up pretty quickly. The GitHub page for wind field provides tons of helpful information about working with physics. I highly recommend reading through it. For the next video, I'll be taking the concepts discussed here and applying them to the top-down styled game from the previous videos. 9. Collisions: Hello folks. In this video I'll be showing how to add walls and collisions to your love 2D game so that your character can't just walk through walls. Additionally, I'll be showing how to generate these walls in game from your tile to map. To start, we'll need to utilize when field, which I talked about in a previous video. These first few steps will be the same from that video. And first you're gonna go to the GitHub page right here and either clone it into your project or you can download it as a Zip. Then of course you'll want to extract this zip file. And then we're going to go in here and grab this wind field folder. It's right next to this README file. I'm going to copy this. And back in our game project folder, I'm going to go to our library's folder and paste this wind field folder right in here. Once that folder is ready, we'll need to include it into our code. So at the top I'm going to add in WWF equals require. And then the path is libraries slash wind field. Keep in mind that this loads the whole wind field folder into this WWF variable. Now we can use this variable to create our world, will say World equals WWF and that new world. And then for the gravity parameters, this is a top-down RPG style games. So we're going to have no gravity 0 comma 0. We also need to update the world, so down and our update function. And we're going to put this after our player movement code. So probably right here. And we're going to say World colon update. And then we need to pass in DT just like that. And then finally down and draw temporarily, we're going to draw the world. So we're going to say World colon draw. This will allow us to see the colliders that we create. But in the end, we'll probably want to remove this since we don't want to actually see all of those gliders and the final product. Also know that we're drawing it inside of our camera so that it appears within the camera's lens. Now that that's in place, we need to give our player a collider, or essentially a physics object that allows it to collide with walls. So back up at the top where we define our player. I'm also going to give it a collider. So player dot collider equals world colon, and then we're gonna make it a BSG rectangle. So new BSG rectangle collider. Now, a BSG rectangle is a lot like a regular rectangle, but its corners are caved in a bit. It's more like an octagon shape, which in my experience works a little bit better for player characters. Now for the parameters, the first is the x and y positions. So for x I'll do 400, and for y I'll do 250. Then we need the size, the width and height of this BSG rectangle with I'll do 40 and height I'll do 80. And then there's one more parameter that determines how far caved in are these corners. To help demonstrate this, I'm going to make it 14 to start. And then one more thing I'm going to do with this Collider isn't going to make it unable to rotate something as a player dot collider colon set fixed rotation to true. So this prevents the collider from rotating around. So now that this is in place, I'm going to save and run. And we can see our clutter is right here. And you can see what I mean by the corners are caved in, so it's like a regular rectangle, but these corners are slanted, so it's more of an oval shape, more technically it's an octagon. But you'll notice that the collider does not move currently, it just stays right in place. What we actually want now is for the player's position to always match this colliders position here. To help with this, we're going to, after we update the world, we're going to also set player dot x equal to player dot collider, colon getX. And same with white player dot y equals player dot collider colon get y. So now the player's position will always line up with the collider. We save and run now, we are evenly matched, although the size probably needs to be adjusted a little bit. So let's do that first. I'm going to scroll back up to where we created the collider for the player. I'm going to increase the width, let's say to 50. And we'll make this 100. And I can also change this 14 so it's less concave. I'll change it to something like ten. So let's try that out. That's a lot better. It's a lot closer to match the players parameters or the player size. You'll notice though now that we can't move anymore. And this is because we're always locking the player's position to the colliders position. And since the Collider isn't moving, we also can't move. So to address this, we're going to rework all the movement code that we did for the player, but change it so that it is addressing the collider instead. So all of this code is happening in update for these if statements that are checking for the keyboard input and how we're moving normally is changing the exposition. But instead what we're going to do is change the velocity of the collider. So to help with this, I'm going to create some new local variables. I'll say local vx and set that to 0 and local VY and set that to 0. So these are going to represent the velocity in the x-direction and the y-direction of our collider. Now instead of updating Plato dot x, let's instead set vx equal to player speed. And same with all these other ones, will change vx. Equals player dot speed. But since we're moving left, we want this to be negative. So we're multiplying played out speed times negative 1. And then down here for up and down, we're going to update VY. Vy equals playback speed for down, and then v y equals player that speed. But since we're moving up, we need to multiply this by negative one. And then after all that's done, our VX and VY values are updated to match whatever our keyboard input was. So we can simply say player dot collider, colon set linear velocity. And this linear velocity function takes in two parameters, one for the x velocity and one for the y velocity. So we can pass in v x for the x and then v y for the y. So whatever keyboard input we put in, it's going to line up with these two parameters and update the linear velocity of our collider. So if we save and try this out now, if I hold down some directions, we can see that I'm kind of moving, but I'm moving very slowly. And this is because we're updating these values to player dot speed. And if we scroll back up, we'll probably find that player that speed, yes, player that speed is very low. It's only five. We need something closer to 300. That's more appropriate speed. So if we save and run now, when I move around, the player moves more specifically the collider moves. And it's matching whatever player to x and player that y is. So our player character moves with it. And with this change, you shouldn't notice any difference with how the player feels to control. Now the next step is to put in some walls for the player to collide with. Since right now I can just walk through these trees and the buildings and stuff. Let's put in a very simple collider to demonstrate. So at the bottom of our loved dot load function, I'm going to put in a new wall collider. I'll call it local wall equals world colon, new rectangle collider. Whoops, new rectangle collider, not BSG rectangle. So with this new rectangle collider, we need to give it a position outputted at position one hundred, two hundred. And then for a width, I don't know, I'll do a width of 120 and then a height of 300. So with that in place, we should see that if we save and run there it is this big rectangle right here is our wall. But you'll notice that when we walk into it, the wall just kinda falls over. I hope you are able to see that it's kind of faded, but the wall does fall over because both of our colliders are dynamic. Instead, we need our wall wall colon set type to static. Static means that it's not impacted by collisions and it won't move away. So if we save and run now, when I run into the wall, the wall stays right in place and the character also stopped when we walk into it. By the way, looking closer, it looks like the border of our collider doesn't exactly match the player sprite. If you wanted to, you can increase the width to be more precise. But in my opinion, being close enough is good enough. Anyway, we have our wall working and it stops the player. What we want to do now is make it so we can generate these walls from tiled. And keep in mind that this requires you to have simple tiled implementation set up for your project. So go ahead and take a look at this video in the corner to get up to speed. So entailed for our map, we're going to start by going here and creating a new object layer. And we're going to call it walls. Now that this walls layer is created and we have it selected, we can use these tools up here for objects. So I'm going to click on this rectangle tool, and I'm going to draw in some objects over top of places where I want there to be a wall. So I drew two objects. And if you use this purple selector up here, you can edit these, you can move them around and change their sizes. But I have two objects drawn in. One another tip if it's not snapping to the grid like it is for me, you can go up to View snapping and then choose your option here for snapping if you need to make it more precise or make it snap to the grid. So with those two objects drawn in, I'm going to save the map. But then also go up to file export as. And then make sure you're exporting it to the correct place. In my case, it's in my game folder, maps, and then it's this test map.get to a file. I'm going to save over top of that. And that makes our map exported. Anytime you make any changes to your map, you need to make sure you save and export, otherwise, those changes will not show up in the game. Now we need to create while colliders that matches those objects that we drew in for tiled. So we're gonna do a few things for this. The first thing I'm gonna do is create a WALS table. So this is going to contain every wall object that we create. Next we need an if statement. We're going to say if game map dot layers with square brackets and say walls. So what this if statement is doing is it's checking to verify that we have a layer called Walls. Otherwise we won't do anything else. So if we have a game map layer called Walls, then we are going to iterate through all the objects in that layer. And we do that with a for loop. We'll say for i comma in pairs. And then in the parentheses here we specify game map that layers. Same thing as before, walls. But then we say dot objects. So this gets us every object in the walls layer. And then we say do and end. Now inside this for-loop is where we're actually going to be generating our wall objects. And we can actually take this code right here and utilize it. So we're going to paste this right in here and format it a little bit. Now. Right now we're hard-coding these like one hundred and two hundred stuff as parameters. But instead what we want to do is take the object right here from tiled and use those values for these. So I'm going to say obj dot x and obj dot y for the x and y value. And same thing with width and height. Width and obs dot height. And save that. So now whatever wall we create, it's taking those values directly from the object that we drew in tiled. And one last thing we want to insert This wall object that we just created into our walls table. So I'm going to say table, insert walls, wall, which puts our wall object into walls. This is helps us keep track of everything that we create. Just to help clarify why this works, if I select one of these objects that we created, we can see that it has an x, y, width and height property, which we can see over here on the left. And those are the exact properties that we're accessing when we're creating this wall. Let's go ahead and save and run. And we can kinda see the white outline. But when I walk into these houses here where I drew those objects, we can no longer walk through it. And this is same with this one up here. Wherever we drew an object in tiled, there is now a law sitting there and that we can't walk through anymore. And once you draw in the rest of the objects in tiled, we don't have to draw the world anymore because everything is accurate to the level itself. So if we remove this, we will no longer see the colliders, which is exactly what we want. If we save and run now, everything looks back to normal, but the player has a hit box and each of these walls can no longer be walk-through. So everything seems to be in place. And that about covers everything. We now have a very solid foundation for an RPG type of game. 10. Wrapping Up: That about wraps up the main content of this class. Like all Skillshare classes, there is the option to submit a class project. I really want anyone taking this class to be as creative as possible. So the class project is simply to make anything you like in love. This can include adding something new to the game that we created in the videos or starting something new. Whatever you do though, I highly encourage you to keep things simple at first and then build up to more complicated stuff. My first game with love was a very basic Breakout clone. And each game after that, built on the complexity, this is a great way to learn and practice, and I always encourage my students to do the same. Working on your own can be challenging regardless though. So there's a few tips I'd like to share. First is to utilize the love 2D wiki. This site outlines everything you could possibly need about love 2D and all of its features. Every function and capability is outlined in detail here. And finding it is pretty easy. For example, if I forgot the parameters for love demographics dot draw, I can just Google online for love 2D, loved our graphics I draw. And the page from the wiki will pop right up. I'm constantly checking stuff on this site whenever I'm working on my own games. Then if you have any specific questions on anything, be sure to check out the love 2D forums. The community here is very active and people are always willing to help out if you're stuck on something. Another helpful thing is to find some open source love projects online and look into how they coded up certain features to get you started. I have a great resource on my GitHub page, which is a full open source love 2D game. You can download it and run it locally to play. And then all of the source code is available for you to look through, learn from, and directly use for your own games. So as you're working on something with love, definitely go down to the projects and resources tab and click the Create Project button, upload some screenshots and describe what you're working on. I'm very excited to see what kind of stuff people come up with. Again though, try to keep it simple at first and work your way up. Starting off easy is the key to getting comfortable with this. And I'd say that we'll conclude this class. Thank you so much for going through this material. If you have not already, please leave a review and if you enjoyed the class, please recommend it. I greatly appreciate the support from here. Feel free to contact me with any Lua, love or general programming questions. I'm always willing to help out however I can with all that said, I believe that covers everything. Thanks again for taking my class and I look forward to seeing you in the next one.