diff --git a/.vscode/settings.json b/.vscode/settings.json index f13778cf..05ac892c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "workbench.colorTheme": "Default Light+", + "workbench.colorTheme": "Default Dark Modern", "notebook.lineNumbers": "on", "files.encoding": "utf8", "java.inlayHints.parameterNames.enabled": "none", diff --git a/Python/04 Funcions/Teoria.ipynb b/Python/04 Funcions/Teoria.ipynb index bfb52184..4f85b171 100644 --- a/Python/04 Funcions/Teoria.ipynb +++ b/Python/04 Funcions/Teoria.ipynb @@ -757,7 +757,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git a/Python/06 Control de fluxe (if else)/Teoria.ipynb b/Python/06 Control de fluxe (if else)/Teoria.ipynb index 69877ca4..6a0389af 100644 --- a/Python/06 Control de fluxe (if else)/Teoria.ipynb +++ b/Python/06 Control de fluxe (if else)/Teoria.ipynb @@ -460,7 +460,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git a/Python/08 Bucles (while for)/A while.ipynb b/Python/08 Bucles (while for)/A while.ipynb index f88f9dce..db99dd0c 100644 --- a/Python/08 Bucles (while for)/A while.ipynb +++ b/Python/08 Bucles (while for)/A while.ipynb @@ -353,7 +353,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git a/Python/11 Dades/A Llistes.ipynb b/Python/11 Dades/A Llistes.ipynb index 91ffaf60..2247d633 100644 --- a/Python/11 Dades/A Llistes.ipynb +++ b/Python/11 Dades/A Llistes.ipynb @@ -525,9 +525,19 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "El producte a la posicó 1 és: ['Escombra', 5.49]\n", + "El nom del producte a la posicó 1 és: Escombra\n", + "El preu del producte a la posicó 1 és: 5.49\n" + ] + } + ], "source": [ "# Exemple d'accedir a les posicions d'una matriu:\n", "productes = [\n", @@ -549,9 +559,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "El producte 'Fregona' costa 10.99 €\n", + "El producte 'Escombra' costa 5.49 €\n", + "El producte 'Galleda' costa 8.95 €\n", + "El producte 'Drap' costa 2.99 €\n", + "El producte 'Fregall' costa 6.75 €\n", + "Suma total: 35.17\n", + "Mitjana: 7.03\n" + ] + } + ], "source": [ "# Exemple d'escriure una elements d'una matriu\n", "productes = [\n", @@ -602,7 +626,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -774,7 +798,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git "a/Python/11 Dades/B Llistes avan\303\247ades.ipynb" "b/Python/11 Dades/B Llistes avan\303\247ades.ipynb" index eeb8e844..f9acc424 100644 --- "a/Python/11 Dades/B Llistes avan\303\247ades.ipynb" +++ "b/Python/11 Dades/B Llistes avan\303\247ades.ipynb" @@ -378,7 +378,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.5" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git a/Python/50 Dibuix/Teoria.ipynb b/Python/50 Dibuix/Teoria.ipynb index 90791ec9..061a603c 100644 --- a/Python/50 Dibuix/Teoria.ipynb +++ b/Python/50 Dibuix/Teoria.ipynb @@ -1 +1 @@ -{"cells":[{"cell_type":"markdown","metadata":{},"source":["
\n","
\n","

© Albert Palacios Jiménez, 2023

\n","
\n","
\n"," \"Logo\n","
\n","
\n","
"]},{"cell_type":"markdown","metadata":{"id":"qDQPPM3dtsAZ"},"source":["# Dibuix\n","\n","Molts llenguatges de programació tenen eines o llibreries, per obrir finestres, fer-hi dibuixos o mostrar-hi imatges.\n","\n","Per poder fer anar aquestes eines, calen coneixements bàsics de programació: variables, funcions, condicions, bucles, ...\n","\n","En Python hi ha moltes llibreries, però una de les més senzilles és **pyGame**.\n","\n","Instal·lació:\n","```bash\n","pip install pygame\n","pip install ipykernel -U --user --force-reinstall\n","```\n","\n","A Linux:\n","```bash\n","sudo apt install install python3-pygame\n","```\n","\n","A macOS amb *brew* o també a Linux:\n","```bash\n","python3 -m pip install pygame --break-system-package\n","python3 -m pip install ipykernel -U --user --force-reinstall --break-system-package\n","```"]},{"cell_type":"markdown","metadata":{},"source":["## Finestres i aplicacions\n","\n","Per poder dibuixar, primer necessitem una finestra d'aplicació.\n","\n","```python\n","screen = pygame.display.set_mode((640, 480))\n","pygame.display.set_caption('Window Title')\n","```\n","\n","Però un cop tenim la finestra, s'ha de definir què fer amb ella. És a dir, el **bucle de l'aplicació**\n","\n","```python\n","def main():\n"," is_looping = True\n","\n"," while is_looping:\n"," is_looping = app_events()\n"," app_run()\n"," app_draw()\n","\n"," clock.tick(30) # Limitar a 30 FPS\n","\n"," # Fora del bucle, tancar l'aplicació\n"," pygame.quit()\n"," sys.exit()\n","```"]},{"cell_type":"markdown","metadata":{},"source":["### Exemple 000"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple000.py')"]},{"cell_type":"code","execution_count":7,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple000.py')"]},{"cell_type":"markdown","metadata":{},"source":["# Dibuix\n","\n","Un cop tenim definida la finesta, i el bucle de l'aplciació, ja es poden dibuixar cosses al a funció **app_draw**\n","\n","```python\n","def app_draw():\n"," \n"," # Pintar el fons de blanc\n"," screen.fill(WHITE)\n","\n"," # Escriure un text de prova\n"," font = pygame.font.SysFont(\"Arial\", 55)\n"," text = font.render('Hello World!', True, BLACK)\n"," screen.blit(text, (50, 200))\n","\n"," # Actualitzar el dibuix a la finestra\n"," pygame.display.update()\n","```"]},{"cell_type":"markdown","metadata":{},"source":["## Ordre de dibuix (canvas)\n","\n","Normalment les llibreries de dibuix funcionen com un quadre *(canvas)*, són una superfície a la que vas dibuixant. I el què dibuixes últim, queda per damunt de tot el què ja has dibuixat.\n","\n","
\n","
\"\"\n","
\n","
\n","
"]},{"cell_type":"markdown","metadata":{},"source":["## Eix de coordenades\n","\n","Indiquem a quina posició volem dibuixar a través de coordenades X,Y.\n","\n","A **pygame** les coordenades són **\"top/left\"**, el què vol dir que el 0,0 de la finestra és la posició de dalt a l'equerra.\n","\n","A l'exemple de la imatge, les coordenades són (x = 80, y = 50):\n","\n","
\n","
\"\"\n","
\n","
\n","
"]},{"cell_type":"markdown","metadata":{},"source":["## Dibuix basic\n","\n","Pygame proporciona diverses funcions per dibuixar formes bàsiques:\n","```python\n","# Una línia entre dos punts.\n","pygame.draw.line(screen, color, start_pos, end_pos, width)\n","\n","# Un rectangle \n","pygame.draw.rect(screen, color, (x, y, width, height))\n","\n","# Un cercle\n","pygame.draw.circle(screen, GREEN, (x, y), radius)\n","\n","# Una el·lipse dins d'un rectangle delimitador.\n","pygame.draw.ellipse(screen, color, (x, y, width, height))\n","\n","# Un arc dins d'un rectangle delimitador.\n","pygame.draw.arc(screen, color, (x, y, width, height), start_angle, end_angle, width)\n","\n","# Un polígon connectant una sèrie de punts.\n","pygame.draw.polygon(screen, color, [(x1, y1), (x2, y2), (x3, y3)], width)\n","\n","# Una sèrie de línies connectades entre diversos punts.\n","pygame.draw.lines(screen, color, closed, point_list, width)\n","```\n"]},{"cell_type":"markdown","metadata":{},"source":["### Exemple 001\n","\n","Dibuix de formes bàsiques, fixar-se en com s'escriuen les coordenades i en l'ordre de dibuix."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple001.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":19,"metadata":{},"outputs":[],"source":["# Fer anar el codi d'exemple\n","import utils; utils.run_code('./exemple001.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 000\n","\n","Modifica la funció **app_draw** de l'arxiu **\"./exercici000.py\"** per fer el següent dibuix, a partir de dos bucles **for**\n","\n","**Nota**: La mida de gruix de la línia és 5\n","\n","
\n","
\"\"\n","
\n","
"]},{"cell_type":"code","execution_count":29,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici000.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Colors\n","\n","**pyGame** permet fer dibuixos amb colors RGB (Red, Green Blue)\n","\n","Els colors són **tuples** de tres paràmetres entre 0 i 255, on:\n","\n","- El primer valor representa el vermell (Red)\n","- El segon valor representa el verd (Green)\n","- El tercer valor representa el blau (Blue)\n","\n","Així, els colors clàssics són:\n","\n"," WHITE = (255, 255, 255) \n"," BLACK = (0, 0, 0) \n"," RED = (255, 0, 0) \n"," GREEN = (0, 255, 0) \n"," BLUE = (0, 0, 255) \n"," YELLOW = (255, 255, 0) \n"," CYAN = (0, 255, 255) \n"," MAGENTA = (255, 0, 255) \n"," ORANGE = (255, 165, 0) \n"," PURPLE = (128, 0, 128) \n"," PINK = (255, 192, 203) \n"," GRAY = (128, 128, 128) \n"," BROWN = (165, 42, 42) \n"," NAVY = (0, 0, 128) \n"," TEAL = (0, 128, 128) \n"," LIME = (0, 255, 0) \n"," INDIGO = (75, 0, 130) \n"," VIOLET = (238, 130, 238)\n"]},{"cell_type":"markdown","metadata":{},"source":["## Relleus i Emplenats\n","\n","Hi ha dos modes de dibuix:\n","\n","- Emplenat (**fill**): És el color o patró que omple l’interior d'una forma. Per exemple, si dibuixes un cercle i l'emplenes de color blau, tot l'interior del cercle serà blau.\n","\n","- Relleu (**stroke**): És el contorn o línia exterior de la forma, que pot tenir un color i gruix diferents. Si dibuixes un cercle amb relleu vermell de 5 píxels, el contorn del cercle serà vermell amb una amplada de 5 píxels, però l'interior pot estar buit o emplenat d’un altre color.\n","\n","Aquestes propietats permeten que una forma tingui un aspecte amb un interior (emplenat) diferent del seu contorn (relleu)"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple002.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":58,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple002.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 001\n","\n","Al codi **\"exercici001.py\"**, modifica la funció **app_draw** per fer el següent dibuix:\n","\n","**Nota**: Per dibuixar l'arc taronja, fer servir la següent informació:\n","\n","- Coordenades: x = 400, y = 250\n","- Mida: ample = 200, alt = 100\n","- Angle inicial: math.radians(45)\n","- Angle final: math.radians(180)\n","- Gruix: 5\n","\n","
\n","
\"\"\n","
\n","
"]},{"cell_type":"code","execution_count":26,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici001.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Texts\n","\n","Per dibuixar un text cal seguir els següents passos:\n","\n","- Definir un estil de font\n","- Definir un text (si es pot, fora del bucle)\n","- Dibuixar el text (dins del bucle)\n","\n","**Nota:** Com que l'estil de font, i el text són variables, millor posar-les fora del bucle de l'aplicació."]},{"cell_type":"markdown","metadata":{},"source":["## Imatges\n","\n","Per dibuixar imatges cal\n","\n","- Carregar la imatge en una variable\n","- Dibuixar la imatge (dins del bucle)\n","\n","**Nota**: Quan es carrega la imatge se li pot canviar la mida, amb *pygame.transform.smoothscale*"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple003.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":58,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple003.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Events, lògica i dibuix\n","\n","Cal entendre que quan fem aplicacions gràfiques, el bucle de l'aplicació es divideix en parts:\n","\n","- **Obtenció d'events**: és a dir la informació que rep l'aplicació\n","\n","- **Càlculs lògics**: els que defineixen l'estat de l'aplicació, i modifiquen les variables\n","\n","- **Dibuix**: a partir dels càlculs anteriors dibuixar el què correspon\n","\n","**Important**: Separar la lògica dels càlculs de les instruccions de dibuix, permet que les instruccions que s'envien a la **tarjeta gràfica** estiguin més optimitzades, i l'aplicació funcioni més ràpid. \n","\n","Quan es posa codi per calcular la lògica dins de la funció de dibuix, les instruccions que s'envien a la tarja gràfica queden fragmentades, i no es poden optimitzar."]},{"cell_type":"markdown","metadata":{},"source":["## Animacions \n","\n","Les animacions permeten canviar el valor d'una variable en el temps, per tal de fer efectes de moviment o de canvi d'estat.\n","\n","Per tal que les animacions siguin coherents en tots els equips (sempre triguin el mateix), no canviarem els valors de les animacions en funció dels cops que hem dibuixat sinó **en funció del temps** que triquem a dibuixar."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple (comprovar si l'usuari vol tancar l'aplicació per sortir del bucle)\n","import utils; utils.show_code('./exemple004.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple (comprovar si l'usuari vol tancar l'aplicació per sortir del bucle)\n","import utils; utils.show_code('./exemple004.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":49,"metadata":{},"outputs":[],"source":["# Codi de l'exemple (canviar el valor de la variable posició X)\n","import utils; utils.run_code('./exemple004.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 002\n","\n","La següent funció, dona una posició X,Y al perímetre d'un cercle a partir dels paràmetres:\n","\n","- Centre del cercle {\"x\": x, \"y\": y}\n","- Radi del cercle\n","- Angle (en graus)"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["import utils\n","\n","utils.point_on_circle(center, radius, angle_degrees)"]},{"cell_type":"markdown","metadata":{},"source":["Al codi **\"exercici002.py\"**, fes l'animació d'una linia que dóna voltes relatives a un cercle:\n","\n","**Nota**: Fes que la velocitat sigui: *50 * delta_time*\n","\n","
\n","\n","
\n","
"]},{"cell_type":"code","execution_count":4,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici002.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Events de teclat\n","\n","Els events són **missatges que el programa rep quan passa alguna cosa**, normalment quan l'usuari interacciona amb l'aplicació a través del mouse o el teclat.\n","\n","Hi ha molts tipus d'events: de la finestra, del mouse, del teclat, ...\n","\n","Amb la informació dels events, podem modificar variables del nostre codi (i conseqüentment modificar el dibuix)"]},{"cell_type":"markdown","metadata":{},"source":["### Exemple 005\n","\n","Els **events de teclat** ens avisen quan s'apreta o s'allibera una tecla. Cal tenir en compte:\n","\n","- Múltiples tecles poden estar apretades al mateix temps\n","- Hi ha tecles de modificació com *control*, *alt*, *command* ... que canvien el comportament de les tecles\n","\n","No s'ha de confondre l'**event d'apretar o aixecar** una tecla:\n","\n","- pygame.KEYDOWN\n","- pygame.KEYUP\n","\n","Amb les **tecles** 'amunt' i 'avall'\n","\n","- pygame.K_UP\n","- pygame.K_DOWN"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple005.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple005.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple005.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":67,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple005.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 003\n","\n","Al codi **\"exercici003.py\"**, arregla l'exemple anterior perquè el quadre taronja no surti mai dels limits del quadre blau.\n","\n","
\n","
\"\"\n","
\n","
"]},{"cell_type":"code","execution_count":70,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici003.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Events de ratolí\n","\n","Al igual que el teclat els events de ratolí ens avisen de:\n","\n","- La posició del mouse\n","- Si s'apreta algún botó del ratolí\n","- Si s'allibera algún botó del ratolí"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple006.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple006.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple006.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":108,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.run_code('./exemple006.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 004\n","\n","Al codi **\"exercici004.py\"**, arregla l'exemple anterior perquè l'ull dret estigui dins dels seus limits"]},{"cell_type":"code","execution_count":107,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici004.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Botons del ratolí apretats o alliberats\n","\n","Al igual que amb el teclat, es produeix un event quan s'apreta o allibera un botó del ratolí.\n","\n","Amb aquest event, podem saber les coordenades on s'ha fet 'click'."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple007.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple007.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple007.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":132,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.run_code('./exemple007.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Arrossegar objectes\n","\n","Per arrossegar s'han de seguir diversos passos:\n","\n","- Capturar els events de botons de mouse\n","- Comprovar si es fa click a sobre d'un objecte o a fora\n","- Apuntar la diferència entre la posició on es fa click i l'origen de dibuix de l'objecte\n","- Moure l'objecte amb el ratolí (segons la diferència anterior)\n","- Alliberar l'arrosegament quan s'allibera el botó del ratolí\n","\n","**Nota:** Per guardar la diferència entre la posició on s'ha fet click i l'origen del dibuix, tenim una variable **\"drag_offset\"**\n","\n"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple008.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple008.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple008.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":133,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.run_code('./exemple008.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 005\n","\n","Al codi **\"exercici005.py\"**, modifica l'exemple anterior per tal que quan els dos poligons estàn sobreposats i a més s'estàn arrossegant, es dibuixin tots dos de color taronja."]},{"cell_type":"code","execution_count":130,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici005.py')"]}],"metadata":{"colab":{"authorship_tag":"ABX9TyPVbRvc9ZXjdvEcZF7RaE6C","provenance":[],"toc_visible":true},"kernelspec":{"display_name":"Python 3","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.5"}},"nbformat":4,"nbformat_minor":0} +{"cells":[{"cell_type":"markdown","metadata":{},"source":["
\n","
\n","

© Albert Palacios Jiménez, 2023

\n","
\n","
\n"," \"Logo\n","
\n","
\n","
"]},{"cell_type":"markdown","metadata":{"id":"qDQPPM3dtsAZ"},"source":["# Dibuix\n","\n","Molts llenguatges de programació tenen eines o llibreries, per obrir finestres, fer-hi dibuixos o mostrar-hi imatges.\n","\n","Per poder fer anar aquestes eines, calen coneixements bàsics de programació: variables, funcions, condicions, bucles, ...\n","\n","En Python hi ha moltes llibreries, però una de les més senzilles és **pyGame**.\n","\n","Instal·lació:\n","```bash\n","pip install pygame\n","pip install ipykernel -U --user --force-reinstall\n","```\n","\n","A Linux:\n","```bash\n","sudo apt install install python3-pygame\n","```\n","\n","A macOS amb *brew* o també a Linux:\n","```bash\n","python3 -m pip install pygame --break-system-package\n","python3 -m pip install ipykernel -U --user --force-reinstall --break-system-package\n","```"]},{"cell_type":"markdown","metadata":{},"source":["## Finestres i aplicacions\n","\n","Per poder dibuixar, primer necessitem una finestra d'aplicació.\n","\n","```python\n","screen = pygame.display.set_mode((640, 480))\n","pygame.display.set_caption('Window Title')\n","```\n","\n","Però un cop tenim la finestra, s'ha de definir què fer amb ella. És a dir, el **bucle de l'aplicació**\n","\n","```python\n","def main():\n"," is_looping = True\n","\n"," while is_looping:\n"," is_looping = app_events()\n"," app_run()\n"," app_draw()\n","\n"," clock.tick(30) # Limitar a 30 FPS\n","\n"," # Fora del bucle, tancar l'aplicació\n"," pygame.quit()\n"," sys.exit()\n","```"]},{"cell_type":"markdown","metadata":{},"source":["### Exemple 000"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple000.py')"]},{"cell_type":"code","execution_count":7,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple000.py')"]},{"cell_type":"markdown","metadata":{},"source":["# Dibuix\n","\n","Un cop tenim definida la finesta, i el bucle de l'aplciació, ja es poden dibuixar cosses al a funció **app_draw**\n","\n","```python\n","def app_draw():\n"," \n"," # Pintar el fons de blanc\n"," screen.fill(WHITE)\n","\n"," # Escriure un text de prova\n"," font = pygame.font.SysFont(\"Arial\", 55)\n"," text = font.render('Hello World!', True, BLACK)\n"," screen.blit(text, (50, 200))\n","\n"," # Actualitzar el dibuix a la finestra\n"," pygame.display.update()\n","```"]},{"cell_type":"markdown","metadata":{},"source":["## Ordre de dibuix (canvas)\n","\n","Normalment les llibreries de dibuix funcionen com un quadre *(canvas)*, són una superfície a la que vas dibuixant. I el què dibuixes últim, queda per damunt de tot el què ja has dibuixat.\n","\n","
\n","
\"\"\n","
\n","
\n","
"]},{"cell_type":"markdown","metadata":{},"source":["## Eix de coordenades\n","\n","Indiquem a quina posició volem dibuixar a través de coordenades X,Y.\n","\n","A **pygame** les coordenades són **\"top/left\"**, el què vol dir que el 0,0 de la finestra és la posició de dalt a l'equerra.\n","\n","A l'exemple de la imatge, les coordenades són (x = 80, y = 50):\n","\n","
\n","
\"\"\n","
\n","
\n","
"]},{"cell_type":"markdown","metadata":{},"source":["## Dibuix basic\n","\n","Pygame proporciona diverses funcions per dibuixar formes bàsiques:\n","```python\n","# Una línia entre dos punts.\n","pygame.draw.line(screen, color, start_pos, end_pos, width)\n","\n","# Un rectangle \n","pygame.draw.rect(screen, color, (x, y, width, height))\n","\n","# Un cercle\n","pygame.draw.circle(screen, GREEN, (x, y), radius)\n","\n","# Una el·lipse dins d'un rectangle delimitador.\n","pygame.draw.ellipse(screen, color, (x, y, width, height))\n","\n","# Un arc dins d'un rectangle delimitador.\n","pygame.draw.arc(screen, color, (x, y, width, height), start_angle, end_angle, width)\n","\n","# Un polígon connectant una sèrie de punts.\n","pygame.draw.polygon(screen, color, [(x1, y1), (x2, y2), (x3, y3)], width)\n","\n","# Una sèrie de línies connectades entre diversos punts.\n","pygame.draw.lines(screen, color, closed, point_list, width)\n","```\n"]},{"cell_type":"markdown","metadata":{},"source":["### Exemple 001\n","\n","Dibuix de formes bàsiques, fixar-se en com s'escriuen les coordenades i en l'ordre de dibuix."]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"data":{"text/markdown":["```python\n","def app_draw():\n"," # Pintar el fons de blanc\n"," screen.fill(WHITE)\n","\n"," # Dibuixar la graella de coordenades (llibreria utils)\n"," utils.draw_grid(pygame, screen, 50)\n","\n"," # Dibuixar un rectangle vermell a la posició (150, 200) de mida (75, 100)\n"," pygame.draw.rect(screen, RED, (150, 200, 75, 100))\n","\n"," # Dibuixar un cercle verd a la posició (100, 150) de radi 10\n"," pygame.draw.circle(screen, GREEN, (100, 150), 50)\n","\n"," # Dibuixar una linia des de l'origen del rectangle fins al centre del cercle\n"," pygame.draw.line(screen, BLUE, (150, 200), (100, 150), 5)\n","\n"," # Actualitzar el dibuix a la finestra\n"," pygame.display.update()\n","```"],"text/plain":[""]},"metadata":{},"output_type":"display_data"}],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple001.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":3,"metadata":{},"outputs":[{"name":"stderr","output_type":"stream","text":[":488: RuntimeWarning: Your system is avx2 capable but pygame was not built with support for it. The performance of some of your blits could be adversely affected. Consider enabling compile time detection with environment variables like PYGAME_DETECT_AVX2=1 if you are compiling without cross compilation.\n"]}],"source":["# Fer anar el codi d'exemple\n","import utils; utils.run_code('./exemple001.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 000\n","\n","Modifica la funció **app_draw** de l'arxiu **\"./exercici000.py\"** per fer el següent dibuix, a partir de dos bucles **for**\n","\n","**Nota**: La mida de gruix de la línia és 5\n","\n","
\n","
\"\"\n","
\n","
"]},{"cell_type":"code","execution_count":29,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici000.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Colors\n","\n","**pyGame** permet fer dibuixos amb colors RGB (Red, Green Blue)\n","\n","Els colors són **tuples** de tres paràmetres entre 0 i 255, on:\n","\n","- El primer valor representa el vermell (Red)\n","- El segon valor representa el verd (Green)\n","- El tercer valor representa el blau (Blue)\n","\n","Així, els colors clàssics són:\n","\n"," WHITE = (255, 255, 255) \n"," BLACK = (0, 0, 0) \n"," RED = (255, 0, 0) \n"," GREEN = (0, 255, 0) \n"," BLUE = (0, 0, 255) \n"," YELLOW = (255, 255, 0) \n"," CYAN = (0, 255, 255) \n"," MAGENTA = (255, 0, 255) \n"," ORANGE = (255, 165, 0) \n"," PURPLE = (128, 0, 128) \n"," PINK = (255, 192, 203) \n"," GRAY = (128, 128, 128) \n"," BROWN = (165, 42, 42) \n"," NAVY = (0, 0, 128) \n"," TEAL = (0, 128, 128) \n"," LIME = (0, 255, 0) \n"," INDIGO = (75, 0, 130) \n"," VIOLET = (238, 130, 238)\n"]},{"cell_type":"markdown","metadata":{},"source":["## Relleus i Emplenats\n","\n","Hi ha dos modes de dibuix:\n","\n","- Emplenat (**fill**): És el color o patró que omple l’interior d'una forma. Per exemple, si dibuixes un cercle i l'emplenes de color blau, tot l'interior del cercle serà blau.\n","\n","- Relleu (**stroke**): És el contorn o línia exterior de la forma, que pot tenir un color i gruix diferents. Si dibuixes un cercle amb relleu vermell de 5 píxels, el contorn del cercle serà vermell amb una amplada de 5 píxels, però l'interior pot estar buit o emplenat d’un altre color.\n","\n","Aquestes propietats permeten que una forma tingui un aspecte amb un interior (emplenat) diferent del seu contorn (relleu)"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple002.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":58,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple002.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 001\n","\n","Al codi **\"exercici001.py\"**, modifica la funció **app_draw** per fer el següent dibuix:\n","\n","**Nota**: Per dibuixar l'arc taronja, fer servir la següent informació:\n","\n","- Coordenades: x = 400, y = 250\n","- Mida: ample = 200, alt = 100\n","- Angle inicial: math.radians(45)\n","- Angle final: math.radians(180)\n","- Gruix: 5\n","\n","
\n","
\"\"\n","
\n","
"]},{"cell_type":"code","execution_count":26,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici001.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Texts\n","\n","Per dibuixar un text cal seguir els següents passos:\n","\n","- Definir un estil de font\n","- Definir un text (si es pot, fora del bucle)\n","- Dibuixar el text (dins del bucle)\n","\n","**Nota:** Com que l'estil de font, i el text són variables, millor posar-les fora del bucle de l'aplicació."]},{"cell_type":"markdown","metadata":{},"source":["## Imatges\n","\n","Per dibuixar imatges cal\n","\n","- Carregar la imatge en una variable\n","- Dibuixar la imatge (dins del bucle)\n","\n","**Nota**: Quan es carrega la imatge se li pot canviar la mida, amb *pygame.transform.smoothscale*"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple003.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":58,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple003.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Events, lògica i dibuix\n","\n","Cal entendre que quan fem aplicacions gràfiques, el bucle de l'aplicació es divideix en parts:\n","\n","- **Obtenció d'events**: és a dir la informació que rep l'aplicació\n","\n","- **Càlculs lògics**: els que defineixen l'estat de l'aplicació, i modifiquen les variables\n","\n","- **Dibuix**: a partir dels càlculs anteriors dibuixar el què correspon\n","\n","**Important**: Separar la lògica dels càlculs de les instruccions de dibuix, permet que les instruccions que s'envien a la **tarjeta gràfica** estiguin més optimitzades, i l'aplicació funcioni més ràpid. \n","\n","Quan es posa codi per calcular la lògica dins de la funció de dibuix, les instruccions que s'envien a la tarja gràfica queden fragmentades, i no es poden optimitzar."]},{"cell_type":"markdown","metadata":{},"source":["## Animacions \n","\n","Les animacions permeten canviar el valor d'una variable en el temps, per tal de fer efectes de moviment o de canvi d'estat.\n","\n","Per tal que les animacions siguin coherents en tots els equips (sempre triguin el mateix), no canviarem els valors de les animacions en funció dels cops que hem dibuixat sinó **en funció del temps** que triquem a dibuixar."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple (comprovar si l'usuari vol tancar l'aplicació per sortir del bucle)\n","import utils; utils.show_code('./exemple004.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple (comprovar si l'usuari vol tancar l'aplicació per sortir del bucle)\n","import utils; utils.show_code('./exemple004.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":49,"metadata":{},"outputs":[],"source":["# Codi de l'exemple (canviar el valor de la variable posició X)\n","import utils; utils.run_code('./exemple004.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 002\n","\n","La següent funció, dona una posició X,Y al perímetre d'un cercle a partir dels paràmetres:\n","\n","- Centre del cercle {\"x\": x, \"y\": y}\n","- Radi del cercle\n","- Angle (en graus)"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["import utils\n","\n","utils.point_on_circle(center, radius, angle_degrees)"]},{"cell_type":"markdown","metadata":{},"source":["Al codi **\"exercici002.py\"**, fes l'animació d'una linia que dóna voltes relatives a un cercle:\n","\n","**Nota**: Fes que la velocitat sigui: *50 * delta_time*\n","\n","
\n","\n","
\n","
"]},{"cell_type":"code","execution_count":4,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici002.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Events de teclat\n","\n","Els events són **missatges que el programa rep quan passa alguna cosa**, normalment quan l'usuari interacciona amb l'aplicació a través del mouse o el teclat.\n","\n","Hi ha molts tipus d'events: de la finestra, del mouse, del teclat, ...\n","\n","Amb la informació dels events, podem modificar variables del nostre codi (i conseqüentment modificar el dibuix)"]},{"cell_type":"markdown","metadata":{},"source":["### Exemple 005\n","\n","Els **events de teclat** ens avisen quan s'apreta o s'allibera una tecla. Cal tenir en compte:\n","\n","- Múltiples tecles poden estar apretades al mateix temps\n","- Hi ha tecles de modificació com *control*, *alt*, *command* ... que canvien el comportament de les tecles\n","\n","No s'ha de confondre l'**event d'apretar o aixecar** una tecla:\n","\n","- pygame.KEYDOWN\n","- pygame.KEYUP\n","\n","Amb les **tecles** 'amunt' i 'avall'\n","\n","- pygame.K_UP\n","- pygame.K_DOWN"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple005.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple005.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple005.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":67,"metadata":{},"outputs":[],"source":["# Fer anar l'exemple\n","import utils; utils.run_code('./exemple005.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 003\n","\n","Al codi **\"exercici003.py\"**, arregla l'exemple anterior perquè el quadre taronja no surti mai dels limits del quadre blau.\n","\n","
\n","
\"\"\n","
\n","
"]},{"cell_type":"code","execution_count":70,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici003.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Events de ratolí\n","\n","Al igual que el teclat els events de ratolí ens avisen de:\n","\n","- La posició del mouse\n","- Si s'apreta algún botó del ratolí\n","- Si s'allibera algún botó del ratolí"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple006.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple006.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple006.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":108,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.run_code('./exemple006.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 004\n","\n","Al codi **\"exercici004.py\"**, arregla l'exemple anterior perquè l'ull dret estigui dins dels seus limits"]},{"cell_type":"code","execution_count":107,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici004.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Botons del ratolí apretats o alliberats\n","\n","Al igual que amb el teclat, es produeix un event quan s'apreta o allibera un botó del ratolí.\n","\n","Amb aquest event, podem saber les coordenades on s'ha fet 'click'."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple007.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple007.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple007.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":132,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.run_code('./exemple007.py')"]},{"cell_type":"markdown","metadata":{},"source":["## Arrossegar objectes\n","\n","Per arrossegar s'han de seguir diversos passos:\n","\n","- Capturar els events de botons de mouse\n","- Comprovar si es fa click a sobre d'un objecte o a fora\n","- Apuntar la diferència entre la posició on es fa click i l'origen de dibuix de l'objecte\n","- Moure l'objecte amb el ratolí (segons la diferència anterior)\n","- Alliberar l'arrosegament quan s'allibera el botó del ratolí\n","\n","**Nota:** Per guardar la diferència entre la posició on s'ha fet click i l'origen del dibuix, tenim una variable **\"drag_offset\"**\n","\n"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple008.py', function_name='app_events')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple008.py', function_name='app_run')"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.show_code('./exemple008.py', function_name='app_draw')"]},{"cell_type":"code","execution_count":133,"metadata":{},"outputs":[],"source":["# Codi de l'exemple\n","import utils; utils.run_code('./exemple008.py')"]},{"cell_type":"markdown","metadata":{},"source":["### Exercici 005\n","\n","Al codi **\"exercici005.py\"**, modifica l'exemple anterior per tal que quan els dos poligons estàn sobreposats i a més s'estàn arrossegant, es dibuixin tots dos de color taronja."]},{"cell_type":"code","execution_count":130,"metadata":{},"outputs":[],"source":["# Fer anar el codi de l'exercici\n","import utils; utils.run_code('./exercici005.py')"]}],"metadata":{"colab":{"authorship_tag":"ABX9TyPVbRvc9ZXjdvEcZF7RaE6C","provenance":[],"toc_visible":true},"kernelspec":{"display_name":"Python 3","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.3"}},"nbformat":4,"nbformat_minor":0} diff --git a/Python/50 Dibuix/exemple003.py b/Python/50 Dibuix/exemple003.py index 44d42f07..59f35c25 100755 --- a/Python/50 Dibuix/exemple003.py +++ b/Python/50 Dibuix/exemple003.py @@ -27,10 +27,7 @@ def main(): global font, text, image - is_looping = True - - # Definir el text - font = pygame.font.SysFont("Arial", 55) + is_looping = Truetext = font.render('Hello Arial!', True, BLACK) text = font.render('Hello Arial!', True, BLACK) # Carregar la imatge diff --git a/Python/50 Dibuix/exercici_matriu_sgd.py b/Python/50 Dibuix/exercici_matriu_sgd.py new file mode 100644 index 00000000..8d7cdede --- /dev/null +++ b/Python/50 Dibuix/exercici_matriu_sgd.py @@ -0,0 +1,74 @@ +import math +import os +os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" +import pygame +import sys +import utils +import random + +# Definir colors +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) +RED = (255, 0, 0) +GREEN = (0, 255, 0) +BLUE = (0, 0, 255) +PURPLE = (128, 0, 128) +ORANGE = (255, 165, 0) + +pygame.init() +clock = pygame.time.Clock() + +font = pygame.font.SysFont("Arial", 55) +#Matriz +matriz = [[str(random.randint(1,9)) for _ in range(10)] for _ in range(10)] + + +# Definir la finestra +screen = pygame.display.set_mode((640, 480)) +pygame.display.set_caption('Window Title') + +# Bucle de l'aplicació +def main(): + is_looping = True + + while is_looping: + is_looping = app_events() + app_run() + app_draw() + + clock.tick(60) # Limitar a 60 FPS + + # Fora del bucle, tancar l'aplicació + pygame.quit() + sys.exit() + +# Gestionar events +def app_events(): + for event in pygame.event.get(): + if event.type == pygame.QUIT: # Botó tancar finestra + return False + return True + +# Fer càlculs +def app_run(): + pass + +# Dibuixar +def app_draw(): + # Pintar el fons de blanc + screen.fill(WHITE) + + # Dibuixar la graella de coordenades (llibreria utils) + utils.draw_grid(pygame, screen, 50) + + # Actualitzar el dibuix a la finestra + pygame.display.update() + + text = font.render('Hello Arial!', True, BLACK) + + #Mostrar Texto + screen.blit(text, (50, 50)) + +if __name__ == "__main__": + main() + diff --git a/Python/52 Deures D0/Ejercicio0_pygame_Steephen_Garcia.py b/Python/52 Deures D0/Ejercicio0_pygame_Steephen_Garcia.py new file mode 100644 index 00000000..e6b6a59b --- /dev/null +++ b/Python/52 Deures D0/Ejercicio0_pygame_Steephen_Garcia.py @@ -0,0 +1,71 @@ +###Ejercicio 0### +import math +import os +os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" +import pygame +import sys +import utils + +# Definir colors +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) +GRAY = (200, 200, 200) +PINK = (255, 105, 180) +GREEN = (0, 255, 0) +BLUE = (0, 0, 255) +RED = (255, 0, 0) + +pygame.init() +clock = pygame.time.Clock() + +# Definir la finestra +screen = pygame.display.set_mode((640, 480)) +pygame.display.set_caption('Window Title') + +# Bucle de l'aplicació +def main(): + is_looping = True + + while is_looping: + is_looping = app_events() + app_run() + app_draw() + + clock.tick(60) # Limitar a 60 FPS + + # Fora del bucle, tancar l'aplicació + pygame.quit() + sys.exit() + +# Gestionar events +def app_events(): + for event in pygame.event.get(): + if event.type == pygame.QUIT: # Botó tancar finestra + return False + return True + +# Fer càlculs +def app_run(): + pass + +# Dibuixar +def app_draw(): + screen.fill(WHITE) + utils.draw_grid(pygame, screen, 50) + + #Cuadrado rosa + pygame.draw.rect(screen, PINK, (150, 200, 50, 50), 5) + + #Triangulo verde + pygame.draw.polygon(screen, GREEN, [(275, 200), (275 - 28, 248), (275 + 28, 248)], 5) + + #Cruz Azul + pygame.draw.line(screen, BLUE, (350, 200), (400, 250), 6) + pygame.draw.line(screen, BLUE, (350, 250), (400, 200), 6) + + #Redonda roja + pygame.draw.circle(screen, RED, (475, 225), 25, 5) + + pygame.display.update() +if __name__ == "__main__": + main() \ No newline at end of file