瀏覽代碼

Updated "2D movement overview" (#6423)

* Update tutorials/2d/2d_movement.rst

Co-authored-by: Raul Santos <[email protected]>
Chris Bradfield 2 年之前
父節點
當前提交
2f904cd216
共有 4 個文件被更改,包括 62 次插入127 次删除
  1. 62 127
      tutorials/2d/2d_movement.rst
  2. 二進制
      tutorials/2d/files/2D_movement_demo.zip
  3. 二進制
      tutorials/2d/img/movement_inputs.png
  4. 二進制
      tutorials/2d/img/movement_inputs.webp

+ 62 - 127
tutorials/2d/2d_movement.rst

@@ -25,7 +25,7 @@ for the Sprite2D's texture or use any other 2D image you have.
 Open ``Project -> Project Settings`` and select the "Input Map" tab. Add the following
 input actions (see :ref:`InputEvent <doc_inputevent>` for details):
 
-.. image:: img/movement_inputs.png
+.. image:: img/movement_inputs.webp
 
 8-way movement
 --------------
@@ -36,77 +36,52 @@ fact that the player can move diagonally by pressing two keys at the same time.
 
 .. image:: img/movement_8way.gif
 
-Add a script to the kinematic body and add the following code:
+Add a script to the character body and add the following code:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
 
     extends CharacterBody2D
 
-    export (int) var speed = 200
-
-    var velocity = Vector2()
+    @export var speed = 400
 
     func get_input():
-        velocity = Vector2()
-        if Input.is_action_pressed("right"):
-            velocity.x += 1
-        if Input.is_action_pressed("left"):
-            velocity.x -= 1
-        if Input.is_action_pressed("down"):
-            velocity.y += 1
-        if Input.is_action_pressed("up"):
-            velocity.y -= 1
-        velocity = velocity.normalized() * speed
+        var input_direction = Input.get_vector("left", "right", "up", "down")
+        velocity = input_direction * speed
 
     func _physics_process(delta):
         get_input()
-        velocity = move_and_slide(velocity)
+        move_and_slide()
 
  .. code-tab:: csharp
 
     using Godot;
     using System;
 
-    public class Movement : CharacterBody2D
+    public partial class Movement : CharacterBody2D
     {
-        [Export] public int speed = 200;
-
-        public Vector2 velocity = new Vector2();
+        [Export]
+        public int Speed { get; set; } = 400;
 
         public void GetInput()
         {
-            velocity = new Vector2();
-
-            if (Input.IsActionPressed("right"))
-                velocity.x += 1;
-
-            if (Input.IsActionPressed("left"))
-                velocity.x -= 1;
-
-            if (Input.IsActionPressed("down"))
-                velocity.y += 1;
 
-            if (Input.IsActionPressed("up"))
-                velocity.y -= 1;
-
-            velocity = velocity.Normalized() * speed;
+            Vector2 inputDirection = Input.GetVector("left", "right", "up", "down");
+            Velocity = inputDirection * Speed;
         }
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
             GetInput();
-            velocity = MoveAndSlide(velocity);
+            MoveAndSlide();
         }
     }
 
-In the ``get_input()`` function, we check for the four key events and sum them
-up to get the velocity vector. This has the benefit of making two opposite keys
-cancel each other out, but will also result in diagonal movement being faster
-due to the two directions being added together.
+In the ``get_input()`` function, we use :ref:`Input <class_Input>` ``get_vector()`` to check for the
+four key events and sum return a direction vector.
 
-We can prevent that if we *normalize* the velocity, which means we set
-its *length* to ``1``, and multiply by the desired speed.
+We can then set our velocity by multiplying this direction vector, which has a
+length of ``1``, by our desired speed.
 
 .. tip:: If you've never used vector math before, or need a refresher,
          you can see an explanation of vector usage in Godot at :ref:`doc_vector_math`.
@@ -131,78 +106,54 @@ while up/down moves it forward or backward in whatever direction it's facing.
 
     extends CharacterBody2D
 
-    export (int) var speed = 200
-    export (float) var rotation_speed = 1.5
+    @export var speed = 400
+    @export var rotation_speed = 1.5
 
-    var velocity = Vector2()
-    var rotation_dir = 0
+    var rotation_direction = 0
 
     func get_input():
-        rotation_dir = 0
-        velocity = Vector2()
-        if Input.is_action_pressed("right"):
-            rotation_dir += 1
-        if Input.is_action_pressed("left"):
-            rotation_dir -= 1
-        if Input.is_action_pressed("down"):
-            velocity = Vector2(-speed, 0).rotated(rotation)
-        if Input.is_action_pressed("up"):
-            velocity = Vector2(speed, 0).rotated(rotation)
+        rotation_direction = Input.get_axis("left", "right")
+        velocity = transform.x * Input.get_axis("down", "up") * speed
 
     func _physics_process(delta):
         get_input()
-        rotation += rotation_dir * rotation_speed * delta
-        velocity = move_and_slide(velocity)
+        rotation += rotation_direction * rotation_speed * delta
+        move_and_slide()
 
  .. code-tab:: csharp
 
     using Godot;
     using System;
 
