Setting up a project on top of planning, is something a lot of beginners tend to overlook.
Being a programmer is the same as being an artist, especially true if you are a solo game developer.
An artist doesn’t immediately draw, they first plan what they want to draw, and then they work on their
art station setup.
What paint brushes should they bring along, what colored paints will they need, what time of day should they
start at for being the most effective?
This is the mentality you need to bring to yourself as a programmer, although not as meticulous, thankfully.
First start by opening up the Godot Game Engine application and creating a new project.
Make sure to click the new project button, we are starting from scratch.
A popup should appear, give your project a name, and a project path location in which to create the project at.
In this case I will name the project Pong Basics Series.
You are free to give any name you want to the project.
Next go ahead and delete the Godot Game Engine logo. We will not be needing it for this series, and it’s
good practice cleaning out what we will not need when creating projects.
You can delete the image by heading over to the filesystem tab, hovering over the logo, right clicking the logo
, and selecting the delete button.
Deleting things the game will not use before starting a project is always good practice.
Next head over to the scenetree tab and selecting the “2D Scene” button.
A new node called Node2d should have been created.
After the scene has been created let’s go ahead and save our new scene.
To do that head over to the scene menu tab and click on the save scene option.
Leave the name as the default (Node2D.tscn), this project will work inside a single scene.
You should see that the scene has been added to the file system tab.
Since our game will run inside a single script, head over to the filesystem tab to start the process.
Inside the filesystem tab, right click on an open space and select the New Script option.
A popup should appear; go ahead and change the name to pong.gd
Verify that the file has been created inside the FileSystem tab.
Next let’s check if HTML templates for testing on a browser have been installed by heading over to the editor tab
and selecting the Manage Export Templates option.
Make sure that you have downloaded and imported the template file.
Once that’s done, we need to change the viewport setting so that it auto resizes itself to the Godot Game
Engines default window width and height setting for when we upload to itch.io and debugging.
To do this head over to the project menu tab and select the Project Settings option.
The project settings popup page should open up.
Inside the General tab, head over to the window tab under the display section, scroll down to the bottom
of the page.
Inside the Stretch mode section, change the mode setting to viewport.
This will allow the viewport to change its size automatically no matter the screen we are in.
Next set your Node2D.tscn file as your main scene.
To do that head over to your file system, right click on Node2D.tscn, and click on
Set as Main Scene.
Next, grab the pong.gd file and attach it to the root node named Node2D.
Attach **pong.gd** to the root node or else we will not be able to see our game objects drawn to the screen.
Lastly, make sure to download the Roboto Light Font Family from google and add it to your root folder.
To add string onto the screen, we will need a font file and in this series I will be using the Robot-Light
font.
Open the pong.gd file and make sure to delete everything in the file and add only the following to the top
of the file:
#pong.gdextendsNode2D
Since we are making a pong game without using Godot’s Node Tree system, we will need to draw objects and
manage movement withing our script file.
To do this we will need the following lifecycle scripts:
The _physics_process() method will call itself 60 times a second, so it’s delta value is reliable and consistent.
This is perfect when we need to move objects onto the screen.
The _draw() method is where we will draw our game objects onto the player scene when the game is running.
First let’s create our values of the screen width and height that we will need to center and position our
objects onto the player screen.
Here we can see that we are grabbing the root viewports value of the window width and height of our game
screen.
One important thing to note is the use of the onready keyword. We need to use the onready keyword to
properly get our viewport sizes. This is because when we run the game, the file loads before the game scene,
and since the viewport is part of the game scene, their will be no viewport in existence to grab values from.
With the onready keyword, we kindly ask the script to retrieve values once the scene tree has
finished loading, which includes our root viewport,
On top of that we are also calculating half the distance of the width and height of our game screen.
These values are perfect for centering things horizontally and vertically on the screen.
Let’s go ahead and draw the ball on the screen and center it in the middle.
Next episode, I will deal with a simple game state machine.
Transcript
Hello, Godot Tutorials is not sponsored by or affiliated with Godot Game Engine in this episode, I'm going to go over the following.
The first thing is I'm going to show you how I like to set up my project before I actually do anything. Second, I like to draw out what I want to code before actually coding. This is so in my head I can visually see what I will be attempting to do in code. And then third, I actually like to sit down and code what I drew out. Please keep in mind that this project will be uploaded to get up. The download link will be in the description down below. And lastly, before moving for it, I like to scan my code quickly and see if there's anything I need to clean up.
Now, being a programmer in game development is an art form.
What I mean is you can consider yourself an artist and just like an artist, when you have an idea or a feeling inside of you to start drawing, you don't go ahead and actually start drawing. You plan it up and you start setting up for your art project. The same thing applies to programming as well. And so we're going to do our set up first. Obviously, we need to download our game engine. And if you've been following this series, hopefully you already have Godot downloaded. But next, since we are exporting to each HTML, that means we need to have a Web browser that supports debugging.
Now, any Web browser will do just fine. However, I like to use Google Chrome, so make sure you download Google Chrome. On top of that, we will be dealing with text files. In this case, we're going to download Raboteau light and this text file will be used for our dynamic font class when we start printing text to screen basically player instructions. Next in the project, we need to open relevant documentation pages in the video game engine website. As programmers, we don't have to memorize every single API call.
However, understanding which classes we may or may not need and having those opened up will help us when we're stuck on certain issues. After that, we're going to go ahead and set up our debugging web page. And then lastly, we're going to go ahead and create our Pung Project in Godot. So first you're going to go ahead and download Google Chrome. And this is because, again, we're going to use Google Chrome HTML debugging tool. After that, you're going to go ahead and download the rebuttal font family. In this case, I like to download my fonts from Google.
And so in this case, if you go to https fonts that Google dot com, you can search for Rowbottom and you can click the download family button. On top of that, we're going to use the layout. Three hundred text format file. I'm going to go ahead and leave links in the description down below. Now, next, you're also going to make sure you have the video game engine downloaded. In this case, we're going to be using the standard version. Sixty four bit, not the model version, C# sharp support version. On top of that, we're going to go ahead and open up tabs based on the nodes we think we may need in the future.
So in this case, we're going to need the node API.
The node API again contains our virtual methods such as entry, exit tree, basically our game lifecycle functions. Next, we're going to need the node to the API again. The node to the API contains our transformation values. This includes position, rotation and scale. Since we are not going to use nodes, instead we're going to draw them onto the screen. We're also going to need the canvas item API opened up. The canvas item API comes with functions that allow us to draw onto the screen, for example, drawing lines, drawing circles, drawing our rectangles and of course drawing our string.
Speaking of drawing strings, it takes in a font data type as the first argument.
And so we're also going to go ahead and open up the font API class. The most important functions from this class will be the get height and get string size. Now get height and get string size are important because we're going to need to know the height of our fonts that are drawn to screen and we need to know the width of our Funston to screen in order to center our string nicely for the player. Now again, we're also going to need either a dynamic font or bitmap font if we're going to draw to the screen.
So in this case, I'm going to use dynamic font. So go ahead and open up the dynamic font API class. Now, we are not going to use anything from the dynamic font API except for the font data to set which text file we will be using in this case. Robota late and setting the size of our font, in this case size twenty four. Lastly, open up the OS class API. We're going to need its window size in order to get the width and height of our screen.
And lastly, let's go ahead and take a look at setting up. Developer tools for Google Chrome, now you're going to go to the top rate, you're going to see three. Go ahead and click that, go all the way down to more tools, then head down to the bottom.
Click on developer tools. And on the right side of the screen, you should see something open up. Now let's make sure that our errors are persistently logged. What I mean by that is normally by default, if you were to get an error here and you were to refresh your screen or in this case, our tab, you're going to notice that our error disappears to fix this. Go ahead to the top rate, the first gear icon. Click on that, go to preserve log and make sure that it is checkmark.
Now, when we have an error logged on to our console and we click the refresh button, you're going to see that are error stays persisted. Now we can go ahead and close this drop down menu by clicking on the gear icon that is now highlighted in blue. On top of that, let's go ahead and fix our view of our HTML page. So in this case, on our left, this is our view. Now, I'm going to go ahead and click this device button. It's called toggle device toolbar. Go ahead and click that. Make sure it's highlighted in blue.
And you should see this sizable and adjustable screen. The reason we want to be able to adjust this is depending on our settings in Godot and we should be able to change to see what our game may or may not look like when displayed on HTML. And this is dependent on how we're going to upload. In our case, what we're going to do is upload to each detail. So in this case, I want you to go to the top rate and make sure that responsive is checkmark. And keep in mind that we are ten, twenty four by six hundred in the Godot application.
I like to keep it at one hundred percent. But if you feel that this is too big, you can always set the scale to a smaller size. It really doesn't matter in our case. We just want to see how our game displays on a web browser. But again, it's important that we set the size to ten, twenty four by six hundred, which is the default size and the Godot Game Engine's new project. That's because when we upload to the audio, we're going to have to manually set the iFrame and we will be setting it to ten, twenty four by six hundred.
Now that we've set up everything, we can go ahead and start coding. But before you start coding, you should really draw out what you're going to do, or at least where are we going to place our items on the screen. Now when we code in this episode, we're going to create a variable for screen dimensions, create dynamic font for drawing string to the screen, Greek player pedal on the left side, create a pedal which will be on the right side. Both pedals will be centered along the Y axis. Then we will create the ball, which will be centered along the X and Y axis of the screen, which is just the center of the screen.
And lastly, we will create a string aligned to the top of our screen centered on the x axis. Now, if you're wondering how I got this list, it's because I like to draw out what the game will look like and start using math to come up with pseudocode. So let me go ahead and show you that. So over here I have the player screen. It's just a rectangle. But visually, this screen has a lot of math going on. Now, over here I have the screen dimensions. As you can see, we have a width, we have a height both respectively, denoted by the X and Y variables.
And if we want the center of our screen, we have a formula which is just X divided by two, by Y divided by two. And of course at the top corner I have ninety degrees. This just lets me know that we need to be oriented with the screen. If we're going to do simple basic collisions which we will deal with in a later episode. Drawing it out is good because now we know the formula for centering our ball. Now let's go ahead and look at pseudocode for centering the ball. So again, I like to draw things. OK, so in this case, you can see here that I drew the ball in purple.
Notice the light blue at the center. That is the pivot point for our ball. Pivot point again is where our ball will be oriented on the screen given an x y coordinate value in this case for Godot, gdscript a vector to value. And of course I have a radius set for our ball. This lets us know the size of the ball. We will draw onto the screen in this case for our drawing. I set it to ten. We will be using the radius for a later episode when dealing with collisions. However, this value in this case the value of ARC can change.
The most important thing is just visually seeing that our ball has a radius. Now, again, to center our boat to the player screen, we need to take our width of the screen divided by two, which will be the X value in the coordinate system and Y divided by two. And this will center our boat onto the screen. So as you can see here, in pseudocode, our ball position is equal to X, divided by two, by Y divided by two. Let's do the same thing for the. Player panel, which will be left alone, centered on the Y-axis.
So, again, I drew what I think we'll need on the screen in this case. I have our player paddle in purple, the light blue at the top left, which again denotes the pivot point. Now, there will be spacing between the left edge of the screen and the player paddle a given this the variable P, which is just padding, which again is distance from the edge of the screen. On top of that, I drew a width and a height and half height and of course half the width of the screen. Now after we have drawn out what we're going to need, we can go ahead and create our pseudocode for the paddle position.
In this case, paddle position is equal to on the x axis, just the padding value, because, again, we need to move it to the right from the edge of the screen. And that is represented by the value P, which is padding. And now on the Y axis, in order to center our paddle on the screen, we're going to need two things. We're going to need the width of the player screen divided by two, which will take us to the middle of the screen. However, because our pivot point is up here, if we were to leave that value there, our paddle will actually extend further down than we intended it to.
And so visually, for the player, it will not be center to the screen. So to fix that, we need to subtract half of the height of our pedal. And this is because in Godot or y value, going down is a positive value. And so we need to subtract half the height of our pedal in order to visually give the impression that our pedal is in fact centered on the Y axis of the player screen. Now we can do the same exact thing with our pedal and it's going to look similar for the y axis coordinate value.
However, in order to place our pedal to the right side of the screen, we need to do something differently. In this case, we have the X value or in this case the player screen width. And so if we take our X value, we go all the way to the right. We need to subtract the padding we have for the player pedal and the wit of our player pedal in order to get our pedal to be aligned almost mirror like to the player pedal. Now if we look here, our formula shows just that a position is equal to player screen minus padding, plus the width by half of the player screen, the height subtracted by half of the pedal height.
And so just by drawing it out, we can see how we are getting our formulas for the position of our drawings. And of course, again, we have to do the same thing for the instructional text because we're going to put our text at the topmost part of the screen. We need to have a formula for how we are going to place that. In this case, we have half of the screen width. We have a padding from the top. Also, when it comes to strings, they are usually placed in a box of sorts. And that's what's going to happen when we use dynamic font in Godot gdscript.
So with dynamic font, we will be able to get the height of our string container and the width of our string container. Now in Godot, text tends to have natural padding, so whether we need a padding value or not is up to you. In this case, I'm going to omit the padding value just because the rubato text file comes with natural padding. Now, once we've drawn it out, we can sort of see what our pseudocode is going to look like for positioning or text container. So in this case, text position will equal to half the player screen with subtracted by half the text container's width by the height of our container.
Now, if you notice here, we have a pivot point to the bottom left. And that's because I find that when dealing with dynamic font for drawing string, I find that it is bottom left. Let's get to drawing our game objects onto the screen.
So first, go ahead and create your project. In this case, I called my project Pong based series to the top left.
You're going to see the scene tab. Go ahead, press to the scene. You're going to see no tudy now that we've created our route. Note called No De. We're going to go ahead to the scene to Pressin, scroll down to save scene. You're going to get a pop up, leave everything as is and press the button and the scene should be saved in your file system tab. On top of that, let's go ahead and delete the icon. You can go ahead. Right, click, press, delete and click remove. Now that that is out of the way, let's make sure that we can debug in HTML now by default.
You cannot test in HTML or export in HTML until you have downloaded the necessary template files. Let me show you what I mean. Let's pretend you've finished your project and you decided to export to export. You go to the project, scroll all the way down so you see export. Go ahead, click that in the menu. You're going to press the ad tab, pick HTML five. Go ahead, press that. And as you can see here, an error shows and this error. Letting you know that by default, there is no export template found at the expected path.
Now, this error is simple to solve. Let me show you how. Let's go ahead and close that tab. Go ahead to the ED tab. Click on that. Make sure you scroll down to manage export templates. Click on that. And as you can see here, you should have something missing. We need to download this. So go ahead, press the download button. When the download is complete, it's just going to send you to a link because we will need to install from go ahead, press this link. It should automatically download for you. When the file has fully downloaded. You're going to make sure that you know where your file was safe to.
In most cases, it should be the download folder of your respective operating system. Regardless, we're going to go back to our game engine application. We're going to go ahead and close. We're going to click install from file and go to the exact file path where our file has downloaded to in most cases, again, it will be your download folder. In this case, when you finally found your file template, you're going to go ahead, select it and make sure it shows here and you're going to press open your system will then try to extract the templates.
And when it is finished, it will show you with a green text. Now we can press the close button to get out and now let's head back to export again, make sure that everything is working. Go to the project, scroll down until you see export. Go ahead and click that. And as you can see here, there is no error. But let's double check by pressing the trash can icon and pressing the delete button. We can go ahead, remove that and redo the process. Go to the ad, click on it, scroll down to HTML five, click on it. And as you can see here, there is no error given to us.
This means that our template file is working correctly. Now, next, let's go ahead and set up our file system for the rest of the project. I'm going to go ahead right click press folder. I'm going to call it Pung Three. And this is because for each episode I do, I'm going to create a new scene with a new script and continue on. So that way, when you want to revisit a previous episode, you're able to see the code at its full completion at what it was towards the end of the episode. So in this case, for PUNKE three, I'm going to click and drag this scene into Pung three am also going to go ahead and create a new script.
I'm going to call this Pung. I'm going to click and drag this to the top of our No to D in the seen tab. I'm going to go ahead and save this. Everything in this episode will be in the three folder. Everything in the fourth episode will be in the Pung for folder and so forth. Now let's make sure that our game is able to run. We're going to go ahead to the top right. We're going to press the button. In this case, we're being prompted to pick a default scene, press select, make sure that we're in the Pung Three folder. I'm going to go ahead, press two. I'm going to click open, make sure that we are being shown a gray screen.
That's very good. Now, let's make sure that our HTML debugging is working. Now, when you went ahead and downloaded your template file, or in this case when you exported to HTML, what you did was you created this HTML5 icon. When you press this, your Web browser should automatically pop up a new tab in this case, localhost or sixty. In this case, we're going to go ahead and copy this. We're going to close this in favor of what we created earlier in this episode. We're going to go ahead and press this. And as you can see here, this is our game screen as it was intended to be.
Now back to the game engine. Let's start coding. I'm going to go ahead and press the icon. I'm going to delete everything. We're going to start from scratch in this case. Let's make sure that we are extending from no to let's go ahead and create our lifecycle scripts. In this case, we know we need a ready virtual method. I'm going to use the pass because it's empty for now. Next, we need to do the same thing for physics process, virtual method again with the keyword pass. Finally, because we are drawing things to the screen, we're going to call the draw method again with the keyword pass to make sure that errors aren't showing.
Now, let's start with what we need. And what we need is to make sure that we have the player screen width in height. So I'm going to create a comment now in this case, we finish creating the comment. So let's go ahead and create our variables. In this case, we need a variable for the screen width. We're going to use the operating system, global class file. This will get us or window size when this case window size, make sure that we do, in fact get the X value because we're dealing with the X axis. In this case, you can also use the getter method, get window size that x either one is fine.
Most important thing is to stay consistent. In this case, I'm going to stick with the getter method.
Now, let's do the same thing with screen height. In this case, we're still going to use the operating system, global class. We will use the getter method.
But we're going to open the wine because this is because if we only use get window size, what we're doing is we're getting a vector to data type. In this case, it's just going to be ten, twenty four by six hundred and vector two using the dot notation, followed by the way, we are just getting the width of our screen instead of a vector two. And to showcase this let's go ahead and brute force. Now I haven't gone over brute force debugging, but basically anything that prints to the screen is considered brute force debugging.
If you're not brute force debugging, then you are doing unit testing. We will not go over that in this series. Now, if we go here to the output, you can see that this is ten, twenty four by six hundred, which means we are getting the values we need for screen width and screen height. Now let's go ahead and create variables for half of our screen.
In this case, we have our screen width, screen height, half screen with half screen height, and that's enough for our window. Now, let's go ahead and start drawing to the screen. So in this case, let's start with the draw circle method.
In this case, our position is a vector two. And just like our drawing, we're going to be have screen width and half screen height. So let's go ahead and do that right now.
Next on the list is our radius, in this case ten point zero and our color. We're going to set to white using the global color class. Now, let's go ahead and see if it's drawn correctly onto our screen. And just like our drawing, you can see that our circle is actually centered to the screen. So in this case, you could say that the hypothesis you drew is actually correct. Next, let's go ahead and draw our rectangle. In this case, the draw it takes and erect to data type.
I'm going to add the comma for my sanity vector to. For the position and size. In this case, I just want to draw to the screen and so I'm just going to type in values, but our size will be 10 width, followed by one hundred height.
We're also going to create our culture, in this case color white, and that should be enough to satisfy. Let's just make sure that we are drawing. As you can see here, we do have our panel on the screen, but now we want this in the middle. And so just like our formula, let's go ahead and create some variables. Now, one thing to keep in mind is that the values we passed to our player panel will be the same for our iPad, for example, the color, the width of the paddle, the height of the paddle. And so let's go ahead and create some paddle variables.
So in this case, I'm going to create a comment section of paddle variables. In this case, we do want a color.
We're going to go ahead, make sure that that's wait. We're also going to create player vector width and height.
OK, now that we have our pedal color and pedal size next, we need to create half of our pedal height and that's because our formulas for positioning our pedals is reliant on getting half the size of our pedal. So let's go ahead and do that half pedal height sequel to pedal size the Y divided by two, and that gives us half of our pedal height. Lastly, let's go ahead and create our paddle padding. So in this case, we're going to do paddle padding and we're going to give it a value of ten point zero.
This is all we need in order to replace or hard coded values. So let's go ahead and delete that now and replace them with our variables in this case or script variables. So in this case, again, we need a wreck to value. It takes into vectors. The first vector is positioned.
So on the X axis, we're going to use paddle padding on the Y axis, we're going to do half screen height and we're going to minus it with half petal height. The next vector to value will be the same. So in this case, we're just going to do paddle size and then we're going to peson paddle color. And this should satisfy or draw a rectangle method. And if we press the button, you can see that our paddle is now centered to the left side of the screen with a padding of 10 pixels, just like our formula in our drawing.
Now, let's go ahead and draw our opponent. We're going to do the same thing. We're going to do draw Recht again. We're going to get the to in this case for our width. We need the screen width. We're going to subtract it by the paddle padding plus the width of our pedal. In this case, I'm just going to use paddle size, get the X value. Now that we've finished the width of our paddle, let's work on the height. It's going to be the same thing as our player paddle in this case, half height for the screen and we're going to subtract that by half petal height and that should give us its position next.
We need to pass it in the valley for our size. So in this case, it's just paddle size. After we've done that, let's go ahead and set the colors. So in this case, paddle color, and that should satisfy our rectangle for the eye.
And if we press play, we should see that our enemy is now oriented to the middle of the screen on the right side, again, just like our drawing.
Now I want you to notice something here or draw rectangles, use variables instead of the draw correct method. But our draw circle is a mix of variables and hard coded static values or in this case, literal values. So let's go ahead and create those variables for the ball. Let's go ahead and create the radius.
And color for the bull next, let's go ahead and create the color for the bull.
And let's go ahead and replace this, so instead of that, we're going to see a radius and instead of color, we're going to say what color? We're going to go ahead Pressplay. And everything is working as it should. Let's finish off with the funds. So let's go ahead and sectioned that off with a comment. Create the variable for fund.
We're using the new method, and that's basically it before we can move on to actually using the font variable, we need to import the font file we downloaded from Google fonts onto our file system. So in this case, let's go ahead. Right click scroll all the way down. So you see open and file manager click that. Once you've done that, you're going to go ahead and go to where you downloaded your Roboto files. In this case, you're going to pick light. So Raboteau light that T.F.
Once you've highlighted it, you're going to click and drag it onto your file system. Let's go ahead and move that up and we'll leave it in the root directory for our game. Now that we've uploaded our rebuttal dash later to file inside of our file system in the root directory for game, we're going to go ahead and create a variable for our rubato and we're going to load it. In this case, our file has been loaded into our variable called Robuchon. Now we are using the load keyword because we need to load this resource and then apply it or inserted into our variable.
Let me go ahead and change the name to a rebuttal file. A little more descriptive. Lastly, we need to create a variable for our font size, in this case, variable font size equal to twenty four.
Now that we have our variable set up, let's go ahead and edit our dynamic font class type in the ready virtual method, in this case font data and we're going to assign it the rebuttal file. Next, we're going to do the size. We're going to set it to the font size.
Now, once we're done with that, let's go ahead and draw or string onto the scene of our game. Now, from there, we can go ahead and actually drove to the scene. In this case, we need to passata fonts.
On top of that, it takes in a vector two for the position. In this case, we just want to show what happens. So I'm just going to do this, just passing random values just to make sure that our font actually draws onto the screen and we need to pass it. Evalyn, we'll do the simple hello world and that's it. That's all we need to satisfy. Now, I'm going to change this to ten just so I can show you an example of where the pivot point is. So now when we press play, you can see the hello world shows. In this case, one hundred pixels x axis, ten pixels y axis.
But notice how it's cut off. That's because our pivot point is not top left, it's bottom left. So let's go ahead and set those values. Now, in this case, we're going to need to create variables to hold the width of our front and our height of our font. But because we cannot set anything until the ready virtual method, we'll just set empty variables here at the top level of our class. So in this case, we need a half width font. Now, on top of that, we also need a variable to hold our height value.
So in this case, we'll just call it now in the ready virtual method. We actually have to set this up because before now, the reason why we have to leave this empty is because we need to wait for the size and font data. Something to note is that string values, when we need to calculate the width or height of strings, it's a little complicated. That's because different characters have different pixel widths and pixel height. And that depends on the font size you used, for example, twelve pixel size versus twenty four pixel size for your characters.
And it also depends on the type of font you're using or are using Sones or using surf. So again, different fonts give you different pixel heights and different pixel widths for each individual character. Keep in mind the capitals range from about ten to twelve pixels. Lower keys range from six to eight pixels periods. Commas range from four to six pixels. Before we can calculate the width and height of our font, we need to know one. What fun are we using into what's the font size? And of course, lastly, we need to know what our string value is.
And so over here in font variable, we're going to do that. So in this case, variable string value and we're going to leave it to Hello World and we're going to leave it to the world. So in this case, once we have our fun data and sizes set, we can go ahead and find out the with the night.
So let's go ahead and do that.
And we're going to use the fun, get string size, we need to pass it in string value so it knows what it's calculating for in this case, the string value, all we need is the X value and we need to divide that by two. Now, on top of that, we also do need the height of our font.
So Godot comes with something called get height, and that's basically it.
Now, if we reach down here, we can get rid of the hardcoded liberal values and actually use our variables. In this case, we're going to do for the wit.
We need half of the screen with half screen wit and we're going to subtract that by half with Funt. And then for the second Veli, we just need the height and so height. Now let's see if it aligns correctly. And there it is. How the world is aligned correctly at the top or pedal's are aligned correctly at the left right and our ball is at the center. So far so good. But let's test it out in time. So let's go ahead to the top right. Click the button.
Click run in browser. Huh. Something's wrong here. Look at that.
Our whole world is very tiny. At the top are bows in the middle are pedals are in the middle. So everything's aligned correctly. But basically it looks nothing like we had when we were running the debugger directly inside of the video game engine. And just to make sure let's go ahead and refresh here. And it still feels a little off. It's still a little tiny, even though we're running in our ten twenty four by six hundred. So to find out what the issue is, it's better that I show you. But to prove it to you, let's go ahead and actually print that. So always get window size.
Now, when we play it here, you should see that it's ten, twenty four by six hundred. However, if we were to run this in our browser and refresh, check that out. Twenty, forty eight by twelve hundred.
Now, fixing this issue is quite simple. All we have to do is go to Project Tab's click on Project Settings on the general tab.
Scroll down until you find display under display. You should see window. Go ahead, click that. You should see the sites or player screen with our player. Screen height. Ten twenty four. Six hundred. Scroll down under stretch. We're going to pick mode viewport now. When we set the stretch to viewport, what's happening is when our player screen runs, our viewport will shrink or expand to get the value to be the same values you see here under the size portion in our project settings.
Now, you're not done here just because we said viewport doesn't fix everything. Let me show you, even though we press play, everything's fine here. Everything is scale to proportion, scale to how we want it. But when we actually run on HTML, what should happen is it shouldn't even show. It shouldn't even in this case. This is what it looks like when the stretch mode is disabled. When I hit refresh, you can see that things are cut off and that's because our viewport has shrunk. But when we place our game objects, we're placing it on the sizes of twenty, forty eight and twelve hundred.
Now, fixing this is quite simple. Instead of using the operating system, get window size. What we can do instead is we can get the root viewport.
So let's go ahead and do that right now. So in this case, we're going to get tree. Get root.
And then we're going to get the size now when we print this to the screen, what we should see is ten, twenty four by six hundred. Now, let's go ahead, run this in the browser.
And down here you can see ten, twenty four by six hundred. Let me clear this again so you can see so ten, twenty four by six hundred. Now as you can see here, we solve the problem sort of. Now you have to remember that shrinking or stretching of the viewport happens after everything's loaded. And so even if we were to do something like this, get treatment, get route that size that X, it's actually going to throw an error. So we have to do is either call the unready keyword, make sure that we call this and everything else that relies on it once everything has loaded and done with on the scene.
True. In this case, we need to wait for get to get through to actually expand and shrink and apply itself. We need to wait for the viewport to actually load onto the scene and then we wait for everything else. And now let's test it out if we press the play button. Notice how nothing changes here. Now, if we run it in the browser, look at that. Everything is in proportion. A little pixilated here, but that's OK. Now, lastly, let's just go ahead and start cleaning our code a little bit. So in this case, now, if we look here, I see something wrong. We have held a world that's actually completely lucky that it ran just right.
Let's use these string value. So over here we can see vector to rectangle. Rectangle spends so much that we actually have to scroll. In this case, it's hard to read code. And one of the principles I taught in the previous series is the keep it simple principle or keep it super simple principle. Now, in this case, we're going to pull up the vector two values and assign them to variables. However, notice that we're reliant on the screen width, which has the unready keyword. Now, when I make changes in this case, this is called refactoring.
I'd like to do it one step at a time. So in this case, vector two, I'm going to pull out, put it towards the bottom. Now I'm going to use the unready keyword, followed by var, followed by a variable name.
In this case, I'm going to quit Ball Vector, which has our position, by the way, and so probably should rename that to ball position and we're going to assign it vector to have screen with half screen height. Now I'm going to take the variable ball, replace this or refactor it, press safe, press the play button, make sure that nothing breaks one step at a time. Now I'm going to put both variable, make sure that we separate our values. Now I'm going to do the same thing with the player pedal.
Go ahead, pick our player Pedowitz this right here. I'm going to copy and paste it, probably copy paste it wrong. That's how big this code is. It's a vector to inside of Iraq to same thing on ready keyword followed by var followed by player position.
I'm going to copy paste that replace this big, ugly line of code with a smaller line of code, make sure it works and it does. OK, now that we got our player position ready, we're actually going to change the name instead. This is going to be a player start.
Position because everything's centered. I'm also going to replace this because it's throwing an error and now we're going to have another unready variable called player position.
It's going to be vector two and we're just going to copy and paste this.
And this panel says we don't really need to insert a vector tube because it already is a vector, too, so I'm going to go ahead, change that clear position. Now, if we press the button, you can see that nothing's changed. Let's go ahead and do the same thing for R a I pedal. So I pedal.
I'm going to just get the ready. Same thing I position after that, we're going to do the A.I. start position.
And we're going to copy and paste again.
Get rid of the vector, too, we don't need it because size is already a vector.
Make sure that our position is inside our draw function. Press the button. We always want to make sure that our changes hasn't broken anything constant debugging. Lastly, we're going to do the same thing for the string value. However, it's going to work a little differently just because our string value requires funds and font is set in our already virtual method.
Now, in this case, let's go ahead and create a common and we're going to set our variable code string position and towards the bottom of our ready virtual method. We're going to go ahead copy paste this. We're going to set our string position in the ready virtual method. We're going to copy the string position. We're going to sit here. We're going to refactor it. So now our drill method is clearer. We're going to press the button, make sure everything works. And yes, hello, world still up there.
On top of that, we're going to make sure that when we run in browser that everything's fine. And yes, yes, it is. Now, we're going to do one more thing. One more thing. So you see this drawer method. Now, what we're really doing is we're creating a starting position. And so in this case, we're going to create a function. We're going to call it sets starting position.
We're going to copy all of this.
We're going to color method here and now when we press play, we start in the starting position and this is good because when we actually create our game further along, we're going to create states in which we need to reset everything on the screen. And this is basically it. Now, at some point you need to tell yourself to stop cleaning code. Just keep in mind, as long as it's good enough.
And in this case, everything fits along just fine here. We don't really need to scroll. If anything, we can also expand. And as you can see, there's not really much scrolling you need to do maybe the position value. But again, if it's too long, you can also hit the return. You can use two lines to do your unready variable. It's not going to break anything. By the way, if you do that, that is OK to do at some point. You just need to move forward. Don't get stuck on perfection because perfection is the enemy of progress. Now, I will be honest. I'm not excited about the variable name for the value that holds our data type that we pass into our draw function.
So I will make one last change. I'll just go a rectangle. I think that a rectangle is more descriptive of what this variable is. The problem and the irony is, is that we use the data type in the name, which I don't like to do. If anything, I would actually do something like this, a wreck to. Now, this is a little better when it comes to naming convention because it actually holds our object. It holds everything that it is the position and the paddle size. And we just pass this in to the draw rectangle function for the game engine to draw to the screen.
Regardless, I'm just going to leave it as is. We'll just settle with that until a better name comes along or until we reach the end of the project in which I'll refactor it using declared data types on the variables. And of course, when you change the name, just keep in mind that we're also going to throw errors because these things don't exist down here. That should clear the error. You may also have a warning to fix that. You just have to put the underscore in front of Delta, let the game engine, even though use the physics process, virtual method, you aren't going to be using the Delta function.
And that's it. I'm basically done in the next episode will be going over basic state machines.
So in summary, when cleaning up your code, don't focus on perfection. Perfection is the enemy of progress and you need to progress to reach the finish line to finish your project. And more importantly, this includes variable and function names. It's perfectly normal for your variable and function names to evolve over time. And this is because over time, as you use your variables and functions in more places inside of your code, you will get a better sense of what those variable names should be.
Now, what I did earlier is a refactoring technique called variable extraction. Variable extraction is taking a complex coding freeze and simplifying them with variables. Let's go ahead and take a look at that. So on the left side, we have our code. If player health is less than one hundred and our health is greater than zero. So basically, if our player health is between zero and one hundred, we want to do something well with variable extraction. What we do is we pull out the code in yellow and put it inside a variable.
In this case, variable is alive, is equal to player health, less than one hundred and player health is greater than zero. What this will do is it will return back a boolean value into the variable called is alive and from is alive. We put that inside or if statement if is alive, do something. The reason you do variable extractions is because you want to make your code readable. In this case, if it is alive describes or self documents to the programmer, what this if statement will do versus if a programmer has to read this if statement both mean the same thing.
But the one on the right is easier to read than the one on the left. So the one thing about code refactoring is that if you are able to refactor in one direction, then refactoring in the opposite direction is also available to you as a tool. Now, in this case, the opposite direction of variable instruction is called variable insertion. And so variable insertion is taking a variable and inserting it into a coding phrase. Now, in this case, this is our code right here. Variable is dead, is equal to player health, less than zero. If is that do something.
However, if we were to do variable insertion, another name for that is also called in lining variables. Then what we do is we take out the variable, we keep the logic health less than zero, and we insert it into our if statement if player health is less than zero. And so both do the same thing. Arguably the one on the left is a little cleaner than the one on the right because we get rid of one line of code. So in a sense, called refactoring or cleaning up code is an art form. There's more than one way to write code. There's more than one way to clean code.
Over time, you may find yourself refactoring in different directions as your code grows, because over time, certain decisions make more sense than others. Now, if you are a little confused about when to refactor, that's OK, because, again, it is an art form. Just keep in mind to focus on finishing your project rather than focusing on the perfect line of code. Thank you so much for joining me. Thank you for clicking the like button. And thank you for clicking the subscribe button.
I look forward to seeing you in the next episode. Have an amazing day.