|
@@ -8,7 +8,7 @@ Pong
|
|
|
|
|
|
In this simple tutorial, a basic game of Pong will be created. There are
|
|
|
plenty of more complex examples in the demos included with the engine,
|
|
|
-but this should get introduced to basic functionality for 2D Games.
|
|
|
+but this should get one introduced to basic functionality for 2D Games.
|
|
|
|
|
|
Assets
|
|
|
~~~~~~
|
|
@@ -25,7 +25,7 @@ resolution. This can be configured in the Project Settings (see :ref:`doc_scenes
|
|
|
.. image:: /img/clearcolor.png
|
|
|
|
|
|
Create a :ref:`class_Node2D` node for the project root. Node2D is the base
|
|
|
-type for the 2D engine. After this, add some sprites :ref:`class_Sprite`
|
|
|
+type for the 2D engine. After this, add some sprites (:ref:`class_Sprite`
|
|
|
node) and set each to the corresponding texture. The final scene layout
|
|
|
should look similar to this (note: the ball is in the middle!):
|
|
|
|
|
@@ -38,7 +38,7 @@ The scene tree should, then, look similar to this:
|
|
|
Save the scene as "pong.scn" and set it as the main scene in the project
|
|
|
properties.
|
|
|
|
|
|
-.. _doc_simple_2d_game-input_actions_setup
|
|
|
+.. _doc_simple_2d_game-input_actions_setup:
|
|
|
|
|
|
Input actions setup
|
|
|
~~~~~~~~~~~~~~~~~~~
|
|
@@ -55,9 +55,10 @@ is defined, then input methods that trigger it are added.
|
|
|
Open the project properties dialog again, but this time move to the
|
|
|
"Input Map" tab.
|
|
|
|
|
|
+.. role:: python(code)
|
|
|
On it, add 4 actions:
|
|
|
-"left_move_up","left_move_down","right_move_up","right_move_down".
|
|
|
-Assign the keys that you desire. A/Z for left and Up/Down as keys
|
|
|
+``left_move_up``, ``left_move_down``, ``right_move_up``, ``right_move_down``.
|
|
|
+Assign the keys that you desire. A/Z (for the left player) and Up/Down (for the right player) as keys
|
|
|
should work in most cases.
|
|
|
|
|
|
.. image:: /img/inputmap.png
|
|
@@ -92,16 +93,16 @@ the dimensions of the screen and the pad:
|
|
|
pad_size = get_node("left").get_texture().get_size()
|
|
|
set_process(true)
|
|
|
|
|
|
-Then, some variables used for in-game will be added:
|
|
|
+Then, some variables used for in-game processing will be added:
|
|
|
|
|
|
::
|
|
|
|
|
|
- #speed of the ball (in pixels/second0
|
|
|
+ #speed of the ball (in pixels/second)
|
|
|
|
|
|
var ball_speed = 80
|
|
|
#direction of the ball (normal vector)
|
|
|
|
|
|
- var direction = Vector2(-1,0)
|
|
|
+ var direction = Vector2(-1, 0)
|
|
|
#constant for pad speed (also in pixels/second)
|
|
|
|
|
|
const PAD_SPEED = 150
|
|
@@ -113,8 +114,8 @@ Finally, the process function:
|
|
|
func _process(delta):
|
|
|
|
|
|
Get some useful values for computation. The first is the ball position
|
|
|
-(from the node), the second is the rectangles (Rect2) of the pads.
|
|
|
-Sprites by defaut center the textures, so a small adjustment of size/2
|
|
|
+(from the node), the second is the rectangle (``Rect2``) for each of the pads.
|
|
|
+Sprites center their textures by default, so a small adjustment of ``pad_size / 2``
|
|
|
must be added.
|
|
|
|
|
|
::
|
|
@@ -123,18 +124,18 @@ must be added.
|
|
|
var left_rect = Rect2( get_node("left").get_pos() - pad_size/2, pad_size )
|
|
|
var right_rect = Rect2( get_node("right").get_pos() - pad_size/2, pad_size )
|
|
|
|
|
|
-Since the ball pos was obtained, integrating it should be simple:
|
|
|
+Since the ball position was obtained, integrating it should be simple:
|
|
|
|
|
|
::
|
|
|
|
|
|
- ball_pos+=direction*ball_speed*delta
|
|
|
+ ball_pos += direction * ball_speed * delta
|
|
|
|
|
|
Then, now that the ball has a new position, it should be tested against
|
|
|
everything. First, the floor and the roof:
|
|
|
|
|
|
::
|
|
|
|
|
|
- if ( (ball_pos.y<0 and direction.y <0) or (ball_pos.y>screen_size.y and direction.y>0)):
|
|
|
+ if ( (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0)):
|
|
|
direction.y = -direction.y
|
|
|
|
|
|
If one of the pads was touched, change direction and increase speed a
|
|
@@ -143,19 +144,19 @@ little.
|
|
|
::
|
|
|
|
|
|
if ( (left_rect.has_point(ball_pos) and direction.x < 0) or (right_rect.has_point(ball_pos) and direction.x > 0)):
|
|
|
- direction.x=-direction.x
|
|
|
- ball_speed*=1.1
|
|
|
- direction.y=randf()*2.0-1
|
|
|
+ direction.x = -direction.x
|
|
|
+ ball_speed *= 1.1
|
|
|
+ direction.y = randf() * 2.0 - 1
|
|
|
direction = direction.normalized()
|
|
|
|
|
|
If the ball went out of the screen, it's game over. Game restarts:
|
|
|
|
|
|
::
|
|
|
|
|
|
- if (ball_pos.x<0 or ball_pos.x>screen_size.x):
|
|
|
- ball_pos=screen_size*0.5 #ball goes to screen center
|
|
|
- ball_speed=80
|
|
|
- direction=Vector2(-1,0)
|
|
|
+ if (ball_pos.x < 0 or ball_pos.x > screen_size.x):
|
|
|
+ ball_pos = screen_size * 0.5 # ball goes to screen center
|
|
|
+ ball_speed = 80
|
|
|
+ direction = Vector2(-1, 0)
|
|
|
|
|
|
Once everything was done with the ball, the node is updated with the new
|
|
|
position:
|
|
@@ -164,7 +165,7 @@ position:
|
|
|
|
|
|
get_node("ball").set_pos(ball_pos)
|
|
|
|
|
|
-Only updating the pads according to player input. the Input class is
|
|
|
+Only update the pads according to player input. The Input class is
|
|
|
really useful here:
|
|
|
|
|
|
::
|
|
@@ -173,9 +174,9 @@ really useful here:
|
|
|
var left_pos = get_node("left").get_pos()
|
|
|
|
|
|
if (left_pos.y > 0 and Input.is_action_pressed("left_move_up")):
|
|
|
- left_pos.y+=-PAD_SPEED*delta
|
|
|
+ left_pos.y += -PAD_SPEED * delta
|
|
|
if (left_pos.y < screen_size.y and Input.is_action_pressed("left_move_down")):
|
|
|
- left_pos.y+=PAD_SPEED*delta
|
|
|
+ left_pos.y += PAD_SPEED * delta
|
|
|
|
|
|
get_node("left").set_pos(left_pos)
|
|
|
|
|
@@ -183,9 +184,9 @@ really useful here:
|
|
|
var right_pos = get_node("right").get_pos()
|
|
|
|
|
|
if (right_pos.y > 0 and Input.is_action_pressed("right_move_up")):
|
|
|
- right_pos.y+=-PAD_SPEED*delta
|
|
|
+ right_pos.y += -PAD_SPEED * delta
|
|
|
if (right_pos.y < screen_size.y and Input.is_action_pressed("right_move_down")):
|
|
|
- right_pos.y+=PAD_SPEED*delta
|
|
|
+ right_pos.y += PAD_SPEED * delta
|
|
|
|
|
|
get_node("right").set_pos(right_pos)
|
|
|
|