-    public class Movement : CharacterBody2D
+    public partial class Movement : CharacterBody2D
     {
-        [Export] public int speed = 200;
-        [Export] public float rotationSpeed = 1.5f;
+        [Export]
+        public int Speed { get; set; } = 400;
+
+        [Export]
+        public float RotationSpeed { get; set; } = 1.5f;
 
-        public Vector2 velocity = new Vector2();
-        public int rotationDir = 0;
+        private int _rotationDirection;
 
         public void GetInput()
         {
-            rotationDir = 0;
-            velocity = new Vector2();
-
-            if (Input.IsActionPressed("right"))
-                rotationDir += 1;
-
-            if (Input.IsActionPressed("left"))
-                rotationDir -= 1;
-
-            if (Input.IsActionPressed("down"))
-                velocity = new Vector2(-speed, 0).Rotated(Rotation);
-
-            if (Input.IsActionPressed("up"))
-                velocity = new Vector2(speed, 0).Rotated(Rotation);
-
-            velocity = velocity.Normalized() * speed;
+            _rotationDirection = Input.GetAxis("left", "right");
+            Velocity = Transform.x * Input.GetAxis("down", "up") * Speed;
         }
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
             GetInput();
-            Rotation += rotationDir * rotationSpeed * delta;
-            velocity = MoveAndSlide(velocity);
+            Rotation += _rotationDirection * RotationSpeed * (float)delta;
+            MoveAndSlide();
         }
     }
 
-Here we've added two new variables to track our rotation direction and speed.
-Again, pressing both keys at once will cancel out and result in no rotation.
+Here we've added two variables to track our rotation direction and speed.
 The rotation is applied directly to the body's ``rotation`` property.
 
-To set the velocity, we use the ``Vector2.rotated()`` method, so that it points
-in the same direction as the body. ``rotated()`` is a useful vector function
-that you can use in many circumstances where you would otherwise need to apply
-trigonometric functions.
+To set the velocity, we use the body's ``transform.x`` which is a vector pointing
+in the body's "forward" direction, and multiply that by the speed.
 
 Rotation + movement (mouse)
 ---------------------------
@@ -218,56 +169,41 @@ is set by the mouse position instead of the keyboard. The character will always
 
     extends CharacterBody2D
 
-    export (int) var speed = 200
-
-    var velocity = Vector2()
+    @export var speed = 400
 
     func get_input():
         look_at(get_global_mouse_position())
-        velocity = Vector2()
-        if Input.is_action_pressed("down"):
-            velocity = Vector2(-speed, 0).rotated(rotation)
-        if Input.is_action_pressed("up"):
-            velocity = Vector2(speed, 0).rotated(rotation)
+        velocity = transform.x * Input.get_axis("down", "up") * speed
 
     func _physics_process(delta):
         get_input()
-        velocity = move_and_slide(velocity)
+        move_and_slide()
 
  .. code-tab:: csharp
 
     using Godot;
     using System;
 
-    public class Movement : CharacterBody2D
+    public partial class Movement : CharacterBody2D
     {
-        [Export] public int speed = 200;
-
-        public Vector2 velocity = new Vector2();
+        [Export]
+        public int Speed { get; set; } = 400;
 
         public void GetInput()
         {
             LookAt(GetGlobalMousePosition());
-            velocity = new Vector2();
-
-            if (Input.IsActionPressed("down"))
-                velocity = new Vector2(-speed, 0).Rotated(Rotation);
-
-            if (Input.IsActionPressed("up"))
-                velocity = new Vector2(speed, 0).Rotated(Rotation);
-
-            velocity = velocity.Normalized() * speed;
+            Velocity = Transform.x * Input.GetAxis("down", "up") * Speed;
         }
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
             GetInput();
-            velocity = MoveAndSlide(velocity);
+            MoveAndSlide();
         }
     }
 
 Here we're using the :ref:`Node2D <class_Node2D>` ``look_at()`` method to
-point the player towards a given position. Without this function, you
+point the player towards the mouse's position. Without this function, you
 could get the same effect by setting the angle like this:
 
 .. tabs::
@@ -293,10 +229,9 @@ on the screen will cause the player to move to the target location.
 
     extends CharacterBody2D
 
-    export (int) var speed = 200
+    @export var speed = 400
 
-    var target = Vector2()
-    var velocity = Vector2()
+    var target = position
 
     func _input(event):
         if event.is_action_pressed("click"):
@@ -305,36 +240,36 @@ on the screen will cause the player to move to the target location.
     func _physics_process(delta):
         velocity = position.direction_to(target) * speed
         # look_at(target)
-        if position.distance_to(target) > 5:
-            velocity = move_and_slide(velocity)
+        if position.distance_to(target) > 10:
+            move_and_slide()
 
  .. code-tab:: csharp
 
     using Godot;
     using System;
 
-    public class Movement : CharacterBody2D
+    public partial class Movement : CharacterBody2D
     {
-        [Export] public int speed = 200;
+        [Export]
+        public int Speed { get; set; } = 400;
 
-        public Vector2 target = new Vector2();
-        public Vector2 velocity = new Vector2();
+        private Vector2 _target;
 
         public override void _Input(InputEvent @event)
         {
             if (@event.IsActionPressed("click"))
             {
-                target = GetGlobalMousePosition();
+                _target = GetGlobalMousePosition();
             }
         }
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
-            velocity = Position.DirectionTo(target) * speed;
+            velocity = Position.DirectionTo(_target) * Speed;
             // LookAt(target);
-            if (Position.DistanceTo(target) > 5)
+            if (Position.DistanceTo(_target) > 10)
             {
-                velocity = MoveAndSlide(velocity);
+                MoveAndSlide();
             }
         }
     }

二進制
tutorials/2d/files/2D_movement_demo.zip


二進制
tutorials/2d/img/movement_inputs.png


二進制
tutorials/2d/img/movement_inputs.webp