Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

18. September 2017

Click here for the previous tutorial section.

Now it’s time to create our bowling lane. If you are a Patreon, the resources we are using are located in the GFS Dropbox in the GameKits\Bowling folder. Godot works a bit different from other game engines in that complex models are imported as scenes. Simply select Import->Scene

clip_image002

At a minimum select the DAE (COLLADA) file location, then the location within your project to import into, then finally click import.

clip_image004

One thing that is very important to realize here is this process will import the entire scene from the model file. This includes lights, cameras, etc… so be sure when you export to DAE, you only export the items you want imported. Of course, you’ve got the option of deleting unneeded items in Godot if needed.

It is possible that the import process doesn’t always bring in the textures, so we will cover doing this part manually. If your model imported fully textured, you can skip ahead and ignore this section. First import that texture object into your scene. The bowling lane has two textures, a diffuse (color) and normal (depth) map. Select Import->Texture.

clip_image006

Then select the texture, where to import it and finally hit the import button.

clip_image008

Repeat this process for each texture file you need to import. Now we need to define a material on our BowlingLane node. Select the BowlingLane, locate MeshInstance->Material->0, click the drop down and select New FixedMaterial.

clip_image010

This will create a new material. Drop it down again and this time select Edit.

clip_image012

Now locate Diffuse, drop down the pull down and select Load.

clip_image014

Select your newly imported Diffuse texture. Now repeat the process for Normal

clip_image016

You can control the strength of the normal map using the Normal Depth setting:

clip_image018

Your Bowling Lane should now look a lot more like a bowling lane than before!

clip_image020

Now we need to add some Physics nodes to our lane. In the Scene graph, select the BowlingLane mesh instance, right click and select Add Child Node.

clip_image022

Select StaticBody.

clip_image024

This will make our lane part of the physics simulation, but as the name suggests, it wont be affected by it. So basically, a static body can be hit, but nothing will happen to it. Finally, we need to define the geometry of physics object. Right click your newly created StaticBody, select Add Child Node Again and this time select CollisionShape.

clip_image026

With the newly created CollisionShape selected, locate Shape, drop down and select New BoxShape.

clip_image028

Now select the Shape drop down again and select Edit

clip_image030

Now modify the Extents until it tightly wraps the underlying shape.

clip_image032

We are now done with the lane. Save the scene file and close it.

Creating the Bowling Pin

Now we repeat the exact same process, except this time with our bowling pin. The process is actually identical, except instead of creating a StaticBody, we create a PhysicsBody. However, in this case the RigidBody needs to be the parent of the Pin. Don’t worry, its pretty simple. Be sure to make the RigidBody node a child of the Root “BowlingPin” node, then drag the Pin node onto the newly created RigidBody. So we can identify the node in code later, also rename it from RigidBody to PinRigidBody. The end result should look like:

clip_image034

In the properties of our RigidBody, we also want to set Can Sleep off and Contact Monitor on, like so:

clip_image036

Creating our Bowling Alley

Now it’s time to put it all together. Go back to GameScene in the editor and we need to create some instances of our lane and pins. Simply locate the lane in the assets view, right click and select Instance.

clip_image038

Now repeat the process for the bowling pin. Your scene should now look something like:

clip_image040

Next reposition the bowling pin and so it’s above the lane and down a bit. Now it’s the moment of truth… are you a 5 pin or 10 pin fan? Either way, duplicate the first pin. Locate it in the Scene panel, right click and select duplicate ( or select and hit Ctrl + D ).

clip_image042

Then move the pin into position and repeat the process. If you want, now is your chance to create 7 pin bowling! Personally, I went with 5, and it looks like this:

clip_image044

5 pin for life! We are certainly getting there! It’s at least starting to feel like a bowling game. It would be a good time to check out our work, but press play and you’ll notice a problem… nothing shows up! That’s because we need to create a camera! With the root node selected, create a new node and select Camera:

clip_image046

Now position the camera in your scene using the transform manipulator. With a camera node selected, you can hit the Preview button at any time to, well, preview the camera.

clip_image048

Now when we press play…

clip_image050

