Browse Source

Copyedit of "getting_started/step_by_step/your_first_game" (#1128)

* Added "your_first_game.rst"

* Minor edits

* Changed "CamelCase" to "PascalCase"
Gem 7 years ago
parent
commit
0535f79cd1
1 changed files with 112 additions and 111 deletions
  1. 112 111
      getting_started/step_by_step/your_first_game.rst

+ 112 - 111
getting_started/step_by_step/your_first_game.rst

@@ -6,39 +6,38 @@ Your First Game
 Overview
 --------
 
-This tutorial will guide you through making your first Godot Engine
-project. You will learn how the Godot Engine editor works, how to structure
+This tutorial will guide you through making your first Godot
+project. You will learn how the Godot editor works, how to structure
 a project, and how to build a 2D game.
 
-.. note:: This project is an introduction to the Godot Engine. It
+.. note:: This project is an introduction to the Godot engine. It
           assumes that you have some programming experience already. If
           you're new to programming entirely, you should start here:
           :ref:`doc_scripting`.
 
-The game is called *"Dodge the Creeps"*. Your character must move and
+The game is called "Dodge the Creeps!". Your character must move and
 avoid the enemies for as long as possible. Here is a preview of the
 final result:
 
 .. image:: img/dodge_preview.gif
 
-**Why 2D?**
-    3D games are much more complex than 2D ones. You should stick to 2D
-    until you have a good understanding of the game development process.
+**Why 2D?** 3D games are much more complex than 2D ones. You should stick to 2D
+until you have a good understanding of the game development process.
 
 Project Setup
 -------------
 
 Launch Godot and create a new project. Then, download
 :download:`dodge_assets.zip <files/dodge_assets.zip>` - the images and sounds you'll be
-using to make the game. Unzip these files in your new project folder.
+using to make the game. Unzip these files to your project folder.
 
-.. note:: For this tutorial, we will assume you are already familiar with the
-          Godot Engine editor. If you haven't read :ref:`doc_scenes_and_nodes`, do so now
+.. note:: For this tutorial, we will assume you are familiar with the
+          editor. If you haven't read :ref:`doc_scenes_and_nodes`, do so now
           for an explanation of setting up a project and using the editor.
 
-This game will use "portrait" mode, so we need to adjust the size of the
+This game will use portrait mode, so we need to adjust the size of the
 game window. Click on Project -> Project Settings -> Display -> Window and
-set ``Width`` to ``480`` and ``Height`` to ``720``.
+set "Width" to 480 and "Height" to 720.
 
 Organizing the Project
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -47,8 +46,8 @@ In this project, we will make 3 independent scenes: ``Player``,
 ``Mob``, and ``HUD``, which we will combine into the game's ``Main``
 scene. In a larger project, it might be useful to make folders to hold
 the various scenes and their scripts, but for this relatively small
-game, you can save your scenes and scripts in the root folder, which is
-referred to as ``res://``.  You can see your project folders in the Filesystem
+game, you can save your scenes and scripts in the root folder,
+referred to as ``res://``.  You can see your project folders in the FileSystem
 Dock in the upper left corner:
 
 .. image:: img/filesystem_dock.png
@@ -56,9 +55,9 @@ Dock in the upper left corner:
 Player Scene
 ------------
 
-The first scene we make defines the "Player" object. One of the benefits
+The first scene we will make defines the ``Player`` object. One of the benefits
 of creating a separate Player scene is that we can test it separately, even
-before we've created the other parts of the game.
+before we've created other parts of the game.
 
 Node Structure
 ~~~~~~~~~~~~~~
@@ -68,21 +67,21 @@ node to the scene.
 
 .. image:: img/add_node.png
 
-With ``Area2D`` we can detect other objects that overlap or run into the player.
-Change its name to ``Player``. This is the scene's "root" or top-level node.
-We can add additional nodes to the player to add functionality.
+With ``Area2D`` we can detect objects that overlap or run into the player.
+Change its name to ``Player`` by clicking on the node's name.
+This is the scene's root node. We can add additional nodes to the player to add functionality.
 
 Before we add any children to the ``Player`` node, we want to make sure we don't
-accidentally move or resize them by clicking on them. Select the player node and
-click the icon next to the lock - its tooltip says "Makes sure the objects children
+accidentally move or resize them by clicking on them. Select the node and
+click the icon to the right of the lock; its tooltip says "Makes sure the object's children
 are not selectable."
 
 .. image:: img/lock_children.png
 
-Save the scene (click Scene -> Save, or press ``Control+S`` on Windows/Linux or ``Command+S`` on Mac).
+Save the scene. Click Scene -> Save, or press ``Ctrl+S`` on Windows/Linux or ``Command+S`` on Mac.
 
-.. note:: In this project, we will be following the Godot Engine naming
-          conventions. Classes (Nodes) use ``CapWords``, variables and
+.. note:: For this project, we will be following the Godot naming
+          conventions. Classes (nodes) use ``PascalCase``, variables and
           functions use ``snake_case``, and constants use ``ALL_CAPS``.
 
 Sprite Animation
@@ -92,7 +91,7 @@ Click on the ``Player`` node and add an :ref:`AnimatedSprite <class_AnimatedSpri
 child. The ``AnimatedSprite`` will handle the appearance and animations
 for our player. Notice that there is a warning symbol next to the node.
 An ``AnimatedSprite`` requires a :ref:`SpriteFrames <class_SpriteFrames>` resource, which is a
-list of the animation(s) it can display. To create one, find the
+list of the animations it can display. To create one, find the
 ``Frames`` property in the Inspector and click "<null>" ->
 "New SpriteFrames". Next, in the same location, click
 ``<SpriteFrames>`` to open the "SpriteFrames" panel:
@@ -102,8 +101,8 @@ list of the animation(s) it can display. To create one, find the
 
 On the left is a list of animations. Click the "default" one and rename
 it to "right". Then click the "Add" button to create a second animation
-named "up". Drag the two images for each animation into "Animation
-Frames" side of the panel:
+named "up". Drag the two images for each animation, named ``playerGrey_up[1/2]`` and ``playerGrey_walk[1/2]``,
+into the "Animation Frames" side of the panel:
 
 .. image:: img/spriteframes_panel2.png
 
@@ -115,15 +114,15 @@ property to ``(0.5, 0.5)``. You can find it in the Inspector under the
 .. image:: img/player_scale.png
 
 Finally, add a :ref:`CollisionShape2D <class_CollisionShape2D>` as a child
-of the ``Player``. This will determine the player's "hitbox", or the
+of ``Player``. This will determine the player's "hitbox", or the
 bounds of its collision area. For this character, a ``CapsuleShape2D``
-gives the best fit, so next to "Shape" in the Inspector, click
+node gives the best fit, so next to "Shape" in the Inspector, click
 "<null>"" -> "New CapsuleShape2D".  Resize the shape to cover the sprite:
 
 .. image:: img/player_coll_shape.png
 
-.. warning:: Remember not to scale the shape's outline! Only use the
-             size handles (red) to adjust the shape!
+.. warning:: Don't scale the shape's outline! Only use the
+             size handles (circled in red) to adjust the shape!
 
 When you're finished, your ``Player`` scene should look like this:
 
@@ -138,13 +137,13 @@ node, so we'll add a script. Click the ``Player`` node and click the
 
 .. image:: img/add_script_button.png
 
-In the script settings window, you can leave the default settings, just
+In the script settings window, you can leave the default settings alone. Just
 click "Create":
 
 .. image:: img/attach_node_window.png
 
-.. note:: If this is your first time encountering GDScript please read
-          :ref:`doc_scripting` first.
+.. note:: If this is your first time encountering GDScript, please read
+          :ref:`doc_scripting` before continuing.
 
 Start by declaring the member variables this object will need:
 
@@ -163,8 +162,8 @@ the ``Player`` node and set the speed property to ``400``.
 
 .. image:: img/export_variable.png
 
-The ``_ready()`` function is called when a node enters the scene tree, so
-that's a good time to find the size of the game window:
+The ``_ready()`` function is called when a node enters the scene tree, 
+which is a good time to find the size of the game window:
 
 ::
 
@@ -172,14 +171,14 @@ that's a good time to find the size of the game window:
         screensize = get_viewport_rect().size
 
 Now we can use the ``_process()`` function to define what the player will do.
-The ``_process()`` function is called on every frame, so we'll use it to update
-elements of our game which we expect to be changing often. Here we'll have it:
+``_process()`` is called every frame, so we'll use it to update
+elements of our game which we expect will change often. Here we'll make it:
 
-- check for input
-- move in the given direction
-- play the appropriate animation.
+- Check for input.
+- Move in the given direction.
+- Play the appropriate animation.
 
-First, we need to check the inputs - is the player pressing a key? For
+First, we need to check for input - is the player pressing a key? For
 this game, we have 4 direction inputs to check. Input actions are defined
 in the Project Settings under "Input Map". You can define custom events and
 assign different keys, mouse events, or other inputs to them. For this demo,
@@ -218,7 +217,7 @@ We can prevent that if we *normalize* the velocity, which means we set
 its *length* to ``1``, and multiply by the desired speed. This means no
 more fast diagonal movement.
 
-.. tip:: If you've never used vector math before (or just need a refresher)
+.. tip:: If you've never used vector math before, or just need a refresher,
          you can see an explanation of vector usage in Godot at :ref:`doc_vector_math`.
          It's good to know but won't be necessary for the rest of this tutorial.
 
@@ -228,10 +227,10 @@ AnimatedSprite animation.
 .. tip:: ``$`` returns the node at the relative path from this node, or returns ``null`` if the node is not found.
          Since AnimatedSprite is a child of the current node, we can just use ``$AnimatedSprite``.
          
-         ``$`` is the short hand for ``get_node()``.
+         ``$`` is shorthand for ``get_node()``.
          So in the code above, ``$AnimatedSprite.play()`` is the same as ``get_node("AnimatedSprite").play()``.
 
-Now that we have a movement direction, we can update the player's position
+Now that we have a movement direction, we can update ``Player``'s position
 and use ``clamp()`` to prevent it from leaving the screen:
 
 ::
@@ -241,13 +240,13 @@ and use ``clamp()`` to prevent it from leaving the screen:
         position.y = clamp(position.y, 0, screensize.y)
 
 
-.. tip:: *Clamping* a value means restricting it to a given minimum/maximum range.
+.. tip:: *Clamping* a value means restricting it to a given range.
 
-Click "Play the Edited Scene. (F6)" and confirm you can move the player
+Click "Play Scene" (``F6``) and confirm you can move the player
 around the screen in all directions.
 
 .. warning:: If you get an error in the "Debugger" panel that refers to a "null instance",
-             this likely means you spelled the node name wrong. Node names are case sensitive
+             this likely means you spelled the node name wrong. Node names are case-sensitive
              and ``$NodeName`` or ``get_node("NodeName")`` must match the name you see in the scene tree.
 
 Choosing Animations
@@ -255,9 +254,9 @@ Choosing Animations
 
 Now that the player can move, we need to change which animation the
 AnimatedSprite is playing based on direction. We have a "right"
-animation, which should be flipped horizontally (using the ``flip_h``
-property) for left movement, and an "up" animation, which should be
-flipped vertically (``flip_v``) for downward movement.
+animation, which should be flipped horizontally using the ``flip_h``
+property for left movement, and an "up" animation, which should be
+flipped vertically with ``flip_v`` for downward movement.
 Let's place this code at the end of our ``_process()`` function:
 
 ::
@@ -271,7 +270,7 @@ Let's place this code at the end of our ``_process()`` function:
             $AnimatedSprite.flip_v = velocity.y > 0
 
 Play the scene again and check that the animations are correct in each
-of the directions. When you're sure that movement is working correctly,
+of the directions. When you're sure the movement is working correctly,
 add this line to ``_ready()`` so the player will be hidden when the game
 starts:
 
@@ -282,29 +281,29 @@ starts:
 Preparing for Collisions
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-We want the player to detect when it is hit by an enemy, but we haven't
-made any enemies yet! That's OK because we're going to use Godot's
+We want ``Player`` to detect when it's hit by an enemy, but we haven't
+made any enemies yet! That's OK, because we're going to use Godot's
 *signal* functionality to make it work.
 
-Add the following at the top of the script (after ``extends Area2d``):
+Add the following at the top of the script, after ``extends Area2d``:
 
 ::
 
     signal hit
 
 This defines a custom signal called "hit" that we will have our player
-emit (send out) when it collides with an enemy. We will use the Area2D to
+emit (send out) when it collides with an enemy. We will use ``Area2D`` to
 detect the collision. Select the ``Player`` node and click the "Node" tab
-next to the Inspector to see the list of signals the player can emit:
+next to the Inspector tab to see the list of signals the player can emit:
 
 .. image:: img/player_signals.png
 
 Notice our custom "hit" signal is there as well! Since our enemies are
 going to be ``RigidBody2D`` nodes, we want the
-``body_entered( Object body )`` signal - that will be emitted when a
+``body_entered( Object body )`` signal; this will be emitted when a
 body contacts the player. Click "Connect.." and then "Connect" again on
-the "Connecting Signal" window - we don't need to change any of those
-settings. Godot will automatically create a function called
+the "Connecting Signal" window. We don't need to change any of these
+settings - Godot will automatically create a function called
 ``_on_Player_body_entered`` in your player's script.
 
 .. tip:: When connecting a signal, instead of having Godot create a
@@ -321,8 +320,8 @@ Add this code to the function:
         $CollisionShape2D.disabled = true
 
 .. Note:: Disabling the area's collision shape means
-             it won't detect collisions. By turning it off, we make
-             sure we don't trigger the ``hit`` signal more than once.
+          it won't detect collisions. By turning it off, we make
+          sure we don't trigger the ``hit`` signal more than once.
 
 
 The last piece for our player is to add a function we can call to reset
@@ -340,7 +339,7 @@ Enemy Scene
 
 Now it's time to make the enemies our player will have to dodge. Their
 behavior will not be very complex: mobs will spawn randomly at the edges
-of the screen and move in a straight line (in a random direction), then
+of the screen and move in a random direction in a straight line, then
 despawn when they go offscreen.
 
 We will build this into a ``Mob`` scene, which we can then *instance* to
@@ -362,26 +361,28 @@ The Mob scene will use the following nodes:
 Don't forget to set the children so they can't be selected, like you did with the
 Player scene.
 
-In the :ref:`RigidBody2D <class_RigidBody2D>` properties, set ``Gravity Scale`` to ``0`` (so
-that the mob will not fall downward). In addition, under the
-``PhysicsBody2D`` section in the Inspector, click the ``Mask`` property and
-uncheck the first box. This will ensure that the mobs do not collide with each other.
+In the :ref:`RigidBody2D <class_RigidBody2D>` properties, set ``Gravity Scale`` to ``0``, so
+the mob will not fall downward. In addition, under the
+``PhysicsBody2D`` section, click the ``Mask`` property and
+uncheck the first box. This will ensure the mobs do not collide with each other.
 
 .. image:: img/set_collision_mask.png
 
 Set up the :ref:`AnimatedSprite <class_AnimatedSprite>` like you did for the player.
-This time, we have 3 animations: "fly", "swim", and "walk". Set the ``Playing``
+This time, we have 3 animations: ``fly``, ``swim``, and ``walk``. Set the ``Playing``
 property in the Inspector to "On" and adjust the "Speed (FPS)" setting as shown below.
-We'll select one of these randomly so that the mobs will have some variety.
+We'll select one of these animations randomly so that the mobs will have some variety.
+
+.. image:: img/mob_animations.gif
+
+``fly`` should be set to 3 FPS, with ``swim`` and ``walk`` set to 4 FPS. 
 
 Like the player images, these mob images need to be scaled down. Set the
 ``AnimatedSprite``'s ``Scale`` property to ``(0.75, 0.75)``.
 
-.. image:: img/mob_animations.gif
-
 As in the ``Player`` scene, add a ``CapsuleShape2D`` for the
 collision. To align the shape with the image, you'll need to set the
-``Rotation Deg`` property to ``90`` under ``Node2D``.
+``Rotation Degrees`` property to ``90`` under ``Node2D``.
 
 Enemy Script
 ~~~~~~~~~~~~
@@ -402,8 +403,8 @@ at the same speed). Set them to ``150`` and ``250`` in the Inspector. We
 also have an array containing the names of the three animations, which
 we'll use to select a random one.
 
-Now let's look at the rest of the script. In ``_ready()`` we choose a
-random one of the three animation types:
+Now let's look at the rest of the script. In ``_ready()`` we randomly 
+choose one of the three animation types:
 
 ::
 
@@ -425,7 +426,7 @@ node and add this code:
     func _on_Visibility_screen_exited():
         queue_free()
 
-That completes the `Mob` scene.
+This completes the `Mob` scene.
 
 Main Scene
 ----------
@@ -460,16 +461,16 @@ Spawning Mobs
 ~~~~~~~~~~~~~
 
 The Main node will be spawning new mobs, and we want them to appear at a
-random location on the edge of the screen. Add a :ref:`Path2D <class_Path2D>` named
-``MobPath`` as a child of ``Main``. When you select the ``Path2D`` node
-you will see some new buttons appear at the top of the editor:
+random location on the edge of the screen. Add a :ref:`Path2D <class_Path2D>` node named
+``MobPath`` as a child of ``Main``. When you select ``Path2D``, 
+you will see some new buttons at the top of the editor:
 
 .. image:: img/path2d_buttons.png
 
 Select the middle one ("Add Point") and draw the path by clicking to add
-the points shown. To have the points snap to the grid, make sure "Snap to
-Grid" is checked. This option can be found under the "Snapping Options"
-button to the left of the "Lock" button. It appears as a series of three
+the points at the corners shown. To have the points snap to the grid, make sure "Snap to
+Grid" is checked. This option can be found under the "Snapping options"
+button to the left of the "Lock" button, appearing as a series of three
 vertical dots.
 
 .. image:: img/draw_path2d.gif
@@ -502,7 +503,7 @@ instance.
     func _ready():
         randomize()
 
-Drag the ``Mob.tscn`` from the "FileSystem" panel and drop it in the
+Drag ``Mob.tscn`` from the "FileSystem" panel and drop it in the
 ``Mob`` property.
 
 Next, click on the Player and connect the ``hit`` signal. We want to make a
@@ -548,14 +549,14 @@ Note that a new instance must be added to the scene using
 ::
 
     func _on_MobTimer_timeout():
-        # choose a random location on the Path2D
+        # choose a random location on Path2D
         $MobPath/MobSpawnLocation.set_offset(randi())
         # create a Mob instance and add it to the scene
         var mob = Mob.instance()
         add_child(mob)
         # set the mob's direction perpendicular to the path direction
         var direction = $MobPath/MobSpawnLocation.rotation + PI/2
-        # set the mob's position to the random location
+        # set the mob's position to a random location
         mob.position = $MobPath/MobSpawnLocation.position
         # add some randomness to the direction
         direction += rand_range(-PI/4, PI/4)
@@ -566,41 +567,41 @@ Note that a new instance must be added to the scene using
 .. important:: In functions requiring angles, GDScript uses *radians*,
                not degrees. If you're more comfortable working with
                degrees, you'll need to use the ``deg2rad()`` and
-               ``rad2deg()`` functions to convert between the two measures.
+               ``rad2deg()`` functions to convert between the two.
 
 HUD
 ---
 
 The final piece our game needs is a UI: an interface to display things
 like score, a "game over" message, and a restart button. Create a new
-scene, and add a :ref:`CanvasLayer <class_CanvasLayer>` node named ``HUD`` ("HUD" stands for
-"heads-up display", meaning an informational display that appears as an
-overlay, on top of the game view).
+scene, and add a :ref:`CanvasLayer <class_CanvasLayer>` node named ``HUD``. "HUD" stands for
+"heads-up display", an informational display that appears as an
+overlay on top of the game view.
 
 The :ref:`CanvasLayer <class_CanvasLayer>` node lets us draw our UI elements on
-the layer above the rest of the game so that the information it displays doesn't get
-covered up by any game elements like the player or the mobs.
+a layer above the rest of the game, so that the information it displays isn't
+covered up by any game elements like the player or mobs.
 
 The HUD displays the following information:
 
--  Score, changed by ``ScoreTimer``
+-  Score, changed by ``ScoreTimer``.
 -  A message, such as "Game Over" or "Get Ready!"
--  A "Start" button to begin the game
+-  A "Start" button to begin the game.
 
 The basic node for UI elements is :ref:`Control <class_Control>`. To create our UI,
-we'll use two types of :ref:`Control <class_Control>` nodes: The :ref:`Label <class_Label>`
-and the :ref:`Button <class_Button>`.
+we'll use two types of :ref:`Control <class_Control>` nodes: :ref:`Label <class_Label>`
+and :ref:`Button <class_Button>`.
 
-Create the following children of the ``HUD`` node:
+Create the following as children of the ``HUD`` node:
 
--  :ref:`Label <class_Label>` (named ``ScoreLabel``)
--  :ref:`Label <class_Label>` (named ``MessageLabel``)
--  :ref:`Button <class_Button>` (named ``StartButton``)
--  :ref:`Timer <class_Timer>` (named ``MessageTimer``)
+-  :ref:`Label <class_Label>` named ``ScoreLabel``.
+-  :ref:`Label <class_Label>` named ``MessageLabel``.
+-  :ref:`Button <class_Button>` named ``StartButton``.
+-  :ref:`Timer <class_Timer>` named ``MessageTimer``.
 
-.. note:: **Anchors and Margins** ``Control`` nodes have a position and size,
+.. note:: **Anchors and Margins:** ``Control`` nodes have a position and size,
           but they also have anchors and margins. Anchors define the
-          origin, or the reference point for the edges of the node. Margins
+          origin - the reference point for the edges of the node. Margins
           update automatically when you move or resize a control node. They
           represent the distance from the control node's edges to its anchor.
           See :ref:`doc_design_interfaces_with_the_control_nodes` for more details.
@@ -667,7 +668,7 @@ the three ``Control`` nodes:
 
 .. image:: img/custom_font2.png
 
-Now add this script to the ``HUD``:
+Now add this script to ``HUD``:
 
 ::
 
@@ -699,7 +700,7 @@ temporarily, such as "Get Ready". On the ``MessageTimer``, set the
         $MessageLabel.show()
 
 This function is called when the player loses. It will show "Game
-Over" for 2 seconds, and then return to the game title and show the
+Over" for 2 seconds, then return to the title screen and show the
 "Start" button.
 
 ::
@@ -726,7 +727,8 @@ Connecting HUD to Main
 
 Now that we're done creating the ``HUD`` scene, save it and go back to ``Main``.
 Instance the ``HUD`` scene in ``Main`` like you did the ``Player`` scene, and place it at the
-bottom of tree. The full tree should look like this, so make sure you didn't miss anything:
+bottom of the tree. The full tree should look like this,
+so make sure you didn't miss anything:
 
 .. image:: img/completed_main_scene.png
 
@@ -763,8 +765,8 @@ be asked to select a main scene, so choose ``Main.tscn``.
 Finishing Up
 ------------
 
-We've now completed all the functionality for our game. Below are some
-remaining steps to add a bit more "juice" and improve the game
+We have now completed all the functionality for our game. Below are some
+remaining steps to add a bit more "juice" to improve the game
 experience. Feel free to expand the gameplay with your own ideas.
 
 Background
@@ -785,19 +787,18 @@ Sound Effects
 
 Sound and music can be the single most effective way to add appeal to
 the game experience. In your game assets folder, you have two sound
-files: "House In a Forest Loop.ogg", for background music, and
+files: "House In a Forest Loop.ogg" for background music, and
 "gameover.wav" for when the player loses.
 
 Add two :ref:`AudioStreamPlayer <class_AudioStreamPlayer>` nodes as children of ``Main``. Name one of
 them ``Music`` and the other ``DeathSound``. On each one, click on the
-``Stream`` property, select "Load" and choose the corresponding audio
+``Stream`` property, select "Load", and choose the corresponding audio
 file.
 
 To play the music, add ``$Music.play()`` in the ``new_game()`` function
 and ``$Music.stop()`` in the ``game_over()`` function.
 
-Finally, add ``$DeathSound.play()`` in the ``game_over()`` function as
-well.
+Finally, add ``$DeathSound.play()`` in the ``game_over()`` function.
 
 Particles
 ~~~~~~~~~
@@ -808,7 +809,7 @@ player's movement. Choose your ``Player`` scene and add a
 
 There are a very large number of properties to choose from when
 configuring particles. Feel free to experiment and create different
-effects. For the effect in the example, use the following settings:
+effects. For the effect in this example, use the following settings:
 
 .. image:: img/particle_trail_settings.png