Skip to content

Commit a7a037b

Browse files
committed
Remove tutorial options and explanations.
Needed to make the tutorial more useful to learners.
1 parent 258a233 commit a7a037b

File tree

2 files changed

+58
-50
lines changed

2 files changed

+58
-50
lines changed

docs/tutorial/part-00.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Part 0 - Setting up a project
2+
##############################################################################
3+
4+
Starting tools
5+
==============================================================================
6+
7+
The IDE used for this tutorial is `Visual Studio Code <https://code.visualstudio.com/>`_ (not to be mistaken for Visual Studio).
8+
9+
Git will be used for version control.
10+
`Follow the instructions here <https://git-scm.com/downloads>`_.
11+
12+
Python 3.11 was used to make this tutorial.
13+
`Get the latest version of Python here <https://www.python.org/downloads/>`_.
14+
If there exists a version of Python later then 3.11 then install that version instead.
15+
16+
17+
First script
18+
==============================================================================
19+
20+
First start with a modern top-level script.
21+
Create a script in the project root folder called ``main.py`` which checks ``if __name__ == "__main__":`` and calls a ``main`` function.
22+
23+
.. code-block:: python
24+
25+
def main() -> None:
26+
print("Hello World!")
27+
28+
29+
if __name__ == "__main__":
30+
main()
31+
32+
In VSCode on the left sidebar is a **Run and Debug** tab.
33+
On this tab select **create a launch.json** file.
34+
This will prompt about what kind of program to launch.
35+
Pick ``Python``, then ``Module``, then when asked for the module name type ``main``.
36+
From now on the ``F5`` key will launch ``main.py`` in debug mode.
37+
38+
Run the script now and ``"Hello World!"`` should be visible in the terminal output.

docs/tutorial/part-01.rst

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,29 @@
1-
Part 1
2-
==============================================================================
1+
Part 1 - Moving a player around the screen
2+
##############################################################################
33

44
Initial script
5-
------------------------------------------------------------------------------
5+
==============================================================================
66

7-
First start with a modern top-level script:
7+
First start with a modern top-level script.
88

99
.. code-block:: python
1010
11-
#!/usr/bin/env python3
12-
"""This script is invoked to start the program."""
13-
from __future__ import annotations # PEP 563
14-
15-
1611
def main() -> None:
17-
"""Main entry point function."""
18-
pass # Nothing yet
12+
...
1913
2014
21-
if __name__ == "__main__": # Top-level code environment
15+
if __name__ == "__main__":
2216
main()
2317
24-
The first line is a `shebang <https://en.wikipedia.org/wiki/Shebang_%28Unix%29>`_ which allows direct execution of the script and will hint certain Python launchers which version to use.
25-
If you always invoke Python directly then you do not need this line.
26-
27-
The triple-quoted string is a `docstring <https://en.wikipedia.org/wiki/Docstring>`_.
28-
The one near the top documents the purpose for the module.
29-
The one in ``main`` documents that function.
30-
31-
``from __future__ import annotations`` tells Python to use `Postponed Evaluation of Annotations <https://peps.python.org/pep-0563/>`_.
32-
This is required for specific type-hints, such as a class using itself in its own annotations.
33-
This will also speed up the initialization of code which uses type-hints.
34-
35-
``def main() -> None:`` has no significance other than convention.
36-
Because this function returns nothing it is annotated with ``-> None``.
37-
38-
``if __name__ == "__main__":`` checks for the `Top-level code environment <https://docs.python.org/3/library/__main__.html>`_.
39-
This prevents tools from accidentally launching the script when they just want to import it.
40-
This is the only required boilerplate, everything else is optional.
18+
You will replace body of the ``main`` function in the following section.
4119

4220
Loading a tileset and opening a window
43-
------------------------------------------------------------------------------
21+
==============================================================================
4422

4523
From here it is time to setup a ``tcod`` program.
4624
Download `Alloy_curses_12x12.png <https://raw.githubusercontent.com/HexDecimal/python-tcod-tutorial-2023/6b69bf9b5531963a0e5f09f9d8fe72a4001d4881/data/Alloy_curses_12x12.png>`_ and place this file in your projects ``data/`` directory.
47-
This tileset is from the `Dwarf Fortress tileset repository <https://dwarffortresswiki.org/index.php/DF2014:Tileset_repository>`_ and you may choose to use any other tileset from there as long is you keep track of the filename yourself.
25+
This tileset is from the `Dwarf Fortress tileset repository <https://dwarffortresswiki.org/index.php/DF2014:Tileset_repository>`_.
26+
These kinds of tilesets are always loaded with ``columns=16, rows=16, charmap=tcod.tileset.CHARMAP_CP437``.
4827

