mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-03 05:48:42 +03:00
Same as before but for other tutorials
Sorry for the big commits with bad logs, it was some really tiresome job :)
This commit is contained in:
@@ -50,11 +50,14 @@ syntax. For example, the syntax to include the page you are reading is
|
||||
Titles
|
||||
~~~~~~
|
||||
|
||||
**TODO: Needs review for Sphinx doc**
|
||||
Please always begin pages with their title and a reference based on the
|
||||
file name (which should ideally be the same as the page title):
|
||||
|
||||
Please always begin pages with their name:
|
||||
::
|
||||
.. _insert_your_title_here:
|
||||
|
||||
``h1. <Insert your title here>``
|
||||
Insert your title here
|
||||
======================
|
||||
|
||||
Also, avoid American CamelCase titles: titles' first word should begin
|
||||
with a capitalized letter, and every following word should not. Thus,
|
||||
|
||||
@@ -99,8 +99,9 @@ memory texture compression format (s3tc, pvrtc, ericsson, etc) by
|
||||
default to improve performance and save resources.
|
||||
|
||||
Since the original textures, 3d file and textues are usually not needed,
|
||||
it's recommended you keep them outside the project. For some hints on
|
||||
how to do this the best way, you can check the :ref:`doc_version_control` tutorial.
|
||||
it's recommended to keep them outside the project. For some hints on
|
||||
how to do this the best way, you can check the :ref:`doc_project_organization`
|
||||
tutorial.
|
||||
|
||||
Two options for textures are provided. They can be copied to the same
|
||||
place as the scene, or they can be copied to a common path (configurable
|
||||
|
||||
@@ -30,9 +30,9 @@ OSX, you can find it in the ~/.android folder).
|
||||
If you can't find it or need to generate one, the keytool command from
|
||||
the JDK can be used for this purpose:
|
||||
|
||||
keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android
|
||||
-keystore debug.keystore -storepass android -dname "CN=Android
|
||||
Debug,O=Android,C=US" -validity 9999
|
||||
::
|
||||
|
||||
keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
|
||||
|
||||
Make sure you have adb
|
||||
----------------------
|
||||
@@ -61,5 +61,3 @@ In that screen, the path to 3 files needs to be set:
|
||||
- The debug *keystore*
|
||||
|
||||
Once that is configured, everything is ready to export to Android!
|
||||
|
||||
|
||||
|
||||
@@ -72,6 +72,5 @@ no longer added to the project, only the engine executable.
|
||||
Services for iOS
|
||||
----------------
|
||||
|
||||
Special iOS services can be used in Godot. Check out the :ref:`doc_services_for_ios` page.
|
||||
|
||||
|
||||
Special iOS services can be used in Godot. Check out the
|
||||
:ref:`doc_services_for_ios` page.
|
||||
|
||||
@@ -14,10 +14,10 @@ are:
|
||||
- Create an atlas for a group of images and crop them, for higher
|
||||
performance and less memory usage.
|
||||
|
||||
Image Export Options
|
||||
Image export options
|
||||
--------------------
|
||||
|
||||
In the `Export Dialog <export>`__, go to the Images tab:
|
||||
In the "Export Dialog", go to the Images tab:
|
||||
|
||||
.. image:: /img/exportimages.png
|
||||
|
||||
@@ -38,7 +38,7 @@ On export, Godot will perform the desired operation. The first export
|
||||
might be really slow, but subsequent exports will be fast, as the
|
||||
converted images will be cached.
|
||||
|
||||
Image Group Export Options
|
||||
Image group export options
|
||||
--------------------------
|
||||
|
||||
This section is similar to the previous one, except it can operate on a
|
||||
@@ -65,5 +65,3 @@ engines, Godot is designed so state changes do not affect it as much).
|
||||
Textures added to an atlas get cropped (empty spaces around the image
|
||||
are removed), so this is another reason to use them (save space). If
|
||||
unsure, though, just leave that option disabled.
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Exporting projects
|
||||
==================
|
||||
|
||||
Why Exporting?
|
||||
Why exporting?
|
||||
--------------
|
||||
|
||||
Originally, Godot did not have any means to export projects. The
|
||||
@@ -35,7 +35,7 @@ does not include tools inside (like the editor, debugger, etc).
|
||||
Finally, Godot has a simple but efficient system for creating DLCs as
|
||||
extra package files.
|
||||
|
||||
On Mobile
|
||||
On mobile
|
||||
~~~~~~~~~
|
||||
|
||||
The same scenario in mobile is a little worse. To distribute a project
|
||||
@@ -54,7 +54,7 @@ compression and that has been standardized for more than a decade, but
|
||||
mobile devices use different formats for texture compression, such as
|
||||
PVRCT (iOS) or ETC (Android)
|
||||
|
||||
Export Dialog
|
||||
Export dialog
|
||||
-------------
|
||||
|
||||
After many attempts at different export workflows, the current one has
|
||||
@@ -81,7 +81,7 @@ export for that platform until he or she resolves it:
|
||||
At that time, the user is expected to come back to the wiki and follow
|
||||
instructions on how to properly set up that platform.
|
||||
|
||||
Export Templates
|
||||
Export templates
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Apart from setting up the platform, the export templates must be
|
||||
@@ -93,7 +93,7 @@ Templates" option in the editor:
|
||||
|
||||
.. image:: /img/exptemp.png
|
||||
|
||||
Export Mode
|
||||
Export mode
|
||||
~~~~~~~~~~~
|
||||
|
||||
When exporting, Godot makes a list of all the files to export and then
|
||||
@@ -125,5 +125,3 @@ creates the package. There are 3 different modes for exporting:
|
||||
*really* useful for games distributed on optical media.
|
||||
|
||||
.. image:: /img/expselected.png
|
||||
|
||||
|
||||
|
||||
@@ -165,5 +165,3 @@ to re-import that asset again, with the ability to change any of the
|
||||
settings.
|
||||
|
||||
.. image:: /img/reimported.png
|
||||
|
||||
|
||||
|
||||
@@ -111,5 +111,3 @@ supported.
|
||||
|
||||
As an alternative, the import screen has a "loop" option that enables
|
||||
looping for the entire sample when importing.
|
||||
|
||||
|
||||
|
||||
@@ -113,5 +113,3 @@ might want to use a super large font, but only to show numbers. For
|
||||
this, he or she writes a numbers.txt file that contains "1234567890",
|
||||
and Godot will only limit itself to import data, thus saving a lot of
|
||||
video memory.
|
||||
|
||||
|
||||
|
||||
@@ -84,5 +84,3 @@ The import dialog also can add the translation to the list of
|
||||
translations to load when the game runs, specified in engine.cfg (or the
|
||||
project properties). Godot allows to load and remove translations at
|
||||
runtime, too.
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Managing image files
|
||||
====================
|
||||
|
||||
If you have read the previous tutorials on :ref:`doc_resources` and
|
||||
:ref:`doc_file_system`, at this point you know that regular image files
|
||||
:ref:`doc_filesystem`, at this point you know that regular image files
|
||||
(.png, .jpg, etc.) are treated as regular resources in Godot.
|
||||
|
||||
Unlike texture resources (.tex files), image files contain no extra
|
||||
@@ -111,5 +111,3 @@ Atlas for a set of images. It is also possible to ask the exporter to
|
||||
scale all images (or selected groups).
|
||||
|
||||
More information on the :ref:`doc_exporting_images` page.
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
One-click deploy
|
||||
================
|
||||
|
||||
Sounds Good, What is it?
|
||||
Sounds good, what is it?
|
||||
------------------------
|
||||
|
||||
This feature will pop up automatically once a platform is properly
|
||||
@@ -19,17 +19,15 @@ the user to automatically export, install and run the project (in debug
|
||||
mode) on the device. This feature is called, in industry buzz-words,
|
||||
"One Click Deploy" (though, it's technically two clicks...).
|
||||
|
||||
Steps for One Click Deploy
|
||||
Steps for one-click deploy
|
||||
--------------------------
|
||||
|
||||
#. Configure target platform.
|
||||
#. Configure device (make sure it's in developer mode, likes the
|
||||
computer, usb is recognized, usb cable is plugged, etc).
|
||||
#. Connect the device..
|
||||
#. And Voila!
|
||||
#. And voila!
|
||||
|
||||
.. image:: /img/oneclick.png
|
||||
|
||||
Click once.. and deploy!
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Filesystem
|
||||
:maxdepth: 1
|
||||
:name: toc-filesystem
|
||||
|
||||
version_control
|
||||
paths
|
||||
saving_your_game
|
||||
project_organization
|
||||
data_paths
|
||||
saving_games
|
||||
encrypting_save_games
|
||||
|
||||
@@ -5,6 +5,6 @@ Game flow
|
||||
:maxdepth: 1
|
||||
:name: toc-game-flow
|
||||
|
||||
pausing_the_game
|
||||
pausing_games
|
||||
background_loading
|
||||
handling_quit_request
|
||||
handling_quit_requests
|
||||
|
||||
@@ -5,4 +5,4 @@ Internationalization
|
||||
:maxdepth: 1
|
||||
:name: toc-i18n
|
||||
|
||||
internationalizing_a_game
|
||||
internationalizing_games
|
||||
|
||||
@@ -50,7 +50,7 @@ so it will take several frames to load.
|
||||
Returns ``OK`` on no errors, ``ERR_FILE_EOF`` when loading is finished.
|
||||
Any other return value means there was an error and loading has stopped.
|
||||
|
||||
Load Progress (optional)
|
||||
Load progress (optional)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To query the progress of the load, use the following methods:
|
||||
@@ -60,31 +60,8 @@ To query the progress of the load, use the following methods:
|
||||
int ResourceInteractiveLoader::get_stage_count() const;
|
||||
int ResourceInteractiveLoader::get_stage() const;
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
get_stage_count
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
returns the total number of stages to load
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
get_stage
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
returns the current stage being loaded
|
||||
``get_stage_count`` returns the total number of stages to load.
|
||||
``get_stage`` returns the current stage being loaded.
|
||||
|
||||
Forcing completion (optional)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -112,74 +89,29 @@ Example
|
||||
This example demostrates how to load a new scene. Consider it in the
|
||||
context of the :ref:`doc_singletons_autoload` example.
|
||||
|
||||
First we setup some variables and initialize the
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
current_scene
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
First we setup some variables and initialize the ``current_scene``
|
||||
with the main scene of the game:
|
||||
|
||||
::
|
||||
|
||||
var loader
|
||||
var wait_frames
|
||||
var time_max = 100 h1. msec
|
||||
var time_max = 100 # msec
|
||||
var current_scene
|
||||
|
||||
func _ready():
|
||||
var root = get_tree().get_root()
|
||||
current_scene = root.get_child( root.get_child_count() -1 )
|
||||
|
||||
The function
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
goto_scene
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
is called from the game when the scene needs to be switched. It requests
|
||||
an interactive loader, and calls
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
set_progress(true)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
to start polling the loader in the
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
_progress
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
current_scene = root.get_child(root.get_child_count() -1)
|
||||
|
||||
The function ``goto_scene`` is called from the game when the scene
|
||||
needs to be switched. It requests an interactive loader, and calls
|
||||
``set_progress(true)`` to start polling the loader in the ``_progress``
|
||||
callback. It also starts a "loading" animation, which can show a
|
||||
progress bar or loading screen, etc.
|
||||
|
||||
::
|
||||
|
||||
func goto_scene(path): h1. game requests to switch to this scene
|
||||
func goto_scene(path): # game requests to switch to this scene
|
||||
loader = ResourceLoader.load_interactive(path)
|
||||
if loader == null: # check for errors
|
||||
show_error()
|
||||
@@ -230,7 +162,7 @@ precise control over the timings.
|
||||
break
|
||||
elif err == OK:
|
||||
update_progress()
|
||||
else: h1. error during loading
|
||||
else: # error during loading
|
||||
show_error()
|
||||
loader = null
|
||||
break
|
||||
@@ -271,8 +203,8 @@ Use a Semaphore
|
||||
While your thread waits for the main thread to request a new resource,
|
||||
use a Semaphore to sleep (instead of a busy loop or anything similar).
|
||||
|
||||
Don't block the main thread during the call to ``poll``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Not blocking main thread during the polling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you have a mutex to allow calls from the main thread to your loader
|
||||
class, don't lock it while you call ``poll`` on the loader. When a
|
||||
@@ -365,4 +297,3 @@ Example:
|
||||
|
||||
**Note**: this code in its current form is not tested in real world
|
||||
scenarios. Ask punto on IRC (#godotengine on irc.freenode.net) for help.
|
||||
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
.. _doc_paths:
|
||||
.. _doc_data_paths:
|
||||
|
||||
Paths
|
||||
=====
|
||||
Data paths
|
||||
==========
|
||||
|
||||
Path Separators
|
||||
Path separators
|
||||
---------------
|
||||
|
||||
For the sake of supporting as many platforms as possible, Godot only
|
||||
accepts unix style path separators (/). These work everywhere,
|
||||
accepts unix style path separators (``/``). These work everywhere,
|
||||
including Windows.
|
||||
|
||||
A path like: "C:\\\\Projects" will become "c:/Projects".
|
||||
A path like: ``C:\Projects`` will become ``C:/Projects``.
|
||||
|
||||
Resource Path
|
||||
Resource path
|
||||
-------------
|
||||
|
||||
As mentioned before. Godot considers that a project exists at any
|
||||
given folder that contains an "engine.cfg" text file, even if such
|
||||
file is empty.
|
||||
|
||||
Accessing project files can be done by opening any path with "res://"
|
||||
Accessing project files can be done by opening any path with ``res://``
|
||||
as a base. For example, a texture located in the root of the project
|
||||
folder may be opened from the following path: "res://sometexture.png".
|
||||
folder may be opened from the following path: ``res://sometexture.png``.
|
||||
|
||||
Userdata Path (Persistent Data)
|
||||
Userdata path (persistent data)
|
||||
-------------------------------
|
||||
|
||||
While the project is running, it is a very common scenario that the
|
||||
@@ -31,7 +31,7 @@ resource path will be read-only, due to it being inside a package,
|
||||
self contained executable, or system wide install location.
|
||||
|
||||
Storing persistent files in such scenarios should be done by using the
|
||||
"user://" prefix, for example: "user://gamesave.txt".
|
||||
``user://`` prefix, for example: ``user://gamesave.txt``.
|
||||
|
||||
In some devices (for example, mobile ad consoles) this path is unique
|
||||
for the app. Under desktop operating systems, the engine uses the
|
||||
@@ -1,6 +1,6 @@
|
||||
.. _doc_encrypting_save_games:
|
||||
|
||||
Encrypting Save Games
|
||||
Encrypting save games
|
||||
=====================
|
||||
|
||||
Why?
|
||||
@@ -32,16 +32,15 @@ encrypt savegames and protect the world order.
|
||||
How?
|
||||
----
|
||||
|
||||
The class :ref:`File <class_File>`
|
||||
is simple to use, just open a location and read/write data (integers,
|
||||
strings and variants). To create an encrypted file, a passphrase must be
|
||||
provided, like this:
|
||||
The class :ref:`File <class_File>` is simple to use, just open a
|
||||
location and read/write data (integers, strings and variants). To create
|
||||
an encrypted file, a passphrase must be provided, like this:
|
||||
|
||||
::
|
||||
|
||||
var f = File.new()
|
||||
var err = f.open_encrypted_with_pass("user://savedata.bin",File.WRITE,"mypass")
|
||||
f.store_var( game_state )
|
||||
var err = f.open_encrypted_with_pass("user://savedata.bin", File.WRITE, "mypass")
|
||||
f.store_var(game_state)
|
||||
f.close()
|
||||
|
||||
This will make the file unreadable to users, but will still not avoid
|
||||
@@ -51,9 +50,8 @@ some unique user identifier is needed, for example:
|
||||
::
|
||||
|
||||
var f = File.new()
|
||||
var err = f.open_encrypted_with_pass("user://savedata.bin",File.WRITE,OS.get_unique_ID())
|
||||
f.store_var( game_state )
|
||||
var err = f.open_encrypted_with_pass("user://savedata.bin", File.WRITE, OS.get_unique_ID())
|
||||
f.store_var(game_state)
|
||||
f.close()
|
||||
|
||||
This is all! Thanks for your cooperation, citizen.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_handling_quit_request:
|
||||
.. _doc_handling_quit_requests:
|
||||
|
||||
Handling Quit Request
|
||||
=====================
|
||||
Handling quit requests
|
||||
======================
|
||||
|
||||
Quitting
|
||||
--------
|
||||
@@ -11,11 +11,10 @@ desktops, this is usually done with the "x" icon on the window titlebar.
|
||||
On Android, the back button is used to quit when on the main screen (and
|
||||
to go back otherwise).
|
||||
|
||||
Handling the Notification
|
||||
Handling the notification
|
||||
-------------------------
|
||||
|
||||
The
|
||||
:ref:`MainLoop <class_MainLoop>`
|
||||
The :ref:`MainLoop <class_MainLoop>`
|
||||
has a special notification that is sent to all nodes when quit is
|
||||
requested: MainLoop.NOTIFICATION_WM_QUIT.
|
||||
|
||||
@@ -24,8 +23,8 @@ Handling it is done as follows (on any node):
|
||||
::
|
||||
|
||||
func _notification(what):
|
||||
if (what==MainLoop.NOTIFICATION_WM_QUIT_REQUEST):
|
||||
get_tree().quit() #default behavior
|
||||
if (what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST):
|
||||
get_tree().quit() # default behavior
|
||||
|
||||
When developing mobile apps, quitting is not desired unless the user is
|
||||
on the main screen, so the behavior can be changed.
|
||||
@@ -36,4 +35,3 @@ behavior to quit when quit is requested, this can be changed:
|
||||
::
|
||||
|
||||
get_tree().set_auto_accept_quit(false)
|
||||
|
||||
@@ -132,7 +132,7 @@ SceneTree (derived from MainLoop) has a method for this:
|
||||
var ev = InputEvent()
|
||||
ev.type=InputEvent.ACTION
|
||||
# set as move_left, pressed
|
||||
ev.set_as_action("move_left",true)
|
||||
ev.set_as_action("move_left", true)
|
||||
# feedback
|
||||
get_tree().input_event(ev)
|
||||
|
||||
@@ -145,6 +145,3 @@ ideal for reassigning or creating different actions at run-time. This
|
||||
singleton is not saved (must be modified manually) and it's state is run
|
||||
from the project settings (engine.cfg). So any dynamic system of this
|
||||
type needs to store settings in the way the programmer sees best fit.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_internationalizing_a_game:
|
||||
.. _doc_internationalizing_games:
|
||||
|
||||
Internationalization
|
||||
====================
|
||||
Internationalizing games
|
||||
========================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@@ -21,18 +21,18 @@ spreadsheets. The process of creating the spreadsheets and importing
|
||||
them is already covered in the :ref:`doc_importing_translations` tutorial, so this
|
||||
one could be seen more like a follow up to that one.
|
||||
|
||||
Configuring the Imported Translation
|
||||
Configuring the imported translation
|
||||
------------------------------------
|
||||
|
||||
The translations can get updated and re-imported when they change, but
|
||||
they still have to be added to the project. This is done in Scene
|
||||
[STRIKEOUT:> Project Settings]> Localization:
|
||||
> Project Settings > Localization:
|
||||
|
||||
.. image:: /img/localization_dialog.png
|
||||
|
||||
This dialog allows to add or remove translations project-wide.
|
||||
|
||||
Localizing Resources
|
||||
Localizing resources
|
||||
--------------------
|
||||
|
||||
It is also possible to instruct Godot to open alternative versions of
|
||||
@@ -44,11 +44,11 @@ assets (resources) depending on the current language. For this the
|
||||
Select the resource to be remapped, and the alternatives for each
|
||||
locale.
|
||||
|
||||
Converting Keys to Text
|
||||
Converting keys to text
|
||||
-----------------------
|
||||
|
||||
Some controls such as :ref:`Button <class_Button>`, :ref:`Label <class_Label>`, etc.
|
||||
will automatically fetch a translation each time they are set a key
|
||||
Some controls such as :ref:`Button <class_Button>`, :ref:`Label <class_Label>`,
|
||||
etc. will automatically fetch a translation each time they are set a key
|
||||
instead of a text. For example, if a label is assigned
|
||||
"MAIN_SCREEN_GREETING1" and a key to different languages exists in the
|
||||
translations, this will be automatically converted. This process is done
|
||||
@@ -56,17 +56,16 @@ upon load though, so if the project in question has a dialog that allows
|
||||
changing the language in the settings, the scenes (or at least the
|
||||
settings scene) will have to be re-loaded for new text to have effect.
|
||||
|
||||
For code, the
|
||||
:ref:`Object.tr() <class_Object_tr>`
|
||||
For code, the :ref:`Object.tr() <class_Object_tr>`
|
||||
function can be used. This will just look-up the text into the
|
||||
translations and convert it if found:
|
||||
|
||||
::
|
||||
|
||||
level.set_text(tr("LEVEL_5_NAME"))
|
||||
status.set_text(tr("GAME_STATUS_"+str(status_index)))
|
||||
status.set_text(tr("GAME_STATUS_" + str(status_index)))
|
||||
|
||||
Making Controls Resizeable
|
||||
Making controls resizeable
|
||||
--------------------------
|
||||
|
||||
The same text in different languages can vary greatly in length. For
|
||||
@@ -79,31 +78,22 @@ TranslationServer
|
||||
-----------------
|
||||
|
||||
Godot has a server for handling the low level translation management
|
||||
called the
|
||||
:ref:`TranslationServer <class_TranslationServer>`.
|
||||
called the :ref:`TranslationServer <class_TranslationServer>`.
|
||||
Translations can be added or removed during run-time, and the current
|
||||
language be changed too.
|
||||
|
||||
Command Line
|
||||
Command line
|
||||
------------
|
||||
|
||||
Language can be tested when running Godot from command line. For
|
||||
example, to test a game in french, the following arguments can be
|
||||
supplied:
|
||||
|
||||
.. raw:: html
|
||||
::
|
||||
|
||||
</pre>
|
||||
c:\MyGame> godot -lang fr
|
||||
|
||||
c:\\\\MyGame> godot -lang fr
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
Translating the Project Name
|
||||
Translating the project name
|
||||
----------------------------
|
||||
|
||||
The project name becomes the app name when exporting to different
|
||||
@@ -115,6 +105,3 @@ application/name and append it the locale identifier. For example:
|
||||
|
||||
As always, If you don't know the code of a language or zone, `check the
|
||||
list :ref:`doc_locales`.
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_mouse_and_input_coordinates:
|
||||
|
||||
Mouse & Input Coordinates
|
||||
=========================
|
||||
Mouse and input coordinates
|
||||
===========================
|
||||
|
||||
About
|
||||
-----
|
||||
@@ -10,30 +10,14 @@ The reason for this small tutorial is to clear up many common mistakes
|
||||
about input coordinates, obtaining mouse position and screen resolution,
|
||||
etc.
|
||||
|
||||
Hardware Display Coordinates
|
||||
Hardware display coordinates
|
||||
----------------------------
|
||||
|
||||
Using hardware coordinates makes sense in the case of writing complex
|
||||
UIs meant to run on PC, such as editors, MMOs, tools, etc. Yet, make not
|
||||
as much sense outside of that scope.
|
||||
UIs meant to run on PC, such as editors, MMOs, tools, etc. Yet, it makes
|
||||
not as much sense outside of that scope.
|
||||
|
||||
[STRIKEOUT:The only way to reliably obtain this information is by using
|
||||
functions such as:]
|
||||
|
||||
**This method is no longer supported:** It was too confusing and caused
|
||||
errors for users making 2D games. Screen would stretch to different
|
||||
resolutions and input would stop making sense. Please use the
|
||||
``_input`` function
|
||||
|
||||
::
|
||||
|
||||
OS.get_video_mode_size()
|
||||
Input.get_mouse_pos()
|
||||
|
||||
However, this is discouraged for pretty much any situation. Please do
|
||||
not use these functions unless you really know what you are doing.
|
||||
|
||||
Viewport Display Coordinates
|
||||
Viewport display coordinates
|
||||
----------------------------
|
||||
|
||||
Godot uses viewports to display content, and viewports can be scaled by
|
||||
@@ -56,11 +40,10 @@ for example:
|
||||
print("Viewport Resolution is: ",get_viewport_rect().size)
|
||||
|
||||
func _ready():
|
||||
set_process_input(true)
|
||||
set_process_input(true)
|
||||
|
||||
Alternatively it's possible to ask the viewport for the mouse position
|
||||
Alternatively it's possible to ask the viewport for the mouse position:
|
||||
|
||||
::
|
||||
|
||||
get_viewport().get_mouse_pos()
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.. _doc_multiple_resolutions:
|
||||
|
||||
Screen Scaling & Multiple Resolutions
|
||||
=====================================
|
||||
Multiple resolutions
|
||||
====================
|
||||
|
||||
Base Resolution
|
||||
Base resolution
|
||||
---------------
|
||||
|
||||
A base screen resolution for the project can be specified in the project
|
||||
@@ -25,8 +25,7 @@ Resizing
|
||||
There are several types of devices, with several types of screens, which
|
||||
in turn have different pixel density and resolutions. Handling all of
|
||||
them can be a lot of work, so Godot tries to make the developer's life a
|
||||
little easier. The
|
||||
:ref:`Viewport <class_Viewport>`
|
||||
little easier. The :ref:`Viewport <class_Viewport>`
|
||||
node has several functions to handle resizing, and the root node of the
|
||||
scene tree is always a viewport (scenes loaded are instanced as a child
|
||||
of it, and it can always be accessed by calling
|
||||
@@ -37,7 +36,7 @@ most flexible way to deal with the problem, it can be a lot of work,
|
||||
code and guessing, so Godot provides a simple set of parameters in the
|
||||
project settings to handle multiple resolutions.
|
||||
|
||||
Stretch Settings
|
||||
Stretch settings
|
||||
----------------
|
||||
|
||||
Stretch settings are located in the project settings, it's just a bunch
|
||||
@@ -45,7 +44,7 @@ of configuration variables that provide several options:
|
||||
|
||||
.. image:: /img/stretchsettings.png
|
||||
|
||||
Stretch Mode
|
||||
Stretch mode
|
||||
------------
|
||||
|
||||
- **Disabled**: The first is the stretch mode. By default this is
|
||||
@@ -67,7 +66,7 @@ Stretch Mode
|
||||
|
||||
.. image:: /img/stretch.png
|
||||
|
||||
Stretch Aspect
|
||||
Stretch aspect
|
||||
--------------
|
||||
|
||||
- **Ignore**: Ignore the aspect ratio when stretching the screen. This
|
||||
@@ -89,6 +88,3 @@ Stretch Aspect
|
||||
reported in the viewport, proportionally). This is usually the best
|
||||
option for 2D games that scroll horizontally (like runners or
|
||||
platformers).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_pausing_the_game:
|
||||
.. _doc_pausing_games:
|
||||
|
||||
Pausing a Game
|
||||
==============
|
||||
Pausing games
|
||||
=============
|
||||
|
||||
Pause?
|
||||
------
|
||||
@@ -16,7 +16,7 @@ Implementing a fine-grained control for what can be paused (and what
|
||||
not) is a lot of work, so a simple framework for pausing is provided in
|
||||
Godot.
|
||||
|
||||
How Pausing Works
|
||||
How pausing works
|
||||
-----------------
|
||||
|
||||
To set pause mode, the pause state must be set. This is done by calling
|
||||
@@ -29,7 +29,7 @@ with a "true" argument:
|
||||
|
||||
Doing so will have the following behavior:
|
||||
|
||||
- 2D and 3D Physics will be stopped.
|
||||
- 2D and 3D physics will be stopped.
|
||||
- _process and _fixed_process will not be called anymore in nodes.
|
||||
- _input and _input_event will not be called anymore either.
|
||||
|
||||
@@ -37,7 +37,7 @@ This effectively stops the whole game. Calling this function from a
|
||||
script, by default, will result in an unrecoverable state (nothing will
|
||||
work anymore!).
|
||||
|
||||
White-Listing Nodes
|
||||
White-listing nodes
|
||||
-------------------
|
||||
|
||||
Before enabling pause, make sure that nodes that must keep working
|
||||
@@ -94,6 +94,3 @@ closed:
|
||||
get_tree().set_pause(false)
|
||||
|
||||
And that should be all!
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_version_control:
|
||||
.. _doc_project_organization:
|
||||
|
||||
Version Control & Project Organization
|
||||
======================================
|
||||
Project organization
|
||||
====================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@@ -24,7 +24,7 @@ browse images, models, sounds, etc. Godot is more scene-based in nature
|
||||
so most of the time the assets are bundled inside the scenes or just
|
||||
exist as files but are referenced from scenes.
|
||||
|
||||
Importing & Game Folder
|
||||
Importing & game folder
|
||||
-----------------------
|
||||
|
||||
It is very often necessary to use asset importing in Godot. As the
|
||||
@@ -69,7 +69,7 @@ Following this layout, many things can be done:
|
||||
other project members, because Godot keeps track of source assets
|
||||
using relative paths.
|
||||
|
||||
Scene Organization
|
||||
Scene organization
|
||||
------------------
|
||||
|
||||
Inside the game folder, a question that often arises is how to organize
|
||||
@@ -123,7 +123,7 @@ settings screen or the valley. Since everything in Godot is done with
|
||||
scenes, and everything that can be named or described can be a scene,
|
||||
this workflow is very smooth and easygoing.
|
||||
|
||||
Cache Files
|
||||
Cache files
|
||||
-----------
|
||||
|
||||
Godot uses a hidden file called ".fscache" at the root of the project.
|
||||
@@ -131,4 +131,3 @@ On it, it caches project files and is used to quickly know when one is
|
||||
modified. Make sure to **not commit this file** to git or svn, as it
|
||||
contains local information and might confuse another editor instance in
|
||||
another computer.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_saving_your_game:
|
||||
.. _doc_saving_games:
|
||||
|
||||
Saving Your Game
|
||||
================
|
||||
Saving games
|
||||
============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@@ -12,7 +12,7 @@ More advanced save games may need to store additional information about
|
||||
an arbitrary number of objects. This will allow the save function to
|
||||
scale as the game grows more complex.
|
||||
|
||||
Identify Persistent Objects
|
||||
Identify persistent objects
|
||||
---------------------------
|
||||
|
||||
First we should identify what objects we want to keep between game
|
||||
@@ -71,14 +71,14 @@ look like this:
|
||||
}
|
||||
return savedict
|
||||
|
||||
This gives us a dictionary with the style {
|
||||
`variable_name <that_variables_value>`__ } which will be useful when
|
||||
This gives us a dictionary with the style
|
||||
``{ "variable_name":that_variables_value }`` which will be useful when
|
||||
loading.
|
||||
|
||||
Saving and reading Data
|
||||
Saving and reading data
|
||||
-----------------------
|
||||
|
||||
As covered in the :ref:`doc_file_system` tutorial, we'll need to open a file
|
||||
As covered in the :ref:`doc_filesystem` tutorial, we'll need to open a file
|
||||
and write to it and then later read from it. Now that we have a way to
|
||||
call our groups and get their relevant data, let's use to_json() to
|
||||
convert it into an easily stored string and store them in a file. Doing
|
||||
@@ -112,7 +112,7 @@ function:
|
||||
if !savegame.file_exists("user://savegame.save"):
|
||||
return #Error! We don't have a save to load
|
||||
|
||||
#We need to revert the game state so we're not cloning objects during loading. This will vary wildly depending on the needs of a project, so take care with this step.
|
||||
# We need to revert the game state so we're not cloning objects during loading. This will vary wildly depending on the needs of a project, so take care with this step.
|
||||
#For our example, we will accomplish this by deleting savable objects.
|
||||
var savenodes = get_tree().get_nodes_in_group("Persist")
|
||||
for i in savenodes:
|
||||
@@ -138,7 +138,7 @@ And now we can save and load an arbitrary number of objects laid out
|
||||
almost anywhere across the scene tree! Each object can store different
|
||||
data depending on what it needs to save.
|
||||
|
||||
Some Notes
|
||||
Some notes
|
||||
----------
|
||||
|
||||
We may have glossed over a step, but setting the game state to one fit
|
||||
@@ -152,5 +152,3 @@ stages (parent objects first) so they are available when child objects
|
||||
are loaded will make sure they're available for the add_child() call.
|
||||
There will also need to be some way to link children to parents as the
|
||||
nodepath will likely be invalid.
|
||||
|
||||
|
||||
@@ -9,9 +9,7 @@ Introduction
|
||||
Godot has a small but very useful feature called viewports. Viewports
|
||||
are, as they name implies, rectangles where the world is drawn. They
|
||||
have three main uses, but can flexibly adapted to a lot more. All this
|
||||
is done via the
|
||||
:ref:`Viewport <class_Viewport>`
|
||||
node.
|
||||
is done via the :ref:`Viewport <class_Viewport>` node.
|
||||
|
||||
.. image:: /img/viewportnode.png
|
||||
|
||||
@@ -21,12 +19,10 @@ The main uses in question are:
|
||||
This is what displays the scenes created by the user. (You should
|
||||
know this by having read previous tutorials!)
|
||||
- **Sub-Viewports**: These can be created when a Viewport is a child of
|
||||
a
|
||||
:ref:`Control <class_Control>`.
|
||||
a :ref:`Control <class_Control>`.
|
||||
- **Render Targets**: Viewports can be set to "RenderTarget" mode. This
|
||||
means that the viewport is not directly visible, but it's contents
|
||||
can be accessed via a
|
||||
:ref:`Texture <class_Texture>`.
|
||||
can be accessed via a :ref:`Texture <class_Texture>`.
|
||||
|
||||
Input
|
||||
-----
|
||||
@@ -35,8 +31,7 @@ Viewports are also responsible of delivering properly adjusted and
|
||||
scaled input events to all it's children nodes. Both the root viewport
|
||||
and sub-viewports do this automatically, but render targets do not.
|
||||
Because of this, the user must do it manually via the
|
||||
:ref:`Viewport.input() <class_Viewport_input>`
|
||||
function if needed.
|
||||
:ref:`Viewport.input() <class_Viewport_input>` function if needed.
|
||||
|
||||
Listener
|
||||
--------
|
||||
@@ -50,11 +45,10 @@ to enable this!
|
||||
Cameras (2D & 3D)
|
||||
-----------------
|
||||
|
||||
When using a 2D or 3D
|
||||
:ref:`Camera <class_Camera>` /
|
||||
:ref:`Camera2D <class_Camera2D>`,
|
||||
cameras will always display on the closest parent viewport (going
|
||||
towards the root). For example, in the following hierarchy:
|
||||
When using a 2D or 3D :ref:`Camera <class_Camera>` /
|
||||
:ref:`Camera2D <class_Camera2D>`, cameras will always display on the
|
||||
closest parent viewport (going towards the root). For example, in the
|
||||
following hierarchy:
|
||||
|
||||
- Viewport
|
||||
|
||||
@@ -76,7 +70,7 @@ or make it the current camera by calling:
|
||||
|
||||
camera.make_current()
|
||||
|
||||
Scale & Stretching
|
||||
Scale & stretching
|
||||
------------------
|
||||
|
||||
Viewports have a "rect" property. X and Y are often not used (only the
|
||||
@@ -100,8 +94,7 @@ settings.
|
||||
Worlds
|
||||
------
|
||||
|
||||
For 3D, a Viewport will contain a
|
||||
:ref:`World <class_World>`. This
|
||||
For 3D, a Viewport will contain a :ref:`World <class_World>`. This
|
||||
is basically, the universe that links physics and rendering together.
|
||||
Spatial-base nodes will register using the World of the closest
|
||||
viewport. By default, newly created viewports do not contain a World but
|
||||
@@ -118,8 +111,7 @@ display single objects and don't want to create a world, viewport has
|
||||
the option to use it's own World. This is very useful when you want to
|
||||
instance 3D characters or objects in the 2D world.
|
||||
|
||||
For 2D, each Viewport always contains it's own
|
||||
:ref:`World2D <class_World2D>`.
|
||||
For 2D, each Viewport always contains it's own :ref:`World2D <class_World2D>`.
|
||||
This suffices in most cases, but in case sharing them may be desired, it
|
||||
is possible to do so by calling the viewport API manually.
|
||||
|
||||
@@ -135,7 +127,7 @@ following API:
|
||||
# queues a screen capture, will not happen immediately
|
||||
viewport.queue_screen_capture()
|
||||
|
||||
After a frame or two (check _process() ), the capture will be ready,
|
||||
After a frame or two (check _process()), the capture will be ready,
|
||||
get it back by using:
|
||||
|
||||
::
|
||||
@@ -145,7 +137,7 @@ get it back by using:
|
||||
If the returned image is empty, capture still didn't happen, wait a
|
||||
little more, as this API is asyncronous.
|
||||
|
||||
Sub-Viewport
|
||||
Sub-viewport
|
||||
------------
|
||||
|
||||
If the viewport is a child of a control, it will become active and
|
||||
@@ -159,7 +151,7 @@ The viewport will cover the area of it's parent control completely.
|
||||
|
||||
.. image:: /img/subviewport.png
|
||||
|
||||
Render Target
|
||||
Render target
|
||||
-------------
|
||||
|
||||
To set as a render target, just toggle the "render target" property of
|
||||
@@ -187,9 +179,6 @@ inside the editor:
|
||||
|
||||
*TODO: Review the doc, ViewportQuad and ViewportFrame don't exist in 2.0.*
|
||||
|
||||
Make sure to check the viewport demos! Viewport folder in the demo.zip
|
||||
available to download, or
|
||||
Make sure to check the viewport demos! Viewport folder in the demos
|
||||
archive available to download, or
|
||||
https://github.com/godotengine/godot/tree/master/demos/viewport
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,25 +1,14 @@
|
||||
.. _doc_http_client_class:
|
||||
|
||||
HTTP client class example
|
||||
=========================
|
||||
HTTP client class
|
||||
=================
|
||||
|
||||
Here's an example of using the
|
||||
:ref:`HTTPClient <class_HTTPClient>`
|
||||
Here's an example of using the :ref:`HTTPClient <class_HTTPClient>`
|
||||
class. It's just a script, so it can be run by executing:
|
||||
|
||||
.. raw:: html
|
||||
::
|
||||
|
||||
</pre>
|
||||
|
||||
c
|
||||
|
||||
c:\\\\godot> godot -s http_test.gd
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
c:\godot> godot -s http_test.gd
|
||||
|
||||
It will connect and fetch a website.
|
||||
|
||||
@@ -109,6 +98,4 @@ It will connect and fetch a website.
|
||||
print("Text: ",text)
|
||||
|
||||
|
||||
quit()
|
||||
|
||||
|
||||
quit()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_matrices_and_transforms:
|
||||
|
||||
Matrices & Transforms
|
||||
=====================
|
||||
Matrices and transforms
|
||||
=======================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@@ -15,7 +15,7 @@ about matrices (but not in-depth).
|
||||
Transformations are most of the time applied as translation, rotation
|
||||
and scale so they will be considered as priority here.
|
||||
|
||||
Oriented Coordinate System (OCS)
|
||||
Oriented coordinate system (OCS)
|
||||
--------------------------------
|
||||
|
||||
Imagine we have a spaceship somewhere in space. In Godot this is easy,
|
||||
@@ -272,7 +272,7 @@ Post - multiplying is also valid:
|
||||
|
||||
var new_pos = m * pos
|
||||
|
||||
Inverse Transform
|
||||
Inverse transform
|
||||
-----------------
|
||||
|
||||
To do the opposite operation (what we did up there with the rocket), the
|
||||
@@ -294,7 +294,7 @@ Or pre-multiplication:
|
||||
|
||||
var new_pos = pos * m
|
||||
|
||||
Orthonormal Matrices
|
||||
Orthonormal matrices
|
||||
--------------------
|
||||
|
||||
However, if the Matrix has been scaled (vectors are not unit length),
|
||||
@@ -312,7 +312,7 @@ the position unchanged:
|
||||
# Does nothing, pos is unchanged
|
||||
pos = Matrix32().xform(pos)
|
||||
|
||||
Affine Inverse
|
||||
Affine inverse
|
||||
--------------
|
||||
|
||||
The affine inverse is a matrix that does the inverse operation of
|
||||
@@ -325,18 +325,18 @@ affine_inverse() method:
|
||||
var mi = m.affine_inverse()
|
||||
var pos = m.xform(pos)
|
||||
pos = mi.xform(pos)
|
||||
#pos is unchanged
|
||||
# pos is unchanged
|
||||
|
||||
If the matrix is orthonormal, then:
|
||||
|
||||
::
|
||||
|
||||
#if m is orthonormal, then
|
||||
# if m is orthonormal, then
|
||||
pos = mi.xform(pos)
|
||||
#is the same is
|
||||
# is the same is
|
||||
pos = m.xform_inv(pos)
|
||||
|
||||
Matrix Multiplication
|
||||
Matrix multiplication
|
||||
---------------------
|
||||
|
||||
Matrices can be multiplied. Multiplication of two matrices "chains"
|
||||
@@ -362,7 +362,7 @@ Is the same as:
|
||||
|
||||
::
|
||||
|
||||
h1. note the inverse order
|
||||
# note the inverse order
|
||||
pos = (transform2 * transform1).xform(pos)
|
||||
|
||||
However, this is not the same:
|
||||
@@ -374,7 +374,7 @@ However, this is not the same:
|
||||
|
||||
Because in matrix math, A + B is not the same as B + A.
|
||||
|
||||
Multiplication by Inverse
|
||||
Multiplication by inverse
|
||||
-------------------------
|
||||
|
||||
Multiplying a matrix by it's inverse, results in identity
|
||||
@@ -384,14 +384,14 @@ Multiplying a matrix by it's inverse, results in identity
|
||||
# No matter what A is, B will be identity
|
||||
B = A.affine_inverse() * A
|
||||
|
||||
Multiplication by Identity
|
||||
Multiplication by identity
|
||||
--------------------------
|
||||
|
||||
Multiplying a matrix by identity, will result in the unchanged matrix:
|
||||
|
||||
::
|
||||
|
||||
h1. B will be equal to A
|
||||
# B will be equal to A
|
||||
B = A * Matrix32()
|
||||
|
||||
Matrix tips
|
||||
@@ -429,36 +429,34 @@ Revert it just like the example above:
|
||||
OK, hopefully this should be enough! Let's complete the tutorial by
|
||||
moving to 3D matrices
|
||||
|
||||
Matrices & Transforms in 3D
|
||||
Matrices & transforms in 3D
|
||||
---------------------------
|
||||
|
||||
As mentioned before, for 3D, we deal with 3
|
||||
:ref:`Vector3 <class_Vector3>`
|
||||
As mentioned before, for 3D, we deal with 3 :ref:`Vector3 <class_Vector3>`
|
||||
vectors for the rotation matrix, and an extra one for the origin.
|
||||
|
||||
Matrix3
|
||||
-------
|
||||
|
||||
Godot has a special type for a 3x3 matrix, named
|
||||
:ref:`Matrix3 <class_Matrix3>`. It
|
||||
can be used to represent a 3D rotation and scale. Sub vectors can be
|
||||
Godot has a special type for a 3x3 matrix, named :ref:`Matrix3 <class_Matrix3>`.
|
||||
It can be used to represent a 3D rotation and scale. Sub vectors can be
|
||||
accessed as:
|
||||
|
||||
::
|
||||
|
||||
var m = Matrix3()
|
||||
var x = m[0] h1. Vector3
|
||||
var y = m[1] h1. Vector3
|
||||
var z = m[2] h1. Vector3
|
||||
var x = m[0] # Vector3
|
||||
var y = m[1] # Vector3
|
||||
var z = m[2] # Vector3
|
||||
|
||||
or, alternatively as:
|
||||
|
||||
::
|
||||
|
||||
var m = Matrix3()
|
||||
var x = m.x h1. Vector3
|
||||
var y = m.y h1. Vector3
|
||||
var z = m.z h1. Vector3
|
||||
var x = m.x # Vector3
|
||||
var y = m.y # Vector3
|
||||
var z = m.z # Vector3
|
||||
|
||||
Matrix3 is also initialized to Identity by default:
|
||||
|
||||
@@ -484,13 +482,10 @@ Transform
|
||||
---------
|
||||
|
||||
To add the final component to the mix, Godot provides the
|
||||
:ref:`Transform <class_Transform>`
|
||||
type. Transform has two members:
|
||||
:ref:`Transform <class_Transform>` type. Transform has two members:
|
||||
|
||||
- *basis* (of type
|
||||
:ref:`Matrix3 <class_Matrix3>`
|
||||
- *origin* (of type
|
||||
:ref:`Vector3 <class_Vector3>`
|
||||
- *basis* (of type :ref:`Matrix3 <class_Matrix3>`
|
||||
- *origin* (of type :ref:`Vector3 <class_Vector3>`
|
||||
|
||||
Any 3D transform can be represented with Transform, and the separation
|
||||
of basis and origin makes it easier to work translation and rotation
|
||||
@@ -501,8 +496,6 @@ An example:
|
||||
::
|
||||
|
||||
var t = Transform()
|
||||
pos = t.xform(pos) #transform 3D position
|
||||
pos = t.basis.xform(pos) h1. (only rotate)
|
||||
pos = t.xform(pos) # transform 3D position
|
||||
pos = t.basis.xform(pos) # (only rotate)
|
||||
pos = t.origin + pos (only translate)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_ray-casting:
|
||||
|
||||
Physics Ray Casting and Queries (2D and 3D)
|
||||
===========================================
|
||||
Ray-casting
|
||||
===========
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. _doc_ssl_certificates:
|
||||
|
||||
SSL Certificates
|
||||
SSL certificates
|
||||
================
|
||||
|
||||
Introduction
|
||||
@@ -28,7 +28,7 @@ this when exporting your project.
|
||||
|
||||
There are two ways to obtain certificates:
|
||||
|
||||
Approach 1, Self Signed Cert
|
||||
Approach 1: self signed cert
|
||||
----------------------------
|
||||
|
||||
The first approach is the simplest, just generate a private and public
|
||||
@@ -41,7 +41,7 @@ this. This approach also **does not require domain validation** nor
|
||||
requires you to spend a considerable amount of money in purchasing
|
||||
certificates from a CA.
|
||||
|
||||
Approach 2, CA Cert
|
||||
Approach 2: CA cert
|
||||
-------------------
|
||||
|
||||
The second approach consists of using a certificate authority (CA)
|
||||
@@ -65,11 +65,8 @@ located in:
|
||||
|
||||
/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
This file allows HTTPS connections to virtually any website (ie, Google,
|
||||
Microsoft, etc) .
|
||||
This file allows HTTPS connections to virtually any website (i.e.,
|
||||
Google, Microsoft, etc.).
|
||||
|
||||
Or just pick any of the more specific certificates there if you are
|
||||
connecting to a specific one.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,6 @@ Learning step by step
|
||||
splash_screen
|
||||
animations
|
||||
resources
|
||||
file_system
|
||||
filesystem
|
||||
scene_tree
|
||||
singletons_autoload
|
||||
|
||||
@@ -13,11 +13,10 @@ To begin, let's just use the scene from the previous tutorial (splash
|
||||
screen). The goal will be to add a simple animation to it. Here's a copy
|
||||
just in case: :download:`robisplash.zip </files/robisplash.zip>`.
|
||||
|
||||
Creating the Animation
|
||||
Creating the animation
|
||||
----------------------
|
||||
|
||||
First of all, add an
|
||||
:ref:`AnimationPlayer <class_AnimationPlayer>`
|
||||
First of all, add an :ref:`AnimationPlayer <class_AnimationPlayer>`
|
||||
node to the scene, make it a child of bg (the root node):
|
||||
|
||||
.. image:: /img/animplayer.png
|
||||
@@ -37,7 +36,7 @@ pressing the "edit" button:
|
||||
|
||||
.. image:: /img/animedit.png
|
||||
|
||||
Editing the Animation
|
||||
Editing the animation
|
||||
---------------------
|
||||
|
||||
Now this is when the magic happens! Several things happen when the
|
||||
@@ -53,7 +52,7 @@ property of any object* can be animated:
|
||||
|
||||
.. image:: /img/propertykeys.png
|
||||
|
||||
Making the Logo Appear
|
||||
Making the logo appear
|
||||
----------------------
|
||||
|
||||
Next, the logo will appear from the top of the screen. After selecting
|
||||
@@ -94,6 +93,3 @@ And finally, when running the scene, the animation should look like
|
||||
this:
|
||||
|
||||
.. image:: /img/out.gif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. _doc_file_system:
|
||||
.. _doc_filesystem:
|
||||
|
||||
Filesystem
|
||||
==========
|
||||
@@ -52,23 +52,23 @@ Example of a filesystem:
|
||||
/enemy/enemysprite.png
|
||||
/player/player.gd
|
||||
|
||||
Directory Delimiter
|
||||
Directory delimiter
|
||||
-------------------
|
||||
|
||||
Godot only supports "/" as a directory delimiter. This is done for
|
||||
Godot only supports ``/`` as a directory delimiter. This is done for
|
||||
portability reasons. All operating systems support this, even Windows,
|
||||
so a path such as c:\\\\project\\\\engine.cfg needs to be typed as
|
||||
c:/project/engine.cfg.
|
||||
so a path such as ``c:\project\engine.cfg`` needs to be typed as
|
||||
``c:/project/engine.cfg``.
|
||||
|
||||
Resource Path
|
||||
Resource path
|
||||
-------------
|
||||
|
||||
For accessing resources, using the host OS filesystem layout can be
|
||||
cumbersome and non portable. To solve this problem, the specal path
|
||||
\`"res://"\` was created.
|
||||
``res://`` was created.
|
||||
|
||||
The path \`"res://"\` will always point at the project root (where
|
||||
engine.cfg is located, so in fact \`"res://engine.cfg"\` is always
|
||||
The path ``res://`` will always point at the project root (where
|
||||
engine.cfg is located, so in fact ``res://engine.cfg`` is always
|
||||
valid).
|
||||
|
||||
This filesystem is read-write only when running the project locally from
|
||||
@@ -76,14 +76,14 @@ the editor. When exported or when running on different devices (such as
|
||||
phones or consoles, or running from DVD), the filesystem will become
|
||||
read-only and writing will no longer be permitted.
|
||||
|
||||
User Path
|
||||
User path
|
||||
---------
|
||||
|
||||
Writing to disk is still needed often, from doing a savegame to
|
||||
downloading content packs. For this, the engine ensures that there is a
|
||||
special path \`"user://"\` that is always writable.
|
||||
special path ``user://`` that is always writable.
|
||||
|
||||
Host Filesystem
|
||||
Host filesystem
|
||||
---------------
|
||||
|
||||
Of course, opening the host filesystem always works, as this is always
|
||||
@@ -108,4 +108,3 @@ for files.
|
||||
|
||||
Because of this, please instruct your team to use a specific naming
|
||||
convention for files when working with Godot!
|
||||
|
||||
@@ -34,8 +34,7 @@ animators.
|
||||
Control
|
||||
~~~~~~~
|
||||
|
||||
The basic node for UI elements is
|
||||
:ref:`Control <class_Control>`
|
||||
The basic node for UI elements is :ref:`Control <class_Control>`
|
||||
(sometimes called "Widget" or "Box" in other toolkits). Every node that
|
||||
provides user interface functionality descends from it.
|
||||
|
||||
@@ -44,7 +43,7 @@ it's coordinates (position, size) are always relative to the parent.
|
||||
This sets the basis for editing complex user interface quickly and
|
||||
visually.
|
||||
|
||||
Input and Drawing
|
||||
Input and drawing
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Controls receive input events by means of the
|
||||
@@ -52,8 +51,7 @@ Controls receive input events by means of the
|
||||
callback. Only one control, the one in focus, will receive
|
||||
keyboard/joypad events (see
|
||||
:ref:`Control.set_focus_mode() <class_Control_set_focus_mode>`
|
||||
and
|
||||
:ref:`Control.grab_focus() <class_Control_grab_focus>`.
|
||||
and :ref:`Control.grab_focus() <class_Control_grab_focus>`.
|
||||
|
||||
Mouse Motion events are received by the control directly below the mouse
|
||||
pointer. When a control receives a mouse button pressed event, all
|
||||
@@ -74,13 +72,11 @@ In general though, the programmer does not need to deal with drawing and
|
||||
input events directly when building UIs, (that is more useful when
|
||||
creating custom controls). Instead, controls emit different kinds of
|
||||
signals with contextural information for when action occurs. For
|
||||
example, a
|
||||
:ref:`Button <class_Button>` emits
|
||||
a "pressed" signal when pressed, a
|
||||
:ref:`Slider <class_Slider>` will
|
||||
example, a :ref:`Button <class_Button>` emits
|
||||
a "pressed" signal when pressed, a :ref:`Slider <class_Slider>` will
|
||||
emit a "value_changed" when dragged, etc.
|
||||
|
||||
Custom Control Mini Tutorial
|
||||
Custom control mini tutorial
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Before going into more depth, creating a custom control will be a good
|
||||
@@ -126,7 +122,7 @@ how most controls work internally.
|
||||
|
||||
.. image:: /img/ctrl_tapped.png
|
||||
|
||||
UI Complexity
|
||||
UI complexity
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
As mentioned before, Godot includes dozens of controls ready for using
|
||||
@@ -137,22 +133,20 @@ meant for complex user interfaces and uniform skinning trough styles. A
|
||||
description is presented as follows to help understand which one should
|
||||
be used in which case.
|
||||
|
||||
Simplified UI Controls
|
||||
Simplified UI controls
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This set of controls is enough for most games, where complex
|
||||
interactions or ways to present information are not necessary. The can
|
||||
be skinned easily with regular textures.
|
||||
|
||||
- :ref:`Label <class_Label>` :
|
||||
Node used for showing text.
|
||||
- :ref:`TextureFrame <class_TextureFrame>`
|
||||
: Displays a single texture, which can be scaled or kept fixed.
|
||||
- :ref:`TextureButton <class_TextureButton>`
|
||||
: Displays a simple texture buttons, states such as pressed, hover,
|
||||
disabled, etc can be set.
|
||||
- :ref:`TextureProgress <class_TextureProgress>`
|
||||
: Displays a single textured progress bar.
|
||||
- :ref:`Label <class_Label>`: Node used for showing text.
|
||||
- :ref:`TextureFrame <class_TextureFrame>`: Displays a single texture,
|
||||
which can be scaled or kept fixed.
|
||||
- :ref:`TextureButton <class_TextureButton>`: Displays a simple texture
|
||||
buttons, states such as pressed, hover, disabled, etc. can be set.
|
||||
- :ref:`TextureProgress <class_TextureProgress>`: Displays a single
|
||||
textured progress bar.
|
||||
|
||||
Additionally, re-positioning of controls is most efficiently done with
|
||||
anchors in this case (see the :ref:`doc_size_and_anchors` tutorial for more
|
||||
@@ -162,12 +156,11 @@ In any case, it will happen often that even for simple games, more
|
||||
complex UI behaviors will be required. An example of this is a scrolling
|
||||
list of elements (for a high score table, for example), which needs a
|
||||
:ref:`ScrollContainer <class_ScrollContainer>`
|
||||
and a
|
||||
:ref:`VBoxContainer <class_VBoxContainer>`.
|
||||
and a :ref:`VBoxContainer <class_VBoxContainer>`.
|
||||
These kind of more advanced controls can be mixed with the regular ones
|
||||
seamlessly (they are all controls anyway).
|
||||
|
||||
Complex UI Controls
|
||||
Complex UI controls
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The rest of the controls (and there are dozens of them!) are meant for
|
||||
@@ -181,6 +174,3 @@ another set of scenarios, most commonly:
|
||||
Re-positioning controls for these kind of interfaces is more commonly
|
||||
done with containers (see the :ref:`doc_size_and_anchors` tutorial for more
|
||||
info).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ In the above picture, Scene B was added to Scene A as an instance. It
|
||||
may seem weird at first, but at the end of this tutorial it will make
|
||||
complete sense!
|
||||
|
||||
Instancing, Step by Step
|
||||
Instancing, step by step
|
||||
------------------------
|
||||
|
||||
To learn how to do instancing, let's start with downloading a sample
|
||||
@@ -76,7 +76,7 @@ Press Play and Voila!
|
||||
|
||||
The instanced ball fell to the bottom of the pit.
|
||||
|
||||
A Little More
|
||||
A little more
|
||||
-------------
|
||||
|
||||
There can be as many instances as desired in a scene, just try
|
||||
@@ -90,7 +90,7 @@ Then try running the scene again:
|
||||
|
||||
Cool, huh? This is how instancing works.
|
||||
|
||||
Editing Instances
|
||||
Editing instances
|
||||
-----------------
|
||||
|
||||
Select one of the many copies of the balls and go to the property
|
||||
@@ -111,6 +111,3 @@ Conclusion
|
||||
|
||||
Instancing seems handy, but there is more to it than it meets the eye!
|
||||
The next part of the instancing tutorial should cover the rest..
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Instancing has many handy uses. At a glance, with instancing you have:
|
||||
- A way to design more complex game flows or even UIs (UI Elements are
|
||||
nodes in Godot too).
|
||||
|
||||
Design Language
|
||||
Design language
|
||||
---------------
|
||||
|
||||
But the real strong point of instancing scenes is that it works as an
|
||||
@@ -66,7 +66,7 @@ operated by non programmers too, so an usual team development process
|
||||
involves 3D or 2D artists, level designers, game designers, animators,
|
||||
etc all working with the editor interface.
|
||||
|
||||
Information Overload!
|
||||
Information overload!
|
||||
---------------------
|
||||
|
||||
Do not worry to much, the important part of this tutorial is to create
|
||||
@@ -75,6 +75,3 @@ way to understand all this is to make some games.
|
||||
|
||||
Everything will become very obvious when put to practice, so, please do
|
||||
not scratch your head and go on to the next tutorial!
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Resources
|
||||
=========
|
||||
|
||||
Nodes and Resources
|
||||
Nodes and resources
|
||||
-------------------
|
||||
|
||||
So far, :ref:`Node <class_Node>`
|
||||
@@ -48,17 +48,14 @@ To make it a litle more visual:
|
||||
|
||||
.. image:: /img/nodes_resources.png
|
||||
|
||||
External vs Built-In
|
||||
External vs built-in
|
||||
--------------------
|
||||
|
||||
The resource properties can reference resources in two ways,
|
||||
*external* (on disk) or **built-in**.
|
||||
|
||||
To be more specific, here's a
|
||||
:ref:`Texture <class_Texture>`
|
||||
in a
|
||||
:ref:`Sprite <class_Sprite>`
|
||||
node:
|
||||
To be more specific, here's a :ref:`Texture <class_Texture>`
|
||||
in a :ref:`Sprite <class_Sprite>` node:
|
||||
|
||||
.. image:: /img/spriteprop.png
|
||||
|
||||
@@ -80,7 +77,7 @@ the scene can be instanced multiple times, the resource will still
|
||||
always be loaded once. That means, different Robi robot scenes instanced
|
||||
at the same time will still share the same image.
|
||||
|
||||
Loading Resources from Code
|
||||
Loading resources from code
|
||||
---------------------------
|
||||
|
||||
Loading resources from code is easy, there are two ways to do it. The
|
||||
@@ -89,7 +86,7 @@ first is to use load(), like this:
|
||||
::
|
||||
|
||||
func _ready():
|
||||
var res = load("res://robi.png") h1. resource is loaded when line is executed
|
||||
var res = load("res://robi.png") # resource is loaded when line is executed
|
||||
get_node("sprite").set_texture(res)
|
||||
|
||||
The second way is more optimal, but only works with a string constant
|
||||
@@ -98,15 +95,14 @@ parameter, because it loads the resource at compile-time.
|
||||
::
|
||||
|
||||
func _ready():
|
||||
var res = preload("res://robi.png") h1. resource is loaded at compile time
|
||||
var res = preload("res://robi.png") # resource is loaded at compile time
|
||||
get_node("sprite").set_texture(res)
|
||||
|
||||
Loading Scenes
|
||||
Loading scenes
|
||||
--------------
|
||||
|
||||
Scenes are also resources, but there is a catch. Scenes saved to disk
|
||||
are resources of type
|
||||
:ref:`PackedScene <class_PackedScene>`,
|
||||
are resources of type :ref:`PackedScene <class_PackedScene>`,
|
||||
this means that the scene is packed inside a resource.
|
||||
|
||||
To obtain an instance of the scene, the method
|
||||
@@ -131,11 +127,10 @@ removed quickly, without having to load them again from disk each
|
||||
time. It is important to remember that, as always, images, meshes, etc
|
||||
are all shared between the scene instances.
|
||||
|
||||
Freeing Resources
|
||||
Freeing resources
|
||||
-----------------
|
||||
|
||||
Resource extends from
|
||||
:ref:`Reference <class_Reference>`.
|
||||
Resource extends from :ref:`Reference <class_Reference>`.
|
||||
As such, when a resource is no longer in use, it will automatically free
|
||||
itelf. Since, in most cases, Resources are contained in Nodes, scripts
|
||||
or other resources, when a node is removed or freed, all the children
|
||||
@@ -144,9 +139,6 @@ resources are freed too.
|
||||
Scripting
|
||||
---------
|
||||
|
||||
Like any object in Godot, not just nodes, Resources can be scripted too.
|
||||
Like any object in Godot, not just nodes, resources can be scripted too.
|
||||
However, there isn't generally much of a win, as resources are just data
|
||||
containers.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ there's not really more depth than this.
|
||||
|
||||
In previous tutorials, everything revolves around the concept of
|
||||
Nodes, scenes are made of them, and they become active once they enter
|
||||
the *Scene Tree*.
|
||||
the *scene tree*.
|
||||
|
||||
This deserves going a little more into depth. In fact, the scene system
|
||||
is not even a core component of Godot, as it is possible to skip it and
|
||||
@@ -27,10 +27,8 @@ The way Godot works internally is as follows. There is the the
|
||||
which is the only instance that runs at the beginning. Afterwards, all
|
||||
drivers, servers, scripting languages, scene system, etc are loaded.
|
||||
|
||||
When initialization is complete,
|
||||
:ref:`OS <class_OS>` needs to be
|
||||
supplied a
|
||||
:ref:`MainLoop <class_MainLoop>`
|
||||
When initialization is complete, :ref:`OS <class_OS>` needs to be
|
||||
supplied a :ref:`MainLoop <class_MainLoop>`
|
||||
to run. Up to this point, all this is internals working (you can check
|
||||
main/main.cpp file in the source code if you are ever interested to
|
||||
see how this works internally).
|
||||
@@ -47,9 +45,8 @@ SceneTree
|
||||
One of the ways to explain how Godot works, is that it's a high level
|
||||
game engine over a low level middleware.
|
||||
|
||||
The scene system is the game engine, while the
|
||||
:ref:`OS <class_OS>` and servers
|
||||
are the low level API.
|
||||
The scene system is the game engine, while the :ref:`OS <class_OS>`
|
||||
and servers are the low level API.
|
||||
|
||||
In any case, the scene system provides it's own main loop to OS,
|
||||
:ref:`SceneTree <class_SceneTree>`.
|
||||
@@ -60,8 +57,7 @@ to do any extra work.
|
||||
It's important to know that this class exists because it has a few
|
||||
important uses:
|
||||
|
||||
- It contains the root
|
||||
:ref:`Viewport <class_Viewport>`,
|
||||
- It contains the root :ref:`Viewport <class_Viewport>`,
|
||||
when a scene is first opened, it's added as a child of it to become
|
||||
part of the *Scene Tree* (more on that next)
|
||||
- It contains information about the groups, and has means to call all
|
||||
@@ -74,11 +70,10 @@ When a node is part of the Scene Tree, the
|
||||
singleton can be obtained by simply calling
|
||||
:ref:`Node.get_tree() <class_Node_get_tree>`.
|
||||
|
||||
Root Viewport
|
||||
Root viewport
|
||||
-------------
|
||||
|
||||
The root
|
||||
:ref:`Viewport <class_Viewport>`
|
||||
The root :ref:`Viewport <class_Viewport>`
|
||||
is always a top of the scene. From a node, it can be obtained in two
|
||||
different ways:
|
||||
|
||||
@@ -96,11 +91,11 @@ While other viewports can be created in the scene (for split-screen
|
||||
effects and such), this one is the only one that is never created by the
|
||||
user. It's created automatically inside SceneTree.
|
||||
|
||||
Scene Tree
|
||||
Scene tree
|
||||
----------
|
||||
|
||||
When a node is connected, directly or indirectly, to the root
|
||||
viewport, it becomes part of the *Scene Tree*.
|
||||
viewport, it becomes part of the *scene tree*.
|
||||
|
||||
This means that, as explained in previous tutorials, will get the
|
||||
_enter_tree() and _ready() callbacks (as well as _exit_tree()).
|
||||
@@ -110,9 +105,9 @@ _enter_tree() and _ready() callbacks (as well as _exit_tree()).
|
||||
When nodes enter the *Scene Tree*, they become active. They get access
|
||||
to everything they need to process, get input, display 2D and 3D,
|
||||
notifications, play sound, groups, etc. When they are removed from the
|
||||
*Scene Tree*, they lose it.
|
||||
*scene tree*, they lose it.
|
||||
|
||||
Tree Order
|
||||
Tree order
|
||||
----------
|
||||
|
||||
Most node operations in Godot, such as drawing 2D, processing or getting
|
||||
@@ -121,8 +116,8 @@ siblings with less order will get notified before the current node.
|
||||
|
||||
.. image:: /img/toptobottom.png
|
||||
|
||||
"Becoming Active" by entering the *Scene Tree* In Detail
|
||||
--------------------------------------------------------
|
||||
"Becoming active" by entering the *Scene Tree*
|
||||
----------------------------------------------
|
||||
|
||||
#. A scene is loaded from disk or created by scripting.
|
||||
#. The root node of that scene (only one root, remember?) is added as
|
||||
@@ -138,7 +133,7 @@ siblings with less order will get notified before the current node.
|
||||
scene" notification ( _exit_tree() callback in GDScript) in
|
||||
bottom-to-top order
|
||||
|
||||
Changing Current Scene
|
||||
Changing current scene
|
||||
----------------------
|
||||
|
||||
After a scene is loaded, it is often desired to change this scene for
|
||||
@@ -157,6 +152,3 @@ some point in your game, it may be desired to create proper loading
|
||||
screens with progress bar, animated indicators or thread (background)
|
||||
loading. This must be done manually using autoloads (see next chapter!)
|
||||
and :ref:`doc_background_loading`.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ tools for editing 2D and 3D scenes as well as user interfaces, but all
|
||||
the editor revolves around the concept of editing a scene and the nodes
|
||||
that compose it.
|
||||
|
||||
Creating New Project
|
||||
--------------------
|
||||
Creating a new project
|
||||
----------------------
|
||||
|
||||
Theory is boring, so let's change subject and go practical. Following a
|
||||
long tradition in tutorials, the first project will be a hello world.
|
||||
@@ -138,7 +138,7 @@ the top bar (or hit F6):
|
||||
|
||||
.. image:: /img/playscene.png
|
||||
|
||||
Aaaand.. Oops.
|
||||
Aaaand... Oops.
|
||||
|
||||
.. image:: /img/neversaved.png
|
||||
|
||||
@@ -162,7 +162,7 @@ demo should finally execute:
|
||||
|
||||
Success!
|
||||
|
||||
Configuring the Project
|
||||
Configuring the project
|
||||
-----------------------
|
||||
|
||||
Ok, It's time to do some configuration to the project. Right now, the
|
||||
@@ -200,15 +200,11 @@ remembered.
|
||||
As a side note, for future reference and a little out of context (this
|
||||
is the first tutorial after all!), it is also possible to add custom
|
||||
configuration options and read them in run-time using the
|
||||
:ref:`Globals <class_Globals>`
|
||||
singleton.
|
||||
:ref:`Globals <class_Globals>` singleton.
|
||||
|
||||
To Be Continued...
|
||||
To be continued...
|
||||
------------------
|
||||
|
||||
This tutorial talks about "Scenes and Nodes", but so far there has been
|
||||
This tutorial talks about "scenes and nodes", but so far there has been
|
||||
only *one* scene and *one* node! Don't worry, the next tutorial will
|
||||
deal with that...
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -64,14 +64,14 @@ rewritten in C++ and exposed transparently to the script. This allows
|
||||
for replacing a GDScript class with a C++ class without altering the
|
||||
rest of the game.
|
||||
|
||||
Scripting a Scene
|
||||
Scripting a scene
|
||||
-----------------
|
||||
|
||||
Before continuing, please make sure to read the :ref:`doc_gdscript` reference.
|
||||
It's a simple language and the reference is short, should not take more
|
||||
than a few minutes to glance.
|
||||
|
||||
Scene Setup
|
||||
Scene setup
|
||||
~~~~~~~~~~~
|
||||
|
||||
This tutorial will begin by scripting a simple GUI scene. Use the add
|
||||
@@ -91,7 +91,7 @@ And try to make it look like this in the 2D editor, so it makes sense:
|
||||
|
||||
Finally, save the scene, a fitting name could be "sayhello.scn"
|
||||
|
||||
Adding a Script
|
||||
Adding a script
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Select the Panel node, then press the "Add Script" Icon as follows:
|
||||
@@ -125,7 +125,7 @@ There is not much in there. The "_ready()" function is called when the
|
||||
node (and all it's children) entered the active scene. (Remember, It's
|
||||
not a constructor, the constructor is "_init()" ).
|
||||
|
||||
The Role of the Script
|
||||
The role of the script
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A script basically adds a behavior to a node. It is used to control the
|
||||
@@ -136,7 +136,7 @@ script.
|
||||
|
||||
.. image:: /img/brainslug.jpg
|
||||
|
||||
Handling a Signal
|
||||
Handling a signal
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Signals are used mostly in GUI nodes, (although other nodes have them
|
||||
@@ -226,6 +226,3 @@ to obtain it would be:
|
||||
|
||||
And, also, try to remember that nodes are referenced by name, not by
|
||||
type.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ processing.
|
||||
|
||||
Idle processing is activated with the
|
||||
:ref:`Node.set_process() <class_Node_set_process>`
|
||||
function. Once active, the
|
||||
:ref:`Node._process() <class_Node__process>`
|
||||
function. Once active, the :ref:`Node._process() <class_Node__process>`
|
||||
callback will be called every frame. Example:
|
||||
|
||||
::
|
||||
@@ -26,7 +25,7 @@ callback will be called every frame. Example:
|
||||
set_process(true)
|
||||
|
||||
func _process(delta):
|
||||
#do something..
|
||||
# do something..
|
||||
|
||||
The delta parameter describes the time elapsed (in seconds, as
|
||||
floating point) since the previous call to _process().
|
||||
@@ -46,7 +45,7 @@ with the following script:
|
||||
set_process(true)
|
||||
|
||||
func _process(delta):
|
||||
accum+=delta
|
||||
accum += delta
|
||||
set_text(str(accum))
|
||||
|
||||
Which will show a counter increasing each second.
|
||||
@@ -75,7 +74,7 @@ all enemies can be notified about the alarm sounding, by using
|
||||
::
|
||||
|
||||
func _on_discovered():
|
||||
get_tree().call_group(0,"guards","player_was_discovered")
|
||||
get_tree().call_group(0, "guards", "player_was_discovered")
|
||||
|
||||
The above code calls the function "player_was_discovered" on every
|
||||
member of the group "guards".
|
||||
@@ -105,9 +104,9 @@ function in your script:
|
||||
::
|
||||
|
||||
func _notification(what):
|
||||
if (what==NOTIFICATION_READY):
|
||||
if (what == NOTIFICATION_READY):
|
||||
print("This is the same as overriding _ready()...")
|
||||
elif (what==NOTIFICATION_PROCESS):
|
||||
elif (what == NOTIFICATION_PROCESS):
|
||||
var delta = get_process_time()
|
||||
print("This is the same as overriding _process()...")
|
||||
|
||||
@@ -115,7 +114,7 @@ The documentation of each class in the :ref:`Class Reference <toc-class-ref>`
|
||||
shows the notifications it can receive. However, again, for most cases
|
||||
script provides simpler overrideable functions.
|
||||
|
||||
Overrideable Functions
|
||||
Overrideable functions
|
||||
----------------------
|
||||
|
||||
As mentioned before, it's better to use these functions. Nodes provide
|
||||
@@ -124,27 +123,27 @@ many useful overrideable functions, which are described as follows:
|
||||
::
|
||||
|
||||
func _enter_tree():
|
||||
pass # When the node enters the _Scene Tree_, it become acive and this function is called. Children nodes have not entered the active scene yet. In general, it's better to use _ready() for most cases.
|
||||
pass # When the node enters the _Scene Tree_, it become acive and this function is called. Children nodes have not entered the active scene yet. In general, it's better to use _ready() for most cases.
|
||||
|
||||
func _ready():
|
||||
pass # This function is called after _enter_tree, but it ensures that all children nodes have also entered the _Scene Tree_, and became active.
|
||||
pass # This function is called after _enter_tree, but it ensures that all children nodes have also entered the _Scene Tree_, and became active.
|
||||
|
||||
func _exit_tree():
|
||||
pass # When the node exists the _Scene Tree_, this function is called. Children nodes have all exited the _Scene Tree_ at this point and all became inactive.
|
||||
pass # When the node exists the _Scene Tree_, this function is called. Children nodes have all exited the _Scene Tree_ at this point and all became inactive.
|
||||
|
||||
func _process(delta):
|
||||
pass # When set_process() is enabled, this is called every frame
|
||||
pass # When set_process() is enabled, this is called every frame
|
||||
|
||||
func _fixed_process(delta):
|
||||
pass # When set_fixed_process() is enabled, this is called every physics frame
|
||||
pass # When set_fixed_process() is enabled, this is called every physics frame
|
||||
|
||||
func _paused():
|
||||
pass # Called when game is paused, after this call, the node will not receive any more process callbacks
|
||||
pass # Called when game is paused, after this call, the node will not receive any more process callbacks
|
||||
|
||||
func _unpaused():
|
||||
pass # Called when game is unpaused
|
||||
pass # Called when game is unpaused
|
||||
|
||||
Creating Nodes
|
||||
Creating nodes
|
||||
--------------
|
||||
|
||||
To create a node from code, just call the .new() method, (like for any
|
||||
@@ -154,8 +153,8 @@ other class based datatype). Example:
|
||||
|
||||
var s
|
||||
func _ready():
|
||||
s = Sprite.new() # create a new sprite!
|
||||
add_child(s) #add it as a child of this node
|
||||
s = Sprite.new() # create a new sprite!
|
||||
add_child(s) # add it as a child of this node
|
||||
|
||||
To delete a node, be it inside or outside the scene, free() must be
|
||||
used:
|
||||
@@ -163,7 +162,7 @@ used:
|
||||
::
|
||||
|
||||
func _someaction():
|
||||
s.free() # immediately removes the node from the scene and frees it
|
||||
s.free() # immediately removes the node from the scene and frees it
|
||||
|
||||
When a node is freed, it also frees all it's children nodes. Because of
|
||||
this, manually deleting nodes is much simpler than it appears. Just free
|
||||
@@ -181,9 +180,9 @@ instead. This erases the node during idle, safely.
|
||||
::
|
||||
|
||||
func _someaction():
|
||||
s.queue_free() # remove the node and delete it while nothing is happening
|
||||
s.queue_free() # remove the node and delete it while nothing is happening
|
||||
|
||||
Instancing Scenes
|
||||
Instancing scenes
|
||||
-----------------
|
||||
|
||||
Instancing a scene from code is pretty easy and done in two steps. The
|
||||
@@ -201,8 +200,7 @@ time.
|
||||
var scene = preload("res://myscene.scn") # will load when parsing the script
|
||||
|
||||
But 'scene' is still not a node containing subnodes. It's packed in a
|
||||
special resource called
|
||||
:ref:`PackedScene <class_PackedScene>`.
|
||||
special resource called :ref:`PackedScene <class_PackedScene>`.
|
||||
To create the actual node, the function
|
||||
:ref:`PackedScene.instance() <class_PackedScene_instance>`
|
||||
must be called. This will return the tree of nodes that can be added to
|
||||
@@ -217,6 +215,3 @@ The advantage of this two-step process is that a packed scene may be
|
||||
kept loaded and ready to use, so it can be used to create as many
|
||||
instances as desired. This is specially useful, for example, to instance
|
||||
several enemies, bullets, etc. quickly in the active scene.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _doc_simple_2d_game:
|
||||
|
||||
Simple 2D game (Pong!)
|
||||
======================
|
||||
Simple 2D game
|
||||
==============
|
||||
|
||||
Pong
|
||||
~~~~
|
||||
@@ -16,7 +16,7 @@ Assets
|
||||
Some assets are included for this tutorial:
|
||||
:download:`pong_assets.zip </files/pong_assets.zip>`.
|
||||
|
||||
Scene Setup
|
||||
Scene setup
|
||||
~~~~~~~~~~~
|
||||
|
||||
For the sake of the old times, the game will be in 640x400 pixels
|
||||
@@ -39,7 +39,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.
|
||||
|
||||
Input Actions Setup
|
||||
Input actions setup
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are so many input methods for video games... Keyboard, Joypad,
|
||||
@@ -189,7 +189,4 @@ really useful here:
|
||||
|
||||
get_node("right").set_pos(right_pos)
|
||||
|
||||
And that's it! a simple Pong was written with a few lines of code.
|
||||
|
||||
|
||||
|
||||
And that's it! A simple Pong was written with a few lines of code.
|
||||
|
||||
@@ -33,10 +33,10 @@ to have parts of a scene that:
|
||||
|
||||
For this, the option for auto-loading nodes and scripts exists.
|
||||
|
||||
Autoload
|
||||
AutoLoad
|
||||
--------
|
||||
|
||||
Autoload can be a scene, or a script that inherits from Node (a Node
|
||||
AutoLoad can be a scene, or a script that inherits from Node (a Node
|
||||
will be created and the script will be set to it). They are added to the
|
||||
project in the Scene > Project Settings > AutoLoad tab.
|
||||
|
||||
@@ -53,7 +53,7 @@ access it by requesting:
|
||||
|
||||
var player_vars = get_node("/root/playervariables")
|
||||
|
||||
Custom Scene Switcher
|
||||
Custom scene switcher
|
||||
---------------------
|
||||
|
||||
This short tutorial will explain how to make a scene switcher by using
|
||||
@@ -178,7 +178,4 @@ Finally, by running the project it's possible to switch bewtween both
|
||||
scenes y pressing the button!
|
||||
|
||||
(To load scenes with a progress bar, check out the next tutorial,
|
||||
[[Background Loading]])
|
||||
|
||||
|
||||
|
||||
:ref:`doc_background_loading`)
|
||||
|
||||
@@ -13,7 +13,7 @@ splash screen.
|
||||
Following is a file with the assets that will be used:
|
||||
:download:`robisplash_assets.zip </files/robisplash_assets.zip>`.
|
||||
|
||||
Setting Up
|
||||
Setting up
|
||||
----------
|
||||
|
||||
Create a scene with screen resolution 800x450, and set it up like this:
|
||||
@@ -22,27 +22,21 @@ Create a scene with screen resolution 800x450, and set it up like this:
|
||||
|
||||
.. image:: /img/robisplashpreview.png
|
||||
|
||||
The nodes 'background" and "logo" are of
|
||||
:ref:`TextureFrame <class_TextureFrame>`
|
||||
The nodes 'background" and "logo" are of :ref:`TextureFrame <class_TextureFrame>`
|
||||
type. These have a special property for setting the texture to be
|
||||
displayed, just load the corresponding file.
|
||||
|
||||
.. image:: /img/texframe.png
|
||||
|
||||
The node "start" is a
|
||||
:ref:`TextureButton <class_TextureButton>`,
|
||||
The node "start" is a :ref:`TextureButton <class_TextureButton>`,
|
||||
it takes several images for different states, but only the normal and
|
||||
pressed will be supplied in this example:
|
||||
|
||||
.. image:: /img/texbutton.png
|
||||
|
||||
Finally, the node "copyright" is a
|
||||
:ref:`Label <class_Label>`. Labels
|
||||
can be set a custom font by editing the following property:
|
||||
Finally, the node "copyright" is a :ref:`Label <class_Label>`.
|
||||
Labels can be set a custom font by editing the following property:
|
||||
|
||||
.. image:: /img/label.png
|
||||
|
||||
As a side note, the font was imported from a TTF, see :ref:`doc_importing_fonts`.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. _doc_vector_math:
|
||||
|
||||
Vector Math
|
||||
Vector math
|
||||
===========
|
||||
|
||||
Introduction
|
||||
@@ -19,7 +19,7 @@ trigonometry instead of vector of math for 2D games.
|
||||
This tutorial will focus on practical usage, with immediate application
|
||||
to the art of game programming.
|
||||
|
||||
Coordinate Systems (2D)
|
||||
Coordinate systems (2D)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Typically, we define coordinates as an (x,y) pair, x representing the
|
||||
@@ -70,8 +70,8 @@ Theorem <http://en.wikipedia.org/wiki/Pythagorean_theorem>`__.
|
||||
|
||||
var len = sqrt( x*x + y*y )
|
||||
|
||||
But.. Angles?
|
||||
-------------
|
||||
But... angles?
|
||||
--------------
|
||||
|
||||
But why not using an *angle*? After all, we could also think of a vector
|
||||
as an angle and a magnitude, instead of a direction and a magnitude.
|
||||
@@ -88,29 +88,27 @@ as measure, but take little part in the math. So, give up the
|
||||
trigonometry already, prepare to embrace vectors!
|
||||
|
||||
In any case, obtaining an angle from a vector is easy and can be
|
||||
accomplished with trig.. er what was that? I mean, the
|
||||
:ref:`atan2.atan2() <class_atan2_atan2>`
|
||||
function.
|
||||
accomplished with trig... er, what was that? I mean, the
|
||||
:ref:`atan2() class_@GDScript_atan2` function.
|
||||
|
||||
Vectors in Godot
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
To make examples easier, it is worth explaining how vectors are
|
||||
implemented in GDScript. GDscript has both
|
||||
:ref:`Vector2 <class_Vector2>` and
|
||||
:ref:`Vector3 <class_Vector3>`,
|
||||
:ref:`Vector2 <class_Vector2>` and :ref:`Vector3 <class_Vector3>`,
|
||||
for 2D and 3D math respectively. Godot uses Vector classes as both
|
||||
position and direction. They also contain x and y (for 2D) and x, y and
|
||||
z (for 3D) member variables.
|
||||
|
||||
::
|
||||
|
||||
h1. create a vector with coordinates (2,5)
|
||||
# create a vector with coordinates (2,5)
|
||||
var a = Vector2(2,5)
|
||||
h1. create a vector and assign x and y manually
|
||||
# create a vector and assign x and y manually
|
||||
var b = Vector2()
|
||||
b.x=7
|
||||
b.y=8
|
||||
b.x = 7
|
||||
b.y = 8
|
||||
|
||||
When operating with vectors, it is not necessary to operate on the
|
||||
members directly (in fact this is much slower). Vectors support regular
|
||||
@@ -118,17 +116,17 @@ arithmetic operations:
|
||||
|
||||
::
|
||||
|
||||
#add a and b
|
||||
var c = a+b
|
||||
h1. will result in c vector, with value (9,13)
|
||||
# add a and b
|
||||
var c = a + b
|
||||
# will result in c vector, with value (9,13)
|
||||
|
||||
It is the same as doing:
|
||||
|
||||
::
|
||||
|
||||
var c = Vector2()
|
||||
c.x=a.x+b.x
|
||||
c.y=a.y+b.y
|
||||
c.x = a.x + b.x
|
||||
c.y = a.y + b.y
|
||||
|
||||
Except the former is way more efficient and readable.
|
||||
|
||||
@@ -140,9 +138,9 @@ numbers, also named **scalars**.
|
||||
|
||||
::
|
||||
|
||||
h1. Multiplication of vector by scalar
|
||||
# Multiplication of vector by scalar
|
||||
var c = a*2.0
|
||||
h1. will result in c vector, with value (4,10)
|
||||
# will result in c vector, with value (4,10)
|
||||
|
||||
Which is the same as doing
|
||||
|
||||
@@ -154,7 +152,7 @@ Which is the same as doing
|
||||
|
||||
Except, again, the former is way more efficient and readable.
|
||||
|
||||
Perpendicular Vectors
|
||||
Perpendicular vectors
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Rotating a 2D vector 90° degrees to either side, left or right, is
|
||||
@@ -170,16 +168,16 @@ Example:
|
||||
::
|
||||
|
||||
var v = Vector2(0,1)
|
||||
#rotate right (clockwise)
|
||||
var v_right = Vector2(-v.y,v.x)
|
||||
#rotate left (counter-clockwise)
|
||||
var v_right = Vector2(v.y,-v.x)
|
||||
# rotate right (clockwise)
|
||||
var v_right = Vector2(-v.y, v.x)
|
||||
# rotate left (counter-clockwise)
|
||||
var v_right = Vector2(v.y, -v.x)
|
||||
|
||||
This is a handy trick that is often of use. It is impossible to do with
|
||||
3D vectors, because there are an infinite amount of perpendicular
|
||||
vectors.
|
||||
|
||||
Unit Vectors
|
||||
Unit vectors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Ok, so we know what a vector is. It has a **direction** and a
|
||||
@@ -209,9 +207,9 @@ by it's magnitude:
|
||||
::
|
||||
|
||||
var a = Vector2(2,4)
|
||||
var m = sqrt( a.x*a.x + a.y*a.y )
|
||||
a.x/=m
|
||||
a.y/=m
|
||||
var m = sqrt(a.x*a.x + a.y*a.y)
|
||||
a.x /= m
|
||||
a.y /= m
|
||||
|
||||
As you might have guessed, if the vector has magnitude 0 (meaning, it's
|
||||
not a vector but the **origin** also called *null vector*), a division
|
||||
@@ -225,7 +223,7 @@ Of course, Vector2 and Vector3 already provide a method to do this:
|
||||
|
||||
a = a.normalized()
|
||||
|
||||
Dot Product
|
||||
Dot product
|
||||
~~~~~~~~~~~
|
||||
|
||||
OK, the **dot product** is the most important part of vector math.
|
||||
@@ -233,7 +231,7 @@ Without the dot product, Quake would have never been made. This is the
|
||||
most important section of the tutorial, so make sure to grasp it
|
||||
properly. Most people trying to understand vector math give up here
|
||||
because, despite how simple it is, they can't make head or tails from
|
||||
it. Why? Here's why, it's because..
|
||||
it. Why? Here's why, it's because...
|
||||
|
||||
The dot product takes two vectors and returns a **scalar**:
|
||||
|
||||
@@ -256,8 +254,8 @@ function:
|
||||
|
||||
var s = a.dot(b)
|
||||
|
||||
The order of two vectors does *not* matter, \`a.dot(b)\` returns the
|
||||
same value as \`b.dot(a)\`.
|
||||
The order of two vectors does *not* matter, ``a.dot(b)`` returns the
|
||||
same value as ``b.dot(a)``.
|
||||
|
||||
This is where despair begins and books and tutorials show you this
|
||||
formula:
|
||||
@@ -319,7 +317,7 @@ Snake (**A**), by subtracting the two:
|
||||
|
||||
::
|
||||
|
||||
var BA = A-B
|
||||
var BA = A - B
|
||||
|
||||
.. image:: /img/tutovec7.png
|
||||
|
||||
@@ -332,12 +330,12 @@ that the guard is facing towards him:
|
||||
|
||||
::
|
||||
|
||||
if ( BA.dot(F) > 0 ):
|
||||
if (BA.dot(F) > 0):
|
||||
print("!")
|
||||
|
||||
Seems Snake is safe so far.
|
||||
|
||||
Siding with Unit Vectors
|
||||
Siding with unit vectors
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Ok, so now we know that dot product between two vectors will let us know
|
||||
@@ -357,28 +355,28 @@ property is added:
|
||||
resulting scalar is **-1**.
|
||||
|
||||
This means that dot product between unit vectors is always between the
|
||||
range of 1 and -1. So Again..
|
||||
range of 1 and -1. So Again...
|
||||
|
||||
- If their angle is **0°** dot product is **1**.
|
||||
- If their angle is **90°**, then dot product is **0**.
|
||||
- If their angle is **180°**, then dot product is **-1**.
|
||||
|
||||
Uh.. this is oddly familiar.. seen this before.. where?
|
||||
Uh.. this is oddly familiar... seen this before... where?
|
||||
|
||||
Let's take two unit vectors. The first one is pointing up, the second
|
||||
too but we will rotate it all the way from up (0°) to down (180°
|
||||
degrees)..
|
||||
degrees)...
|
||||
|
||||
.. image:: /img/tutovec8.png
|
||||
|
||||
..while plotting the resulting scalar!
|
||||
While plotting the resulting scalar!
|
||||
|
||||
.. image:: /img/tutovec9.png
|
||||
|
||||
Aha! It all makes sense now, this is a
|
||||
`Cosine <http://mathworld.wolfram.com/Cosine.html>`__ function!
|
||||
|
||||
We can say that, then, as a rule..
|
||||
We can say that, then, as a rule...
|
||||
|
||||
The **dot product** between two **unit vectors** is the **cosine** of
|
||||
the **angle** between those two vectors. So, to obtain the angle between
|
||||
@@ -409,7 +407,7 @@ Planes
|
||||
|
||||
The dot product has another interesting property with unit vectors.
|
||||
Imagine that perpendicular to that vector (and through the origin)
|
||||
passes a [STRIKEOUT:plane]. Planes divide the entire space into positive
|
||||
passes a plane. Planes divide the entire space into positive
|
||||
(over the plane) and negative (under the plane), and (contrary to
|
||||
popular belief) you can also use their math in 2D:
|
||||
|
||||
@@ -430,7 +428,7 @@ except that the plane is an infinite surface (imagine an infinite, flat
|
||||
sheet of paper that you can orient and is pinned to the origin) instead
|
||||
of a line.
|
||||
|
||||
Distance to Plane
|
||||
Distance to plane
|
||||
-----------------
|
||||
|
||||
Now that it's clear what a plane is, let's go back to the dot product.
|
||||
@@ -449,7 +447,8 @@ space the distance will be negative, too:
|
||||
|
||||
This allows us to tell which side of the plane a point is.
|
||||
|
||||
#h3. Away from the Origin
|
||||
Away from the origin
|
||||
--------------------
|
||||
|
||||
I know what you are thinking! So far this is nice, but *real* planes are
|
||||
everywhere in space, not only passing through the origin. You want real
|
||||
@@ -465,8 +464,7 @@ by N and D. For example:
|
||||
|
||||
.. image:: /img/tutovec12.png
|
||||
|
||||
For 3D math, Godot provides a
|
||||
:ref:`Plane <class_Plane>`
|
||||
For 3D math, Godot provides a :ref:`Plane <class_Plane>`
|
||||
built-in type that handles this.
|
||||
|
||||
Basically, N and D can represent any plane in space, be it for 2D or 3D
|
||||
@@ -475,17 +473,9 @@ for both. It's the same as before, but D id the distance from the origin
|
||||
to the plane, travelling in N direction. As an example, imagine you want
|
||||
to reach a point in the plane, you will just do:
|
||||
|
||||
.. raw:: html
|
||||
::
|
||||
|
||||
</pre>
|
||||
|
||||
var point_in_plane = N\*D
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
var point_in_plane = N*D
|
||||
|
||||
This will stretch (resize) the normal vector and make it touch the
|
||||
plane. This math might seem confusing, but it's actually much simpler
|
||||
@@ -507,9 +497,8 @@ inverted negative and positive half spaces:
|
||||
N = -N
|
||||
D = -D
|
||||
|
||||
Of course, Godot implements this operator in
|
||||
:ref:`Plane <class_Plane>`, so
|
||||
doing:
|
||||
Of course, Godot implements this operator in :ref:`Plane <class_Plane>`,
|
||||
so doing:
|
||||
|
||||
::
|
||||
|
||||
@@ -522,7 +511,7 @@ calculating the distance to it. So, why is it useful to calculate the
|
||||
distance from a point to a plane? It's extremely useful! Let's see some
|
||||
simple examples..
|
||||
|
||||
Constructing a Plane in 2D
|
||||
Constructing a plane in 2D
|
||||
--------------------------
|
||||
|
||||
Planes clearly don't come out of nowhere, so they must be built.
|
||||
@@ -546,11 +535,11 @@ degrees to either side:
|
||||
|
||||
::
|
||||
|
||||
#calculate vector from a to b
|
||||
# calculate vector from a to b
|
||||
var dvec = (point_b - point_a).normalized()
|
||||
#rotate 90 degrees
|
||||
# rotate 90 degrees
|
||||
var normal = Vector2(dvec.y,-dev.x)
|
||||
#or alternatively
|
||||
# or alternatively
|
||||
# var normal = Vector2(-dvec.y,dev.x)
|
||||
# depending the desired side of the normal
|
||||
|
||||
@@ -567,7 +556,7 @@ point_b will work since they are in the same plane:
|
||||
Doing the same in 3D is a little more complex and will be explained
|
||||
further down.
|
||||
|
||||
Some Examples of Planes
|
||||
Some examples of planes
|
||||
-----------------------
|
||||
|
||||
Here is a simple example of what planes are useful for. Imagine you have
|
||||
@@ -589,12 +578,12 @@ Code should be something like this:
|
||||
|
||||
::
|
||||
|
||||
var inside=true
|
||||
var inside = true
|
||||
for p in planes:
|
||||
#check if distance to plane is positive
|
||||
if ( N.dot(point) - D > 0):
|
||||
inside=false
|
||||
break h1. with one that fails, it's enough
|
||||
# check if distance to plane is positive
|
||||
if (N.dot(point) - D > 0):
|
||||
inside = false
|
||||
break # with one that fails, it's enough
|
||||
|
||||
Pretty cool, huh? But this gets much better! With a little more effort,
|
||||
similar logic will let us know when two convex polygons are overlapping
|
||||
@@ -614,37 +603,37 @@ Code should be something like this:
|
||||
|
||||
::
|
||||
|
||||
var overlapping=true
|
||||
var overlapping = true
|
||||
|
||||
for p in planes_of_A:
|
||||
var all_out = true
|
||||
for v in points_of_B:
|
||||
if ( p.distance_to(v) < 0):
|
||||
all_out=false
|
||||
break
|
||||
|
||||
if (all_out):
|
||||
# a separating plane was found
|
||||
# do not continue testing
|
||||
overlapping=false
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
#only do this check if no separating plane
|
||||
#was found in planes of A
|
||||
for p in planes_of_B:
|
||||
var all_out = true
|
||||
for v in points_of_A:
|
||||
if ( p.distance_to(v) < 0):
|
||||
all_out=false
|
||||
var all_out = true
|
||||
for v in points_of_B:
|
||||
if (p.distance_to(v) < 0):
|
||||
all_out = false
|
||||
break
|
||||
|
||||
if (all_out):
|
||||
overlapping=false
|
||||
break
|
||||
if (all_out):
|
||||
# a separating plane was found
|
||||
# do not continue testing
|
||||
overlapping = false
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
print("Polygons Collided!")
|
||||
# only do this check if no separating plane
|
||||
# was found in planes of A
|
||||
for p in planes_of_B:
|
||||
var all_out = true
|
||||
for v in points_of_A:
|
||||
if (p.distance_to(v) < 0):
|
||||
all_out = false
|
||||
break
|
||||
|
||||
if (all_out):
|
||||
overlapping = false
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
print("Polygons Collided!")
|
||||
|
||||
As you can see, planes are quite useful, and this is the tip of the
|
||||
iceberg. You might be wondering what happens with non convex polygons.
|
||||
@@ -652,7 +641,7 @@ This is usually just handled by splitting the concave polygon into
|
||||
smaller convex polygons, or using a technique such as BSP (which is not
|
||||
used much nowadays).
|
||||
|
||||
Cross Product
|
||||
Cross product
|
||||
-------------
|
||||
|
||||
Quite a lot can be done with the dot product! But the party would not be
|
||||
@@ -687,19 +676,11 @@ The formula for the cross product is:
|
||||
|
||||
This can be simplified, in Godot, to:
|
||||
|
||||
.. raw:: html
|
||||
::
|
||||
|
||||
</pre>
|
||||
var c = a.cross(b)
|
||||
|
||||
var c = a.cross(b)
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
|
||||
However, unlike the dot product, doing \`a.cross(b)\` and \`b.cross(a)\`
|
||||
However, unlike the dot product, doing ``a.cross(b)`` and ``b.cross(a)``
|
||||
will yield different results. Specifically, the returned vector will be
|
||||
negated in the second case. As you might have realized, this coincides
|
||||
with creating perpendicular vectors in 2D. In 3D, there are also two
|
||||
@@ -708,7 +689,7 @@ possible perpendicular vectors to a pair of 2D vectors.
|
||||
Also, the resulting cross product of two unit vectors is *not* a unit
|
||||
vector. Result will need to be renormalized.
|
||||
|
||||
Area of a Triangle
|
||||
Area of a triangle
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Cross product can be used to obtain the surface area of a triangle in
|
||||
@@ -719,19 +700,10 @@ Cross product can be used to obtain the surface area of a triangle in
|
||||
Take any of them as a pivot and compute the adjacent vectors to the
|
||||
other two points. As example, we will use B as a pivot:
|
||||
|
||||
.. raw:: html
|
||||
::
|
||||
|
||||
</pre>
|
||||
|
||||
var BA = A-B
|
||||
|
||||
var BC = C-B
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
var BA = A - B
|
||||
var BC = C - B
|
||||
|
||||
.. image:: /img/tutovec18.png
|
||||
|
||||
@@ -752,23 +724,15 @@ of the triangle is half of it.
|
||||
|
||||
var area = P.length()/2
|
||||
|
||||
Plane of the Triangle
|
||||
Plane of the triangle
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
With **P** computed from the previous step, normalize it to get the
|
||||
normal of the plane.
|
||||
|
||||
.. raw:: html
|
||||
::
|
||||
|
||||
</pre>
|
||||
|
||||
var N = P.normalized()
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</pre>
|
||||
var N = P.normalized()
|
||||
|
||||
And obtain the distance by doing the dot product of P with any of the 3
|
||||
points of the **ABC** triangle:
|
||||
@@ -811,7 +775,7 @@ So, to obtain N, the correct formula is:
|
||||
# var N = (A-B).cross(A-C).normalized()
|
||||
var D = N.dot(A)
|
||||
|
||||
Collision Detection in 3D
|
||||
Collision detection in 3D
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is another bonus bit, a reward for being patient and keeping up
|
||||
@@ -850,71 +814,78 @@ So the final algorithm is something like:
|
||||
|
||||
::
|
||||
|
||||
var overlapping=true
|
||||
var overlapping = true
|
||||
|
||||
for p in planes_of_A:
|
||||
var all_out = true
|
||||
for v in points_of_B:
|
||||
if ( p.distance_to(v) < 0):
|
||||
all_out=false
|
||||
break
|
||||
|
||||
if (all_out):
|
||||
# a separating plane was found
|
||||
# do not continue testing
|
||||
overlapping=false
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
#only do this check if no separating plane
|
||||
#was found in planes of A
|
||||
for p in planes_of_B:
|
||||
var all_out = true
|
||||
for v in points_of_A:
|
||||
if ( p.distance_to(v) < 0):
|
||||
all_out=false
|
||||
var all_out = true
|
||||
for v in points_of_B:
|
||||
if (p.distance_to(v) < 0):
|
||||
all_out = false
|
||||
break
|
||||
|
||||
if (all_out):
|
||||
overlapping=false
|
||||
break
|
||||
if (all_out):
|
||||
# a separating plane was found
|
||||
# do not continue testing
|
||||
overlapping = false
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
# only do this check if no separating plane
|
||||
# was found in planes of A
|
||||
for p in planes_of_B:
|
||||
var all_out = true
|
||||
for v in points_of_A:
|
||||
if (p.distance_to(v) < 0):
|
||||
all_out = false
|
||||
break
|
||||
|
||||
for ea in edges_of_A:
|
||||
for eb in edges_of_B:
|
||||
var n = ea.cross(eb)
|
||||
if (n.length()==0):
|
||||
continue
|
||||
var max_A=-1e20 # tiny number
|
||||
var min_A=1e20 # huge number
|
||||
|
||||
# we are using the dot product directly
|
||||
# so we can map a maximum and minimum range
|
||||
# for each polygon, then check if they
|
||||
# overlap.
|
||||
|
||||
for v in points_of_A:
|
||||
var d = n.dot(v)
|
||||
if (d>max_A):
|
||||
max_A=d
|
||||
if (dmax_B):
|
||||
max_B=d
|
||||
if (dmax_B or min_B>max_A):
|
||||
# not overlapping!
|
||||
overlapping=false
|
||||
break
|
||||
|
||||
if (not overlapping):
|
||||
break
|
||||
|
||||
if (all_out):
|
||||
overlapping = false
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
print("Polygons Collided!")
|
||||
for ea in edges_of_A:
|
||||
for eb in edges_of_B:
|
||||
var n = ea.cross(eb)
|
||||
if (n.length() == 0):
|
||||
continue
|
||||
|
||||
var max_A = -1e20 # tiny number
|
||||
var min_A = 1e20 # huge number
|
||||
|
||||
# we are using the dot product directly
|
||||
# so we can map a maximum and minimum range
|
||||
# for each polygon, then check if they
|
||||
# overlap.
|
||||
|
||||
for v in points_of_A:
|
||||
var d = n.dot(v)
|
||||
if (d > max_A):
|
||||
max_A = d
|
||||
if (d < min_A):
|
||||
min_A = d
|
||||
|
||||
var max_B = -1e20 # tiny number
|
||||
var min_B = 1e20 # huge number
|
||||
|
||||
for v in points_of_B:
|
||||
var d = n.dot(v)
|
||||
if (d > max_B):
|
||||
max_B = d
|
||||
if (d < min_B):
|
||||
min_B = d
|
||||
|
||||
if (min_A > max_B or min_B > max_A):
|
||||
# not overlapping!
|
||||
overlapping = false
|
||||
break
|
||||
|
||||
if (not overlapping):
|
||||
break
|
||||
|
||||
if (overlapping):
|
||||
print("Polygons collided!")
|
||||
|
||||
This was all! Hope it was helpful, and please give feedback and let know
|
||||
if something in this tutorial is not clear! You should be now ready for
|
||||
the next challenge... :ref:`doc_matrices_and_transforms`!
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user