https://foro.gambas-es.org/viewtopic.php?f=16&t=6892
-----------------------------------
Shell
Lunes, 02 Abril 2018, 12:23

[Python] Código Fuente De Los Libros Para PyGame
-----------------------------------
Buenos días!.

Esto en verdad es un tema en general no tiene por que ser Python o PyGame,
puede afectar a cualquier programa que use POO.

Llevo viendo varios libros con Pygame y muchas veces la mayoría de la estructura del código es el uso
de variables globales. Abundan. No se ve normalmente una rutina principal. 
Las clases, la rutina principal, todo junto.  Recordemos que un código de Python usa indentación.
Y muchos lenguajes. Supongo que habrá códigos mejores hechos unos que otros.

En cambio hay otros que usan una forma mejor para la creación del programa. Estos son menos.
Es como empezar siempre con una plantilla.

Me he encontrado un ejemplo básico que es la pulsación de una tecla. Esto me ha dado un poco de guerra,
ya que la variable donde se almacenaba la tecla pulsada era una variable global, al dividir el código
en partes. En los métodos de la clase del objeto que tenía que moverse, la daba como no definida, 
en fin.

Al final solucione el problema, recordando "la estructura  u organización de las clases" de otro libro.

El problema que nos encontramos es que el programador que crea el libro puede "no usar"
una estructura o esqueleto para la aplicación. No es una forma buena de programar ni tampoco
la de enseñar. Pero esto no ocurre solo con los programadores de Python con Pygame.

Partiendo siempre de una forma de escribir el código siempre estará bien organizado.
Ahora bien, puede que esta forma "pueda" variar según el lenguaje que usemos, o por 
el uso de librerías concretas.

Soy partidario de que el programador que enseña debe tener una manera que podía ser
siempre la misma pero bien organizada, porque lo que se trata es enseñar a programar
y que nuestros códigos no sean un plato de espagueti.

Los programadores que crean libros de programación, ademas de enseñar a conocer
un lenguaje, deberían siempre de enseñar un método, su método de creación y organización
del código.

Saludos


-----------------------------------
Shell
Lunes, 02 Abril 2018, 12:43

Re: [Python] Código Fuente De Los Libros Para PyGame
-----------------------------------
Como veis en este caso la variable que almacena la tecla pulsada es local a main.

[code linenumbers=false syntax=python]
def main():

    pygame.init()
    reloj = pygame.time.Clock()
    pygame.display.set_caption('Space Invaders')
    pantalla = pygame.display.set_mode((ANCHO_PANTALLA, ALTO_PANTALLA))

    caza_imagen = pygame.image.load('Imagenes/fighter.png').convert()
    caza_imagen.set_colorkey((BLANCO))
    caza_imagen_ancho = caza_imagen.get_width()
    caza_imagen_alto = caza_imagen.get_height()

    caza = Caza()

    while True:
        reloj.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        tecla_presionada = pygame.key.get_pressed()
..........


if __name__=='__main__': main()
[/code]

Al ser local la variable tecla_presionada, la clase Caza o Figther no la conoce.
Funciona si quitas ese bloque y lo dejas todo global.

En este código funciona, no esta comentado, pero las clases tienen una mejor organización.
Lo que hace es mover una imagen en la parte inferior de la ventana de izquierda a derecha.
Tampoco el programador tenía costumbre de usar constante y si números mágicos, aunque
luego en el libro explicaba el significado de esos números.

Fijaros que la tecla pulsada se le pasa al objeto tipo "caza" en su método mover, desde la clase Juego.

El movimiento no se encuentra en la parte de dibujar en la ventana, en este caso, mostrar frames.
En cambio se encuentra en la parte del código que se detecta los eventos.

[code linenumbers=false syntax=python]
#!/usr/bin/env python3

import pygame, sys
from pygame.locals import *

NEGRO = (0, 0, 0)
BLANCO = (255, 255, 255)
ANCHO_PANTALLA = 640
ALTO_PANTALLA = 650

class Caza:

    def __init__(self):
        self.x = 320
        self.caza_imagen = pygame.image.load('Imagenes/fighter.png').convert()
        self.caza_imagen.set_colorkey((BLANCO))
        self.caza_imagen_ancho = self.caza_imagen.get_width()
        self.caza_imagen_alto = self.caza_imagen.get_height()

    def mover(self, tecla_presionada):
        tecla_presionada = pygame.key.get_pressed()
        if tecla_presionada[K_LEFT] and self.x > 0:
            self.x -= 3
        elif tecla_presionada[K_RIGHT] and self.x < ANCHO_PANTALLA - self.caza_imagen_ancho:
            self.x += 3

    def dibujar(self, pantalla):
        pantalla.blit(self.caza_imagen,(self.x, ALTO_PANTALLA - self.caza_imagen_alto))

class Juego:

    def __init__(self):
        self.caza = Caza()        

    def proceso_eventos(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
               return True                          
        self.caza.mover(pygame.key.get_pressed())

        return False

    def mostrar_frames(self, pantalla):        
        pantalla.fill(NEGRO)      
        self.caza.dibujar(pantalla)
        pygame.display.update()

def main():

    pygame.init()
   
    pygame.display.set_caption('Space Invaders')
    pantalla = pygame.display.set_mode((ANCHO_PANTALLA, ALTO_PANTALLA))

    hecho = False
    reloj = pygame.time.Clock()

    juego = Juego()

    while not hecho:

        hecho = juego.proceso_eventos()        

        juego.mostrar_frames(pantalla)        

        reloj.tick(60)       


if __name__=='__main__': main()
[/code]

Este código lo pasaré a Gambas, pero en este cambia tanto para la clase Paint como el uso de SDL,
en el que ya usaría el evento Key_Press.

Saludos


