You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: tutorials/python/2021/index.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,12 +11,14 @@ The event is still ongoing.
11
11
It isn't unusual for tcod to be updated during the event, so you might have to upgrade it has you progress on this version of the tutorial.
12
12
Earlier pages may also be updated at times.
13
13
14
+
You can point out or fix typos by [making an issue or pull request](https://github.com/libtcod/libtcod.github.io). Code suggestions go [here](https://github.com/TStand90/tcod_tutorial_v2) instead.
15
+
14
16
## Main Tutorial:
15
17
16
18
-[Part 0 - Setting Up](part-0)
17
19
-[Part 1 - Drawing the ‘@’ symbol and moving it around](part-1)
18
-
- Part 2 - The generic Entity, the render functions, and the map (July 6th)
19
-
- Part 3 - Generating a dungeon
20
+
-[Part 2 - The generic Entity, the render functions, and the map](part-2)
21
+
-[Part 3 - Generating a dungeon](part-3)
20
22
- Part 4 - Field of view (July 13th)
21
23
- Part 5 - Placing enemies and kicking them (harmlessly)
22
24
- Part 6 - Doing (and taking) some damage (July 20th)
@@ -13,141 +13,27 @@ If not, be sure to check that page, and make sure that you've got Python and TCO
13
13
14
14
Assuming that you've done all that, let's get started.
15
15
16
-
17
16
We will start by setting up the following directory structure.
18
-
The font from [Part 0](part-0) will go into a `data` directory, then a `game` package will be created with some Python modules, then finally `main.py` will be created as an entry point.
17
+
The font from [Part 0](part-0) will go into a `data` directory, then `main.py` will be created as an entry point.
19
18
20
19
```
21
20
/data/dejavu16x16_gs_tc.png
22
-
/game/__init__.py
23
-
/game/actions.py
24
-
/game/input_handlers.py
25
21
/main.py
26
22
```
27
23
28
-
`/game/__init__.py` will be a blank file as it's only needed to [define a Python package](https://docs.python.org/3/tutorial/modules.html#packages).
29
-
30
-
```python
31
-
# game/__init__.py
32
-
```
33
-
34
-
`/game/actions.py` is based loosely on [Bob Nystrom's "Is There More to Game Architecture than ECS?"](https://www.youtube.com/watch?v=JxI3Eu5DPwE).
35
-
36
-
```python
37
-
# game/actions.py
38
-
from__future__import annotations
39
-
40
-
41
-
classAction:
42
-
pass
43
-
44
-
45
-
classMove(Action):
46
-
def__init__(self, dx: int, dy: int):
47
-
super().__init__()
48
-
49
-
self.dx = dx
50
-
self.dy = dy
51
-
```
52
-
53
-
This has the base class `Action` and the real action `Move` for relative movement, the `Move` class holds the direction of movement.
54
-
Since this is in a module in a package the fully qualified name for `Move` is `game.actions.Move`, so it won't be necessary to add the word `Action` to any sub-classes of `Action`.
55
-
56
-
`from __future__ import annotations` tells Python to do [Postponed Evaluation of Annotations](https://www.python.org/dev/peps/pep-0563/), this helps reduce issues from modules referencing each other which can happen often whenever type-hinting is being used.
57
-
This will be added to the beginning of most new modules.
58
-
59
-
`/game/input_handlers.py`
24
+
`/main.py` is the entry point of the program. You can use `python main.py` to start the program after the following is implemented.
[Optional](https://docs.python.org/3/library/typing.html#typing.Optional) is imported from the typing module.
119
-
`tcod` and `game.actions` is also used in this module so they are imported as well.
120
-
121
-
`MOVE_KEYS` can be simplified if you don't need diagonal movement:
122
-
123
-
```python
124
31
MOVE_KEYS= {
125
32
tcod.event.K_UP: (0, -1),
126
33
tcod.event.K_DOWN: (0, 1),
127
34
tcod.event.K_LEFT: (-1, 0),
128
35
tcod.event.K_RIGHT: (1, 0),
129
36
}
130
-
```
131
-
132
-
The `EventHandler` class inherits from [tcod.event.EventDispatch](https://python-tcod.readthedocs.io/en/latest/tcod/event.html#tcod.event.EventDispatch), the generic type is filled with `game.actions.Action` which means the event methods can return that type and that the caller of the [dispatch](https://python-tcod.readthedocs.io/en/latest/tcod/event.html#tcod.event.EventDispatch.dispatch) method can receive that type.
133
-
134
-
Trying to close the window will trigger a call to `ev_quit`.
135
-
This will raise [SystemExit](https://docs.python.org/3/library/exceptions.html#SystemExit) which will propagate and terminate the script.
136
-
137
-
When a key is pressed then `ev_keydown` is triggered.
138
-
This will check if that key is one of the keys in `MOVE_KEYS`, if it is then `game.actions.Move` is returned with the values of `MOVE_KEYS[event.sym]`.
139
-
Any unexpected key will return `None` instead.
140
-
141
-
142
-
`/main.py` is the entry point of the program. You can use `python main.py` to start the program after the following is implemented.
`#!/usr/bin/env python3` is a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) and must be the first line to be useful.
194
-
It's normally used to make scripts executable on Linux, but is sometimes used by Python launchers on other platforms as well.
78
+
It is normally used to make scripts executable on Linux, but is also used by the Windows Python launcher.
195
79
196
80
`tcod` is imported along with the two other modules we've added.
197
81
82
+
`MOVE_KEYS` is a Python dictionary mapping of [tcod KeySym's](https://python-tcod.readthedocs.io/en/latest/tcod/event.html#tcod.event.KeySym) to in-game directions.
83
+
This will be expanded in later parts.
84
+
198
85
The `main` function will be the entry point of the program.
199
86
There's nothing special about the name other than the terminology, the special nature of this function comes from the `__name__ == "__main__"` condition at the bottom of the script which is only True when the script is directly run, compared to importing main from an interactive prompt.
200
87
@@ -204,8 +91,6 @@ The floor division operator is used so that the numbers don't promote to a float
204
91
The tileset is loaded with [tcod.tileset.load_tilesheet](https://python-tcod.readthedocs.io/en/latest/tcod/tileset.html#tcod.tileset.load_tilesheet)
205
92
The Python-tcod docs have a [character reference](https://python-tcod.readthedocs.io/en/latest/tcod/charmap-reference.html) to keep track of which layouts have what glyphs.
206
93
207
-
The `event_handler` is now initialized.
208
-
209
94
[tcod.context.new](https://python-tcod.readthedocs.io/en/latest/tcod/context.html#tcod.context.new) is used to setup the window and returns a [Context](https://python-tcod.readthedocs.io/en/latest/tcod/context.html#tcod.context.Context) instance.
210
95
Contexts must be closed once you're done with them, but the `with` statement will do this automatically when exiting the with-block.
211
96
@@ -215,21 +100,26 @@ This is a convenient way to handle array indexes so we'll use `order="F"` a lot
215
100
You might wonder why `order="F"` isn't the default [and there is an explanation for that](https://numpy.org/doc/stable/reference/internals.html#multidimensional-array-indexing-order-issues).
216
101
These arrays are not being used yet.
217
102
218
-
Now with `while True:` the game-loop begins, with the only way of existing this loop normally being the `SystemExit` exceptions implemented earlier.
219
-
The player position is printed to `root_console`, then `root_console` is displayed using `context.present(root_console)`, after that the `root_console` is cleared for the next frame.
103
+
Now with `while True:` the game-loop begins, with the only way of existing this loop normally being the `SystemExit` exceptions implemented later.
104
+
`root_console` is cleared, then the player position is printed to `root_console`, then `root_console` is displayed using `context.present(root_console)`.
220
105
221
106
The for-loop waits for there to be events then iterates over all events until none are left.
222
107
This is an efficient way to handle events when the game doesn't have real-time animations or mechanics.
223
108
If you have real-time effects then you should replace [tcod.event.wait](https://python-tcod.readthedocs.io/en/latest/tcod/event.html#tcod.event.wait) with [tcod.event.get](https://python-tcod.readthedocs.io/en/latest/tcod/event.html#tcod.event.get).
224
109
225
-
Events are sent to the `EventHandler` class and the action to be performed is returned.
226
-
This could be `None` or any `Action`.
227
-
`isinstance(action, game.actions.Move)` tests if `action` is an instance of `Move`.
228
-
This affects type checking which can now assume that `action` is that type within the if-branch.
229
-
It can then unpack its values and checks if the destination is in the bounds of the screen before setting the player position.
110
+
[isinstance](https://docs.python.org/3/library/functions.html#isinstance) is being used here to sort events by type.
111
+
This has an effect on type-checking, where anything within an `isinstance` branch can be assumed to actually be that type, much like a type cast in any other language.
112
+
113
+
Trying to close the window will result in a `Quit` event.
114
+
When this happens we will raise [SystemExit](https://docs.python.org/3/library/exceptions.html#SystemExit) which will propagate and terminate the script.
115
+
116
+
For `KeyDown` events we check if the key is in the `MOVE_KEYS` dictionary then try to move by that amount.
117
+
If the destination is on the screen then the player moves to that spot.
230
118
231
119
You can see the current progress of this code in its entirety [here](https://github.com/TStand90/tcod_tutorial_v2/tree/2021/part-1).
232
120
233
-
Part-2 isn't available yet, [but you can setup distribution in the meantime](distribution).
121
+
If you want to distribute your game then [you can set that up now or at any time later](distribution).
0 commit comments