Hmm, a bit dark in here isn’t it? Well that makes sense, we have no lights in our scene. We have two options here… we can add some lights or we can add ambient lighting. Getting the later right is probably a bit easier, so lets take that approach. With the camera selected, located the Environment setting, drop it down and select New Environment

clip_image052

Now drop it down again, this time selecting Edit. Now turn Ambient lighting on and select a color close to white.

clip_image054

One thing you might find is that the results are really blurry and undesirable. There are two ways to address this… first, select the texture, locate the flags propert and turn off MipMap and Filtering:

clip_image056

Finally, in the mesh of an imported scene, you can turn off baked lighting:

clip_image058

Both of these steps are completely optional. At this point our game should look like:

clip_image060

And our scene should look like:

clip_image062

Now all we need is a ball!  Click here for the next tutorial section.

Programming , ,

18. September 2017

Click here for the previous section in this tutorial.

Time for the exact same process as pin and lane, except this time rename the RigidBody to BowlingBallRigidBody. The major differences are we used a SphereShape for our collision shape.

clip_image002

Plus, in physics, in addition to setting Sleep off, and Contact Listener on, we increase the Mass to 3. The value doesn’t really matter, this just means our bowling ball is 3x heavier than the pins.

clip_image004

Just for now lets get things rolling (ugh… the puns) and give our ball some initial velocity, so when we play our game, things happen. We will override this in a bit when we implement user control. Simply set the velocity to -15 or so on the Z axis:

clip_image006

Now when you play the game, if you’ve done everything correctly, the ball should roll down the lane and hit the pins.

clip_image008

Almost there! Now let’s add some audio that happens when the ball hits a pin. It’s the exact same process as back when we created our title screen, so I’m not going to go over it again. Just be sure to add the SamplePlayer to the bowling ball like so:

clip_image010

Then go in and create a sample library and add our bowling ball sound effect, in my case Hit.wav.

Now it’s time to do a bit of coding. The BowlingBall is going to be the heart of our game, so let’s add the script to it. Using the same process as back in the title screen, select the BowlingBall root node and attach a new script. Now select the child BowlingBallRigidBody node, switch to the Node tab, select body_enter and hit the Connect button at the bottom right hand corner.

clip_image012

Another window will pop up asking you which node to connect to. Select our BowlingBall node then click Connect.

clip_image014

This will open up the script editor and create a new function for us. Inside the function enter the following code:

func _on_BowlingBall_body_enter( body ):
	var name = body.get_name()
	if name == "PinBody":
		self.get_node("SamplePlayer").play("Hit")

Now when you play the scene, when the bowling ball hits the pins, audio should play!

Handling User Input

** Before you continue… go back to the bowling ball and remove the Linear velocity we added earlier! We are going to handle that manually from this point on! **

Next we need to give the user some control over the bowling ball. First off, we need to create an Input map. We are going to use left and right arrows for moving the ball, well… left and right. Additionally, the space bar will be used to throw the ball.

Go to the Scene -> Project Settings Menu, then switch to the Input Map tab. Now we are going to add an entry. Simply enter LEFT in the text box, then click Add:

clip_image016

Click the + Icon, then select Key

clip_image018

When prompted, press the Left arrow key

clip_image020

Now repeat this process for Right and Space. You can of course map multiple keys to a single ID, so if you wanted LEFT to also trigger when the A key is pressed, or on Left mouse click, you can. Now lets wire our script up to handle input. Simply add or replace the following in your BowlingBall script:

func _ready():
	set_process_input(true)

func _input(event):
	if(event.is_action_released("LEFT")):
		self.get_node("BowlingBallRigidBody").apply_impulse(Vector3(0,0,0),Vector3(-1,0,0))

	if(event.is_action_released("RIGHT")):
		self.get_node("BowlingBallRigidBody").apply_impulse(Vector3(0,0,0),Vector3(1,0,0))
		
	if(event.is_action_released("SPACE")):
		self.get_node("BowlingBallRigidBody").apply_impulse(Vector3(0,0,0),Vector3(0,0,-35))