4928
Load the tileset with :any:`tcod.tileset.load_tilesheet` and then pass it to :any:`tcod.context.new`.
5029
These functions are part of modules which have not been imported yet, so new imports need to be added.
@@ -74,22 +53,22 @@ If you run this script now then a window will open and then immediately close.
7453
If that happens without seeing a traceback in your terminal then the script is correct.
7554

7655
Configuring an event loop
77-
------------------------------------------------------------------------------
56+
==============================================================================
7857

7958
The next step is to keep the window open until the user closes it.
8059

8160
Since nothing is displayed yet a :any:`Console` should be created with ``"Hello World"`` printed to it.
8261
The size of the console can be used as a reference to create the context by adding the console to :any:`tcod.context.new`.
8362

84-
To actually display the console to the window the :any:`Context.present` method must be called with the console.
85-
Be sure to check the additional a parameters of :any:`Context.present`, you can keep aspect or enforce integer scaling.
63+
Begin the main game loop with a ``while True:`` statement.
8664

87-
Events are checked by iterating over all pending events.
88-
If your game is strictly turn-based then you should use :any:`tcod.event.wait`.
89-
If your game is real-time or has real-time animations then it should use :any:`tcod.event.get` instead.
65+
To actually display the console to the window the :any:`Context.present` method must be called with the console as a parameter.
66+
Do this first in the game loop before handing events.
9067

91-
Test if an event is for closing the window with ``isinstance(event, tcod.event.Quit)``.
92-
If this is True then you should exit the function, either with ``return``, or with :any:`sys.exit`, or with ``raise SystemExit``.
68+
Events are checked by iterating over all pending events with :any:`tcod.event.wait`.
69+
Use the code ``for event in tcod.event.wait():`` to begin handing events.
70+
Test if an event is for closing the window with ``if isinstance(event, tcod.event.Quit):``.
71+
If this is True then you should exit the function with ``raise SystemExit``.
9372

9473
.. code-block:: python
9574
:emphasize-lines: 2,3,11-18
@@ -118,13 +97,12 @@ If you run this then you get a window saying ``"Hello World"``.
11897
The window can be resized and the console will be stretched to fit the new resolution.
11998

12099
An example game state
121-
------------------------------------------------------------------------------
100+
==============================================================================
122101

123102
What exists now is not very interactive.
124103
The next step is to change state based on user input.
125104

126105
Like ``tcod`` you'll need to install ``attrs`` with Pip, such as with ``pip install attrs``.
127-
Alternatively you can use :any:`dataclasses`, but this tutorial uses ``attrs`` since it has a more modern implementation.
128106

129107
Start by adding an ``attrs`` class called ``ExampleState``.
130108
This a normal class with the ``@attrs.define(eq=False)`` decorator added.
@@ -135,8 +113,7 @@ The parameters for ``on_draw`` are ``self`` because this is an instance method a
135113
``on_draw`` returns nothing, so be sure to add ``-> None``.
136114

137115
:any:`Console.print` is the simplest way to draw the player because other options would require bounds-checking.
138-
139-
If ``tcod.console.Console`` is too verbose then you can add ``from tcod.console import Console`` so that you can use just ``Console`` instead.
116+
Call this method using the players current coordinates and the ``"@"`` character.
140117

141118
.. code-block:: python
142119
@@ -190,13 +167,6 @@ Modify the drawing routine so that the console is cleared, then passed to ``Exam
190167
191168
Now if you run the script you'll see ``@``.
192169

193-
This code is sensitive to typing.
194-
If you wrote ``player_x=console.width / 2`` instead of ``player_x=console.width // 2`` (note the number of slashes) then ``player_x`` will be assigned as a float instead of an int.
195-
If ``player_x`` is a float then :any:`Console.print` will raise a TypeError.
196-
In this case the incorrect code is when ``ExampleState`` is created with an invalid type and not the print function call.
197-
Running ``mypy`` on your code will show you this type error at the correct position.
198-
Your IDE should also complain about a bad type if setup correctly.
199-
200170
The next step is to move the player on events.
201171
A new method will be added to the ``ExampleState`` for this called ``on_event``.
202172
``on_event`` takes a ``self`` and a :any:`tcod.event.Event` parameter and returns nothing.

0 commit comments

Comments
 (0)