drawzero 0.4.4__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {drawzero-0.4.4 → drawzero-0.5.1}/LICENSE +21 -21
  2. {drawzero-0.4.4 → drawzero-0.5.1}/MANIFEST.in +8 -8
  3. drawzero-0.5.1/PKG-INFO +325 -0
  4. {drawzero-0.4.4 → drawzero-0.5.1}/README.md +281 -279
  5. drawzero-0.5.1/pyproject.toml +56 -0
  6. {drawzero-0.4.4 → drawzero-0.5.1}/setup.cfg +4 -4
  7. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/__about__.py +11 -11
  8. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/__init__.py +46 -46
  9. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/__main__.py +10 -10
  10. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/00_hello_world.py +16 -20
  11. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/01_grid_and_coordinates.py +20 -20
  12. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/02_loops_and_rgb_colors.py +24 -24
  13. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/03_simple_objects.py +55 -55
  14. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/04_loops_sin_plot.py +13 -13
  15. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/05_points.py +57 -57
  16. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/06_turtle_style.py +18 -18
  17. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/07_animation_circles.py +14 -14
  18. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/08_animation_traffic_light.py +33 -33
  19. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/09_animation_rectangles.py +39 -39
  20. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/10_animation_planets.py +25 -25
  21. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/11_transparency_and_line_width.py +39 -39
  22. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/12_images.py +11 -11
  23. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/13_gradients.py +17 -17
  24. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/14_animation_close_vertex.py +36 -36
  25. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/15_animation_firework.py +120 -120
  26. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/16_keyboard_and_mouse.py +40 -40
  27. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/17_mouse_tube.py +18 -18
  28. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/18_game_stars.py +97 -97
  29. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/19_game_colors.py +62 -62
  30. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/20_game_racing.py +57 -57
  31. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/99_errors.py +41 -40
  32. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/colors.py +684 -684
  33. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/converters.py +169 -158
  34. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/copy_examples.py +16 -16
  35. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/draw.py +403 -317
  36. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/errors.py +15 -15
  37. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/gradient.py +62 -62
  38. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/i18n.py +182 -166
  39. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/key_flags.py +260 -260
  40. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/pt.py +791 -791
  41. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/renderer.py +401 -393
  42. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/renderer_ejudge.py +110 -110
  43. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/screen_size.py +41 -41
  44. drawzero-0.5.1/src/drawzero.egg-info/PKG-INFO +325 -0
  45. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero.egg-info/SOURCES.txt +10 -4
  46. drawzero-0.5.1/src/drawzero.egg-info/requires.txt +14 -0
  47. drawzero-0.5.1/tests/test_converters.py +124 -0
  48. drawzero-0.5.1/tests/test_copy_examples.py +26 -0
  49. drawzero-0.5.1/tests/test_errors.py +71 -0
  50. drawzero-0.5.1/tests/test_examples_gui_mode.py +95 -0
  51. drawzero-0.5.1/tests/test_examples_text_mode.py +91 -0
  52. drawzero-0.5.1/tests/test_gradient.py +35 -0
  53. drawzero-0.5.1/tests/test_i18n.py +16 -0
  54. drawzero-0.5.1/tests/test_pt.py +16 -0
  55. drawzero-0.4.4/PKG-INFO +0 -309
  56. drawzero-0.4.4/docs/pt.rst +0 -0
  57. drawzero-0.4.4/setup.py +0 -123
  58. drawzero-0.4.4/src/drawzero.egg-info/PKG-INFO +0 -309
  59. drawzero-0.4.4/src/drawzero.egg-info/entry_points.txt +0 -3
  60. drawzero-0.4.4/src/drawzero.egg-info/requires.txt +0 -1
  61. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_00.png +0 -0
  62. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_01.png +0 -0
  63. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_02.png +0 -0
  64. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_03.png +0 -0
  65. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_04.png +0 -0
  66. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_05.png +0 -0
  67. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_06.png +0 -0
  68. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_10.png +0 -0
  69. {drawzero-0.4.4 → drawzero-0.5.1}/docs/ex_13.png +0 -0
  70. {drawzero-0.4.4 → drawzero-0.5.1}/docs/hello_world.png +0 -0
  71. {drawzero-0.4.4 → drawzero-0.5.1}/docs/keyboard_and_mouse_events.gif +0 -0
  72. {drawzero-0.4.4 → drawzero-0.5.1}/docs/planet_animation.gif +0 -0
  73. {drawzero-0.4.4 → drawzero-0.5.1}/docs/transparent.png +0 -0
  74. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/__init__.py +0 -0
  75. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/examples/cat.png +0 -0
  76. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero/utils/__init__.py +0 -0
  77. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero.egg-info/dependency_links.txt +0 -0
  78. {drawzero-0.4.4 → drawzero-0.5.1}/src/drawzero.egg-info/top_level.txt +0 -0
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2019 Sergey Shashkov
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Sergey Shashkov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,8 +1,8 @@
1
- # Include the README
2
- include *.rst
3
-
4
- # Include the license file
5
- include LICENSE
6
-
7
- # Images
8
- recursive-include docs *.rst *.png *.gif
1
+ # Include the README
2
+ include *.rst
3
+
4
+ # Include the license file
5
+ include LICENSE
6
+
7
+ # Images
8
+ recursive-include docs *.rst *.png *.gif
@@ -0,0 +1,325 @@
1
+ Metadata-Version: 2.4
2
+ Name: drawzero
3
+ Version: 0.5.1
4
+ Summary: A zero-boilerplate canvas drawing framework for Python 3, based on Pygame.
5
+ Author-email: Sergey Shashkov <sh57@yandex.ru>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ShashkovS/drawzero
8
+ Project-URL: Documentation, https://drawzero.org/
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Education
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: Environment :: Win32 (MS Windows)
13
+ Classifier: Environment :: X11 Applications
14
+ Classifier: Environment :: MacOS X
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Natural Language :: Russian
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: Implementation :: CPython
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: mkdocs-static-i18n[material]>=1.3.0
31
+ Requires-Dist: pygame>=2.0.1
32
+ Provides-Extra: dev
33
+ Requires-Dist: setuptools; extra == "dev"
34
+ Requires-Dist: build; extra == "dev"
35
+ Requires-Dist: mkdocs-material; extra == "dev"
36
+ Requires-Dist: mkdocs-static-i18n[material]; extra == "dev"
37
+ Requires-Dist: pymdown-extensions; extra == "dev"
38
+ Requires-Dist: mkdocstrings-python; extra == "dev"
39
+ Requires-Dist: pytest; extra == "dev"
40
+ Requires-Dist: coverage; extra == "dev"
41
+ Requires-Dist: wheel; extra == "dev"
42
+ Requires-Dist: twine; extra == "dev"
43
+ Dynamic: license-file
44
+
45
+ <p align="center">
46
+ <a href="https://pypi.org/project/drawzero/" target="_blank">
47
+ <img alt="PyPI" src="https://img.shields.io/pypi/v/drawzero">
48
+ </a>
49
+ <img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/drawzero">
50
+ <img alt="GitHub" src="https://img.shields.io/github/license/ShashkovS/drawzero">
51
+ <img alt="coverage" src="https://img.shields.io/badge/coverage-90%25-brightgreen">
52
+ </p>
53
+
54
+ # Draw Zero
55
+ A zero-boilerplate canvas drawing framework for Python 3, based on Pygame.
56
+
57
+ **[Documentation](https://drawzero.org/)**
58
+
59
+
60
+ ## Some examples
61
+
62
+ Here's some neat stuff you can do:
63
+
64
+ ``` python
65
+ # import all
66
+ from drawzero import *
67
+
68
+ # simple shapes
69
+ fill('#12bbae')
70
+ line('red', (400, 400), (800, 800))
71
+ circle('yellow', (500, 560), 200)
72
+ filled_circle('brown', (500, 500), 20)
73
+ text('red', 'Hello, world!', (300, 200), 72)
74
+ rect('blue', (200, 600), 100, 100)
75
+ filled_rect('orange', (400, 600), 100, 100)
76
+ polygon('white', [(20, 200), (100, 240), (40, 160)])
77
+ filled_polygon('burlywood', 200, 400, 130, 304, 20, 342, 20, 458, 130, 496, )
78
+ ```
79
+
80
+ <img alt="hello world" src="https://raw.githubusercontent.com/ShashkovS/drawzero/master/docs/hello_world.png" width="75%">
81
+
82
+ # Animation
83
+
84
+ Animations are also straightforward:
85
+
86
+ <img alt="planet_animation" src="https://raw.githubusercontent.com/ShashkovS/drawzero/master/docs/planet_animation.gif" width="50%">
87
+
88
+ ``` python
89
+ from drawzero import *
90
+ from math import sin, cos, pi
91
+
92
+ earth_orbit = 400
93
+ earth_radius = 30
94
+ earth_rot_step = 2 * pi / 360
95
+ moon_orbit = 100
96
+ moon_radius = 10
97
+ moon_rot_step = 2 * pi / 60
98
+
99
+ i = 0
100
+ while True:
101
+ i += 1
102
+ e_x = 500 + earth_orbit * cos(earth_rot_step * i)
103
+ e_y = 500 + earth_orbit * sin(earth_rot_step * i)
104
+ m_x = e_x + moon_orbit * cos(moon_rot_step * i)
105
+ m_y = e_y + moon_orbit * sin(moon_rot_step * i)
106
+
107
+ clear()
108
+ filled_circle(C.red, (500, 500), 100)
109
+ filled_circle(C.blue, (e_x, e_y), earth_radius)
110
+ filled_circle(C.yellow, (m_x, m_y), moon_radius)
111
+ tick()
112
+ ```
113
+
114
+
115
+ # Point class which acts like 2-d vector and Turtle both
116
+
117
+ <img alt="transparent.png" src="https://raw.githubusercontent.com/ShashkovS/drawzero/master/docs/ex_05.png" width="50%">
118
+
119
+ ```python
120
+ from drawzero import *
121
+
122
+ # just coordinates
123
+ A = Pt(100, 100)
124
+ B = Pt(300, 150)
125
+ line(C.red, A, B)
126
+
127
+ # A point which acts as 2-d vector and as a Turtle
128
+ # Pt(x=0.0, y=0.0, *, heading=0.0)
129
+ #
130
+ # Provides (for a, b — points, k number):
131
+ # * arithmetic
132
+ # a+b — vector addition
133
+ # a-b — vector subtraction
134
+ # k*a and a*k — multiplication with scalar
135
+ # abs — absolute value of a
136
+ # +a, -a
137
+
138
+ # arithmetic
139
+ A = Pt(100, 200)
140
+ dx = Pt(50, 5)
141
+ for i in range(10):
142
+ filled_circle(C.blue, A + dx * i, radius=10)
143
+
144
+ # * turtle-style movement
145
+ # forward — Move the point forward by the specified distance.
146
+ # backward — Move the point backward by distance.
147
+ # right — Turn point right by angle degrees.
148
+ # left — Turn point left by angle degrees.
149
+ # goto — Move point to an absolute position.
150
+ # rotate_around — Rotate around given point by angle degrees.
151
+ # move_towards — Move towards the given point by the specified distance.
152
+ # reset, home — Move point to the origin - coordinates (0,0), set heading=0
153
+ # setx — Set the point's first coordinate to x
154
+ # sety — Set the point's second coordinate to y
155
+ # setheading — Set the point's heading
156
+
157
+ A = Pt(100, 300)
158
+ B = Pt(1000, 400)
159
+ for i in range(10):
160
+ filled_circle(C.green2, A, radius=10)
161
+ A.move_towards(50, B)
162
+
163
+ A = Pt(100, 400)
164
+ for i in range(10):
165
+ filled_circle(C.magenta, A, radius=10)
166
+ A.left(10).forward(30)
167
+
168
+ # * information
169
+ # position — Return the point's current location (x,y), as a tuple.
170
+ # x, xcor — Return the point's x coordinate.
171
+ # y, ycor — Return the point's y coordinate
172
+ # heading — Return the point's heading
173
+ # distance — Return the distance between points
174
+ # towards — Return the angle towards point
175
+ # * deep copy
176
+ # copy — a clone of point
177
+ ```
178
+
179
+
180
+
181
+ # Transparency
182
+
183
+ Transparency is also straightforward via alpha parameter or RGBA color:
184
+
185
+ <img alt="transparent.png" src="https://raw.githubusercontent.com/ShashkovS/drawzero/master/docs/transparent.png" width="50%">
186
+
187
+ ```python
188
+ from drawzero import *
189
+
190
+ clear()
191
+ fill(C.black)
192
+
193
+ filled_circle('red', (100, 100), 20)
194
+ filled_circle('blue', (100, 110), 22, alpha=100) # <-- alpha
195
+ circle('red', (100, 100), 50, line_width=10)
196
+ circle((0, 255, 0, 50), (100, 110), 50, line_width=10) # <-- RGBA
197
+ ...
198
+ ```
199
+
200
+ <details>
201
+ <summary>Full code for transparency and line width example</summary>
202
+
203
+ ``` python
204
+ from drawzero import *
205
+
206
+ clear()
207
+ fill(C.black)
208
+
209
+ filled_circle('red', (100, 100), 20)
210
+ filled_circle('blue', (100, 110), 22, alpha=100)
211
+ circle('red', (100, 100), 50, line_width=10)
212
+ circle((0, 255, 0, 50), (100, 110), 50, line_width=10)
213
+ filled_rect(C.aquamarine, (200, 100), 100, 40)
214
+ filled_rect(C.darkmagenta, (210, 110), 100, 40, alpha=80)
215
+ rect(C.darkgoldenrod, (180, 90), 200, 80, line_width=10)
216
+ rect(C.hotpink, (190, 90), 200, 90, alpha=180, line_width=10)
217
+
218
+ line('red', 600, 400, 600, 990)
219
+ image('cat.png', (500, 500))
220
+ image('cat.png', (500, 800), width=200, alpha=128)
221
+ image('cat.png', (550, 850), width=200, alpha=128)
222
+
223
+ polygon('yellow', [(20, 300), (100, 340), (40, 260)], line_width=20)
224
+ polygon((0, 0, 255, 200), [(20, 300), (100, 340), (40, 260)], line_width=15)
225
+ polygon('red', [(20, 300), (100, 340), (40, 260)])
226
+
227
+ filled_polygon('burlywood', 200, 600, 130, 504, 20, 542, 20, 658, 130, 696)
228
+ filled_polygon(C.hotpink, 200, 700, 130, 604, 20, 642, 20, 758, 130, 796, alpha=100)
229
+
230
+ line(C.green, (700, 100), (800, 200))
231
+ line(C.green, (710, 100), (810, 200), line_width=5)
232
+ line(C.red, (820, 100), (720, 200), line_width=10, alpha=50)
233
+ line(C.blue, (830, 100), (730, 200), line_width=10, alpha=128)
234
+ ```
235
+ </details>
236
+
237
+
238
+ # Color gradients
239
+
240
+ <img alt="transparent.png" src="https://raw.githubusercontent.com/ShashkovS/drawzero/master/docs/ex_13.png" width="50%">
241
+
242
+ ```python
243
+ from drawzero import *
244
+
245
+
246
+ scale1 = Gradient([C.black, C.white], 0, 1000)
247
+ for x in range(0, 1000, 10):
248
+ filled_rect(scale1(x), (x, 0), 10, 100)
249
+ text(C.white, 'scale1 = Gradient([C.black, C.white], 0, 1000)', (50, 100), 48, '<^')
250
+
251
+ scale2 = Gradient([C.green, C.yellow, C.magenta, C.red], 0, 1000)
252
+ for x in range(0, 1000, 10):
253
+ filled_rect(scale2(x), (x, 200), 10, 100)
254
+ text(C.white, 'scale2 = Gradient([C.green, C.yellow, C.magenta, C.red], 0, 1000)', (50, 300), 32, '<^')
255
+
256
+ scale3 = Gradient([C.white, C.black, C.red, C.black, C.white], 200, 800)
257
+ for x in range(0, 1000, 10):
258
+ filled_rect(scale3(x), (x, 400), 10, 100)
259
+ text(C.white, 'scale3 = Gradient([C.white, C.black, C.red, C.black, C.white], 200, 800)', (50, 500), 32, '<^')
260
+ ```
261
+
262
+
263
+
264
+ # Keyboard and mouse events
265
+
266
+ Process keyboard events in two ways: check if key is pressed via `get_keys_pressed()` or run throw `keysdown` or `keysup` events:
267
+
268
+ ``` python
269
+ from drawzero import *
270
+
271
+ upper_text = 'Typed: '
272
+ SIZE = 20
273
+ x = y = 500 - SIZE // 2
274
+
275
+ while True:
276
+ # Mouse buttons events
277
+ if mousebuttonsdown:
278
+ x, y = mousebuttonsdown[0].pos
279
+ # Keys which are still pressed
280
+ keys = get_keys_pressed()
281
+ if keys[K.UP] or keys[K.w]:
282
+ y -= 5
283
+ if keys[K.DOWN] or keys[K.s]:
284
+ y += 5
285
+ if keys[K.LEFT] or keys[K.a]:
286
+ x -= 5
287
+ if keys[K.RIGHT] or keys[K.d]:
288
+ x += 5
289
+ # Keyboard events
290
+ for ev in keysdown:
291
+ if ev.unicode:
292
+ upper_text += ev.unicode
293
+
294
+ # Redraw everything
295
+ clear()
296
+ filled_rect(C.red, x, y, SIZE, SIZE)
297
+ text(C.white, upper_text, (100, 5))
298
+ filled_circle(C.yellow, mouse_pos(), 3)
299
+ tick()
300
+ ```
301
+
302
+ <img alt="keyboard_and_mouse_events.gif" src="https://raw.githubusercontent.com/ShashkovS/drawzero/master/docs/keyboard_and_mouse_events.gif" width="50%">
303
+
304
+
305
+
306
+ # Installation
307
+
308
+ In a Terminal window, type:
309
+ ```shell
310
+ pip install drawzero --upgrade --user
311
+ ```
312
+
313
+
314
+ Or run the following program:
315
+
316
+ ```python
317
+ import os, sys
318
+ python = sys.executable
319
+ user = '--user' if 'venv' not in python and 'virtualenvs' not in python else ''
320
+ cmd = f'"{python}" -m pip install drawzero --upgrade {user}'
321
+ os.system(cmd)
322
+ from drawzero import *
323
+ ```
324
+
325
+ # [Contributing](CONTRIBUTING.md)