Great, we can now control our ball, have collisions with pins and audio plays. We are 99% of the way toward a finished game… only one catch… you can only play once… that’s a bit of an issue no? Let’s do a quick and direct reset by reloading the scene when the user presses the R key. Add RESET to the InputMap and append the following code to your _input() function:

	if(event.is_action_released("RESET")):
		get_tree().reload_current_scene()

And our final complete code should look like:

extends Spatial

func _ready():
	set_process_input(true)
	set_process(true)

func _input(event):
	if(event.is_action_released("LEFT")):
		self.get_node("BowlingBallRigidBody").apply_impulse(Vector3(0,0,0),Vector3(-1,0,0))

	if(event.is_action_released("RIGHT")):
		self.get_node("BowlingBallRigidBody").apply_impulse(Vector3(0,0,0),Vector3(1,0,0))
		
	if(event.is_action_released("SPACE")):
		self.get_node("BowlingBallRigidBody").apply_impulse(Vector3(0,0,0),Vector3(0,0,-35))

	if(event.is_action_released("RESET")):
		get_tree().reload_current_scene()

		
func _on_BowlingBallRigidBody_body_enter( body ):
	var name = body.get_name()
	if name == "PinRigidBody":
		self.get_node("SamplePlayer").play("Hit")


And all done, one complete if primitive bowling game!  Once again, here is the video version.

Programming , ,

15. September 2017


Some time back Microsoft launched the UWP, Universal Windows Platform, a target enabling you to create Windows store apps that could also be run on XBox One hardware.  There was however a big catch, limited resources.  From the UWP documentation:

  • The maximum memory available to an app running in the foreground is 1 GB.

    • The maximum memory available to an app running in the background is 128 MB.
    • Apps that exceed these memory requirements will encounter memory allocation failures. For more information about monitoring memory use, see the MemoryManager class reference.

  • Share of 2-4 CPU cores depending on the number of apps and games running on the system.

  • Share of 45% of the GPU depending on the number of apps and games running on the system.

  • UWP on Xbox One supports DirectX 11 Feature Level 10. DirectX 12 is not supported at this time.

  • All apps must target the x64 architecture in order to be developed or submitted to the store for Xbox.

So, basically you got access to half of an Xbox One…  Bummer.  Thankfully in the upcoming Fall Update, that is all about to change!  From the Microsoft blog:

Since the advent of consoles, developers have asked for ways to create games for one platform that you could run anywhere. With the release of the Expanded Resources feature in the Windows Fall Creators Update, we are taking the industry closer to that goal than it has ever been before. Now, developers will automatically have access to 6 exclusive cores, 5 GB of ram and full access to the GPU!

Awesome!  I have a video discussing this change available here.

GameDev News

14. September 2017


The Defold Engine just got it’s own community hub, available at defold.com/community.  In addition to the existing forums and social media pages, the community portal now includes an asset portal and a community games showcase.

image

The Asset portal currently contains just under 30 different projects including new project templates, to Unity Ad plugins and UI systems.  The system also enables authenticated users to upload their own assets.  The new Games page showcases games made using the Defold game engine and also includes the ability to upload your own titles.  The look is very polished, although the icons used right now are rather large requiring a fair bit of scrolling.  Hopefully as the site gets more populated, the sizes are dialed back a little bit for efficiencies sake.


Defold is a free 2D Lua powered game engine.  If you are interested in learning more, we have a complete tutorial series available here.

GameDev News

13. September 2017


The Xenko game engine just released version 2.1.  This recently out of beta C# powered game engine just got a bunch prettier with several xenkorendering improvements.  The engine also gained the ability to stream textures which should decrease scene load times and memory usage.  The input system was rewritten and Direct X 12 support was improved.


The following is a summary of new features in the 2.1 release:

  • Local reflections
  • Clear coat shading
  • Thin glass materials
  • Texture streaming
  • Render masks
  • Improved profiler
  • Debug text during runtime
  • Rewritten input system
  • Improved Direct3D 12 support
  • Improved environment fresnel
  • Japanese documentation now available


For more details be sure to check out the release notes which includes a full change log.


Xenko was previously known as Paradox and we did a short tutorial series available here if you wish to learn more.

GameDev News

Month List

Popular Comments