SlideShare uma empresa Scribd logo
1 de 10
Baixar para ler offline
PROGRAMA: AVENTURA
                            
                        CURSO: 1º BACHILLERATO




Aventura: Ficción Interactiva




     (Parte del código de recorte basado en un script original de Tiny Ducks On Wheels)


Introducción
El objetivo del programa es aprender una serie de técnicas y disponer de código que nos
sirva para realizar juegos de ficción interactiva con PyGame, es decir, juegos
conversacionales (del estilo de “The House”) con imágenes. Para ello, el programa se
organiza en torno a tres clases y una función que podéis modificar o ampliar en vuestros
propios programas:
1.    La clase Narrar
      Un objeto de este tipo es el que se utilizar para poner en pantalla la descripción del
      lugar en el que se encuentra el jugador. También puede usarse para responder a sus
      peticiones. Cuando se crea el objeto, hay que proporcionarle una surface (sobre la
      que se dibujará), un rect (que marcará la zona donde ha de dibujarse), un tipo de letra
      y un color (que se emplearán al dibujar el texto) y el color de fondo.
2.    La clase Hablar
      El objeto de este tipo hace las veces del cuadro donde el jugador escribe las acciones
      que desea realizar. Al crearse el objeto, debemos pasarle también una surface y un
      rect, un tipo de letra, su color y el color de fondo.
 PÁGINA 1 DE 10
                                
                       CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                          
                       CURSO: 1º BACHILLERATO

3.   La clase Juego
     Se trata del tipo de objeto más importante del juego, pues representa el status en el
     que se encuentra; localización, acciones... Como allí donde esté el jugador debe
     proporcionársele una descripción del entorno y, además, debe poder decir lo que
     quiere hacer, esta clase está ligada a las clases Narrar y Hablar. En consecuencia,
     cuando se crea uno de estos objetos hay que proporcionarle, una vez más, una surface
     (sobre lo que dibujar), una imagen (que representará el lugar en el que nos
     encontramos), un objeto de tipo Narrar y otro de tipo Hablar.
4.   La función procesar()
     Esta función se encargará de procesar las órdenes del jugador para realizar las
     correspondientes acciones, es decir, es el parser. En un juego completo, aquí está el
     núcleo del desarrollo de la aventura, ya que se usará para tomar objetos, cambiar de
     localización, luchar, etc. Como las acciones dependerán de la situación en la que nos
     encontremos en el juego, cuando se invoca a la función se le ha de pasar como
     argumento un objeto de tipo Juego.




Como quiera que el programa tiene por objetivo aprender la técnica, no es un juego
realmente operativo. Sólo están implementados los comandos “norte”, “sur” y “salir” y sólo
están incluidos dos lugares (y por tanto, dos imágenes).
Veamos el código:




 PÁGINA 2 DE 10
                              
                      CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                           
                       CURSO: 1º BACHILLERATO


Importación de Librerías y Definición de Constantes
Ya de sobras conocido; las librerías habituales, la inicialización de PyGame, la creación del
objeto visor con la surface del juego y las declaraciones de los colores que vamos a usar
con los textos y el diálogo.


Clase JUEGO
1.   En el constructor de la clase, es decir, la función __init__(), lo que hacemos es
     almacenar como atributos los argumentos que se le pasan para que la clase los pueda
     utilizar posteriormente cuando se desee. Estos atributos (a los que se accede como
     sabemos, con self.nombre_del_atributo) son surface, image (hemos usado image y
     no imagen, como nombre, por similitud a la clase pygame.sprite.Sprite), narrar y
     hablar. Ya hemos explicado más arriba su significado.
2.   La función update() se encarga de actualizar y dibujar en pantalla la situación en la
     que nos encontramos en el juego (observa, de nuevo, que hemos elegido un nombre
     familiar...). Fíjate el orden en el que lo hacemos. Primero se dibuja la imagen de fondo
     (‘el paisaje’). A continuación se llama al método update() del objeto narrar para
     que dibuje sobre el paisaje lo que ocurre en el juego. Finalmente se llama a la función
     escuchar() del propio objeto para que, como veremos enseguida, se esté atento al
     teclado y se procesen las teclas que se vayan pulsando.
3.   escuchar() se encarga de ir escribiendo en pantalla lo que se escribe hasta que se
     pulsa la tecla return (K_RETURN). La técnica es interesante, pues al contrario que
     con los programas escritos para la linea de comandos, en las surfaces de PyGame no
     se puede escribir directamente al estilo del conocido raw_input(). Veamos cómo se
     ha implementado:
     Lo primero es calcular cuántas letras nos caben en el cuadrado de texto que hará las
     veces de diálogo. Veremos en breve que el objeto hablar tiene un atributo de tipo
     Rect (que llamaremos rect) que indica la zona en la que se va a poner en pantalla. Así
     que podemos averiguar su anchura total en pixeles con hablar.rect.w . Si lo
     dividimos por la anchura de una letra típica, como la letra ‘a’, sabremos cuántas letras
     nos van a caber. Afortunadamente, el objeto de tipo hablar tendrá también un
     atributo de tipo Font (llamado tipoLetra) que posee (mira la documentación) una
     función miembro ( size() ) que nos da la anchura en pixeles de un carácter.
     ¡Estupendo! Almacenaremos cuántas letras nos caben en la variable maximo. Es más
     fácil verlo que contarlo:

     maximo = self.hablar.rect.w / self.hablar.tipoLetra.size('a')[0]

     (el [0] del final es por que, como habrás visto en la documentación, la función size()
     nos devuelve una tupla con la anchura y la altura, así que nos interesa el primer
     elemento).

     Probablemente, si has probado a escribir texto con PyGame habrás tenido problemas
     con los acentos o con los caracteres no anglosajones como ‘ñ’. Para que se muestren
     correctamente, necesitamos pasarle los textos con codificación unicode. No te
     preocupes; basta añadirle una u como prefijo a una cadena de texto para que se
     considere como unicode. Es por eso por lo que se ha escrito

     self.hablar.frase = u''

 PÁGINA 3 DE 10
                               
                      CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                           
                       CURSO: 1º BACHILLERATO



     para inicializar una cadena de texto (en blanco) a la que se añadirán las teclas que se
     vayan pulsando. De nuevo, frase será un atributo del objeto hablar que se encargará
     de memorizar las órdenes que se vayan dando en el juego.
     Lo siguiente es dibujar el cuadrado que enmarca la zona donde se escribirán nuestras
     ordenes. La función cuadrado() del objeto hablar se encargará de ello. Naturalmente,
     si queremos que se muestre inmediatamente en pantalla, tendremos que invocar a
     pygame.display.update().
     Vamos a la parte final. Necesitamos un bucle que vaya capturando las teclas pulsadas y
     que termine cuando se pulse return. La variable booleana hablando nos ayudará en
     la tarea; dentro del bucle, miramos la cola de eventos de la forma habitual y si la
     tecla pulsada es K_RETURN, hablando se pone a False, el bucle acabará y se
     saldrá de la función escuchar().
     Si la tecla pulsada es otra, querremos escribirla en pantalla. Afortunadamente,
     PyGame dispone de evento.unicode que nos da, precisamente, el texto de la tecla
     pulsada en codificación unicode. La función que se encargará de usar esta pulsación
     para escribir en pantalla será la función update() del objeto hablar:

     self.hablar.update(evento.unicode)

     Un matiz. Si la tecla pulsada es la de borrar (K_BACKSPACE), querremos que se
     elimine la última tecla pulsada, de allí la instrucción

     self.hablar.frase = self.hablar.frase[:-1]

     que hace precisamente eso (y no hay que pasarle ningún valor para dibujar). Además,
     hay que controlar que el número de teclas pulsadas no superen el máximo deseado (en
     caso contrario, el texto se saldría del cuadro), lo que se consigue mirando si
     len(self.hablar.frase) < maximo.


Clase Hablar
Se encarga de mostrar y almacenar las órdenes del jugador.
1.   __init__(), como es habitual, guarda como atributos los valores que se pasan al
     objeto cuando se crea. Además, se definen dos atributos más: margen marca el
     tamaño del margen, ya que si el texto comienza a escribirse justo en el borde del
     cuadro queda poco elegante; y frase contendrá, como hemos visto, lo que escribe el
     jugador.
2.   La función cuadrado() realza la zona en la que se va a escribir. Para que no tape la
     parte de la imagen de fondo que tiene detrás tendremos que aplicarle transparencia.
     ¿Cómo hacerlo? Primero creamos una surface del tamaño del rect del objeto que
     llamamos cuadrado. Indicamos que vamos a usar transparencia con el ya conocido
     convert_alpha(). ¿Cuánta transparencia? Eso se indica con set_alpha() ; cuanto
     menor sea el valor que le pasemos, tanto más transparente será. Finalmente, pintamos
     el cuadrado entero del color deseado con fill() y se dibuja el resultado sobre la
     surface que se ha pasado al objeto (típicamente, nuestro visor).
3.   Al método update(), si recordamos lo que hemos visto en la clase Juego, le pasamos
     el valor de evento.unicode (la tecla pulsada). Ese parámetro lo hemos llamado tecla
     en la implementación de la función. El objetivo es añadir dicha tecla a la variable frase
     y dibujar el resultado.
 PÁGINA 4 DE 10
                               
                      CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                            
                        CURSO: 1º BACHILLERATO

     Las primeras dos líneas posicionan dónde va a escribirse, dejando el margen
     pertinente. A continuación se añade a frase el valor de tecla (todo está en unicode,
     así que es correcto), se dibuja el marco semitransparente, se dibuja el texto y se
     actualiza la pantalla para que se muestre. ¡Muy bien!


Clase Narrar
Muestra la descripción del lugar donde se encuentra el jugador o cualquier otro mensaje
que se desee como respuesta a una acción, a través de su atributo texto. La idea es hacerlo
de forma similar a la clase anterior pero ahora el problema es distinto. El texto entero ya lo
tenemos pero, por contra, puede ser muy largo y ocupar muchas líneas. La clase se
encargará de ajustar automáticamente el texto al tamaño disponible.
1.   __init__() almacena, como es habitual, los parámetros con los que se crea el objeto
     en atributos propios (para usarlos posteriormente). Hay un añadido, como ya hemos
     comentado, texto.
2.   cortaTexto() es un método que toma como argumento un número que representa el
     tamaño máximo en pixeles que puede ocupar una línea de texto. El objetivo de la
     función es, partiendo del texto almacenado en texto, dividirlo en una lista de líneas
     que respeten el ancho dado. Con ello se consigue que sea cual sea el valor de texto, se
     ajuste y quepa dentro de la zona donde se va a escribir.
     Para realizarlo, y usando nuestra vieja amiga split(), el texto se divide en una lista de
     líneas de partida (para conservar los puntos y aparte que pudiera tener):

     lineas = self.texto.split("n")

     (el código especial ‘n’ es la marca de nueva línea en Linux). A continuación creamos
     una lista vacía, resultado, en donde se irán añadiendo las lineas con el tamaño
     correcto.
     El resto del trabajo se realiza con un bucle for que recorre todas las lineas anteriores.
     Para cada una de ellas, palabras contiene su lista de palabras (de nuevo usando
     split()). La idea es ir añadiendo palabras, calcular cuanto tamaño tiene cada una, y si
     no se supera el tamaño máximo ir a por la siguiente. En el momento en el que se
     supere dicho tope, se cambia de linea (es decir, se añade la línea a la lista y se
     empiezan a mirar las siguientes palabras). Intenta seguir el proceso. Ten en cuenta que
     se calcula el ancho en pixeles de un texto con size(), que se añaden elementos a la lista
     con el método append() de los objetos list, y que para concatenar textos se usa el
     método join() de los objetos str. En cualquier caso, la función termina devolviendo
     como valor de salida a resultado, la lista de líneas deseada.
3.   La función update() toma como único argumento un número, margen, cuyo
     significado es evidente por el nombre. Comenzamos calculando la posición en la que
     situar el texto horizontalmente, dejando el margen y obteniendo la lista de líneas que
     se van a escribir, lineas, llamando al método cortaTexto() que hemos visto hace un
     momento. Observa que se ha tenido en cuenta también el margen para indicar el
     máximo tamaño disponible (se resta dos veces, contando ambos lados).
     Para centrar el texto verticalmente, necesitamos saber cuanto ocupan las líneas. En
     nuestro auxilio viene el método get_linesize() de los objetos Font. Nos devuelve la
     altura en pixeles que ocupa una linea de texto con ese tipo de letra. Una vez conocido,
     para conseguir que el texto quede en la parte central de la zona de impresión,
     calculamos su coordenada vertical así:

 PÁGINA 5 DE 10
                                
                      CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                            
                        CURSO: 1º BACHILLERATO

    posy = self.rect.top + (self.rect.h - alturaLinea * len(lineas)) / 2

    (observa que a la altura de la zona que ocupa el texto, se le resta la altura total de todas
    las líneas y el resultado se divide por dos para que el margen sea el mismo por arriba
    que por abajo; probablemente necesitarás hacerte un dibujo para entenderlo).
    Ya podemos pasar a dibujar. Primero, de forma similar a como hacía la función
    cuadrado() en la clase Hablar, dibujamos el cuadrado de fondo semitransparente.
    A continuación, recorremos todas las líneas del texto y las dibujamos. Fíjate que
    después de dibujar una línea, se añade a posy el valor de la altura de la línea calculada
    para que la siguiente se dibuje debajo, en el lugar correcto. Y, finalmente, se vuelca
    todo en pantalla para que lo visualice el jugador.


función procesar()
En un juego real esta función sería bastante más complicada y extensa y ésta es la razón
por lo que se implementa como una función externa y no como un método más de la
clase Juego. De hecho, para poder modificarlo, juego se pasa como argumento a la
función.
Nuestro procesar() simplemente comprueba cuál es la imagen de fondo actual (es decir,
juego.image) para actuar convenientemente. Si se trata de castillo sólo haremos caso
cuando la frase que ha escrito el jugador sea ‘norte’; entonces cambiamos la imagen a
patio y la descripción a frase2. Algo similar ocurre cuando la imagen actual es patio; la
única salida es al sur y sólo se obedece en tal caso. Por otra parte, si el jugador escribe
‘salir’ el juego debe terminar.
Lo dicho, en un juego serio aquí se harían muchas comprobaciones. Además, nadie nos
impide añadir más atributos a la clase Juego para que se almacene más información sobre
el jugador (objetos que lleva, salud, armas, etc). Recuerda que en el juego ‘TheHouse’, el
parser era bastante largo y usaba bastantes variables de estado.



Cuerpo Principal del Juego
Llegamos al último bloque del juego. Para empezar, cargamos las imágenes de fondo
castillo y patio y definimos las descripciones de ambas localizaciones, frase1 y frase2.
En un juego completo, lo ideal sería una lista o un diccionario y no variables sueltas.
Continuamos definiendo los tipos de letra para la descripción de los lugares y las
situaciones (letraNarrar) y para el diálogo con el ordenador (letraHablar). También se
definen las zonas donde se van a mostrar con sendos Rect (dondeTexto y
dondeComando).
Justo antes del bucle del juego se crean los objetos que lo controlan; narrar, hablar y
juego. En la creación de este último se usan los dos anteriores. Observa que para
inicializar el juego necesitamos proporcionarle los datos de por donde empezar. La imagen
de fondo se pasa al crearlo (castillo) y la descripción del lugar se pone a mano con

narrar.texto = frase1

Finalmente, el bucle del juego realiza una y otra vez las dos tareas obvias; mostrar en
pantalla la situación actualizada y esperar las acciones del usuario con juego.update() y
procesar lo que haya introducido el jugador con procesar(juego).
 PÁGINA 6 DE 10
                                
                       CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                            
                     CURSO: 1º BACHILLERATO



   # -*- coding: utf-8 -*-

   #-------------------------------------------------------------------
   # aventura.py
   # (cortaTexto basado en un script de Tiny Ducks On Wheels)
   #-------------------------------------------------------------------


   import pygame, sys
   from pygame.locals import *

   AMARILLO = (200,200,0)
   BLANCO = (200,200,200)
   VERDE = (0,100,0)
   LILA = (50,0,50)

   pygame.init()

   visor = pygame.display.set_mode((800,600))

   #-------------------------------------------------------------------
   # Clase Juego
   # (Clase principal que coordina las demás)
   #-------------------------------------------------------------------

   class Juego:
      def __init__(self, surface, imagen, narrar, hablar):
        self.surface = surface
        self.image = imagen
        self.narrar = narrar
        self.hablar = hablar

      def update(self):
        self.surface.blit(self.image, (0,0))
        self.narrar.update(10)
        self.escuchar()

      def escuchar(self):
        maximo = self.hablar.rect.w / self.hablar.tipoLetra.size('a')[0]
        self.hablar.frase = u''
        self.hablar.cuadrado()
        pygame.display.update()
        hablando = True
        while hablando:
           for evento in pygame.event.get():
              if evento.type == QUIT:
                  pygame.quit()
                  sys.exit()
              elif evento.type == KEYDOWN:




PÁGINA 7 DE 10
                                
                    CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                             
                        CURSO: 1º BACHILLERATO




                  if evento.key == K_RETURN:
                      hablando = False
                  elif evento.key == K_BACKSPACE:
                      self.hablar.frase = self.hablar.frase[:-1]
                      self.hablar.update(u'')
                  elif len(self.hablar.frase) < maximo:
                      self.hablar.update(evento.unicode)

   #-------------------------------------------------------------------
   # Clase Hablar
   # ( Gestiona ka introducción de texto del usaurio)
   #-------------------------------------------------------------------

   class Hablar:
      def __init__(self, surface, rect, tipoLetra, colorTexto, colorFondo):
        self.surface = surface
        self.rect = rect
        self.tipoLetra = tipoLetra
        self.color = colorTexto
        self.colorFondo = colorFondo
        self.margen = 10
        self.frase = u''

      def cuadrado(self):
        cuadrado = pygame.Surface((self.rect.w,self.rect.h))
        cuadrado.convert_alpha()
        cuadrado.set_alpha(200)
        cuadrado.fill(self.colorFondo)
        self.surface.blit(cuadrado, self.rect.topleft)

      def update(self, tecla):
        x = self.rect.left + self.margen
        y = self.rect.top + self.margen
        self.frase += tecla
        self.cuadrado()
        self.surface.blit(self.tipoLetra.render(self.frase, True, self.color), (x,y))
        pygame.display.update()

   #-------------------------------------------------------------------
   # Clase Narrar
   # ( Muestra las descripciones de las situaciones)
   #-------------------------------------------------------------------

   class Narrar:
      def __init__(self, surface, rect, tipoLetra, colorTexto, colorFondo):
        self.surface = surface
        self.rect = rect
        self.tipoLetra = tipoLetra
        self.color = colorTexto




PÁGINA 8 DE 10
                                 
                       CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                            
                        CURSO: 1º BACHILLERATO



         self.colorFondo = colorFondo
         self.texto = u''

      def cortaTexto(self, anchoTotal):
        lineas = self.texto.split("n")
        resultado = []
        for linea in lineas:
           palabras = linea.split(" ")
           comienzo = 0

            i=0
            while i < len(palabras):
              ancho = self.tipoLetra.size(" ".join(palabras[comienzo:i+1]))[0]
              if ancho > anchoTotal:
                  resultado.append(" ".join(palabras[comienzo:i]))
                  comienzo = i
                  i -= 1
              elif i is len(palabras) - 1:
                  resultado.append(" ".join(palabras[comienzo:i + 1]))

                  i += 1

         return resultado

      def update(self, margen):
        posx = self.rect.left + margen
        lineas = self.cortaTexto(self.rect.width - 2*margen)
        alturaLinea = self.tipoLetra.get_linesize()
        posy = self.rect.top + (self.rect.h - alturaLinea * len(lineas)) / 2
        cuadrado = pygame.Surface((self.rect.w, self.rect.h))
        cuadrado.convert_alpha()
        cuadrado.set_alpha(200)
        cuadrado.fill(self.colorFondo)
        self.surface.blit(cuadrado, (self.rect.left,self.rect.top))
        for linea in lineas:
           self.surface.blit(self.tipoLetra.render(linea, True, self.color), (posx, posy))
           posy = posy + alturaLinea
        pygame.display.update()

   #-------------------------------------------------------------------
   # Función procesar()
   # ( El parser del juego)
   #-------------------------------------------------------------------

   def procesar(juego):
     if juego.image == castillo and juego.hablar.frase == 'norte':
         juego.image = patio
         juego.narrar.texto = frase2
     elif juego.image == patio and juego.hablar.frase == 'sur':




PÁGINA 9 DE 10
                                
                       CC: FERNANDO SALAMERO
PROGRAMA: AVENTURA
                         
                     CURSO: 1º BACHILLERATO



         juego.image = castillo
         juego.narrar.texto = frase1
      elif juego.hablar.frase == 'salir':
         pygame.quit()
         sys.exit()

   #-------------------------------------------------------------------
   # Cuerpo Principal del Juego
   #-------------------------------------------------------------------

   castillo = pygame.image.load('castillo.jpg').convert()
   patio = pygame.image.load('patio.png').convert()
   frase1 = u'Abres los Ojos...nNo recuerdas nada. ¿Dónde estás? Al norte hay una
   puerta.'
   frase2 = u'Un patio se abre ante ti. Al sur está la puerta que has traspasado.'

   letraHablar = pygame.font.Font('Grandezza.ttf', 24)
   letraNarrar = pygame.font.Font('Adolphus.ttf', 24)
   dondeTexto = pygame.Rect((100,300,600, 200))
   dondeComando = pygame.Rect((100,550,600,40))
   narrar = Narrar(visor, dondeTexto, letraNarrar, AMARILLO, LILA)
   hablar = Hablar(visor, dondeComando, letraHablar, BLANCO, VERDE)
   juego = Juego(visor, castillo, narrar, hablar)
   narrar.texto = frase1


   while True:
     juego.update()
     procesar(juego)




PÁGINA 10 DE 10
                            
                   CC: FERNANDO SALAMERO

Mais conteúdo relacionado

Mais procurados (20)

Programación con Pygame I
Programación con Pygame IProgramación con Pygame I
Programación con Pygame I
 
Programación con Pygame IV
Programación con Pygame IVProgramación con Pygame IV
Programación con Pygame IV
 
Instructivo tortugart
Instructivo tortugartInstructivo tortugart
Instructivo tortugart
 
Manual Basico para Encantadores de Serpientes (Python)
Manual Basico para Encantadores de Serpientes (Python)Manual Basico para Encantadores de Serpientes (Python)
Manual Basico para Encantadores de Serpientes (Python)
 
Intro pygamev2
Intro pygamev2Intro pygamev2
Intro pygamev2
 
Intro PyGame Capitulo 5
Intro PyGame Capitulo 5Intro PyGame Capitulo 5
Intro PyGame Capitulo 5
 
Python no muerde
Python  no muerdePython  no muerde
Python no muerde
 
Intro Pygame Capitulo 2
Intro Pygame Capitulo 2Intro Pygame Capitulo 2
Intro Pygame Capitulo 2
 
Intro PygameCapitulo 3
Intro PygameCapitulo 3Intro PygameCapitulo 3
Intro PygameCapitulo 3
 
Introducción a las librerías PyGame y PyOpenGL
Introducción a las librerías PyGame y PyOpenGLIntroducción a las librerías PyGame y PyOpenGL
Introducción a las librerías PyGame y PyOpenGL
 
Python (práctica 1)
Python (práctica 1)Python (práctica 1)
Python (práctica 1)
 
Capitulo 4
Capitulo 4Capitulo 4
Capitulo 4
 
Presentación del 21 de abril de 2012
Presentación del 21 de abril de 2012Presentación del 21 de abril de 2012
Presentación del 21 de abril de 2012
 
Python para principiantes
Python para principiantesPython para principiantes
Python para principiantes
 
Programación scratch
Programación scratchProgramación scratch
Programación scratch
 
Práctica de calculadora documentada
Práctica de calculadora documentadaPráctica de calculadora documentada
Práctica de calculadora documentada
 
Tema 2
Tema 2Tema 2
Tema 2
 
Batch
BatchBatch
Batch
 
manual-batch-desde-0
manual-batch-desde-0manual-batch-desde-0
manual-batch-desde-0
 
Inmersión en Python 3.0.11
Inmersión en Python 3.0.11Inmersión en Python 3.0.11
Inmersión en Python 3.0.11
 

Semelhante a Programación con Pygame VII

Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)Fernando Salamero
 
4manipularbotones 121006192501-phpapp02 (1)
4manipularbotones 121006192501-phpapp02 (1)4manipularbotones 121006192501-phpapp02 (1)
4manipularbotones 121006192501-phpapp02 (1)Jose Joney Vargas Castro
 
Taller de introduccion a python con turtle
Taller de  introduccion a python  con  turtleTaller de  introduccion a python  con  turtle
Taller de introduccion a python con turtleAlbert Page
 
Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)Fernando Salamero
 
Tutorial game maker
Tutorial game makerTutorial game maker
Tutorial game makerJoserichi
 
Practicas: "MICROSOFT WORD"
Practicas: "MICROSOFT WORD"Practicas: "MICROSOFT WORD"
Practicas: "MICROSOFT WORD"'Aroo Juárez
 
Unidad 2 manipular el dibujo utilizando herramientas de diseño
Unidad 2 manipular el dibujo utilizando herramientas de diseñoUnidad 2 manipular el dibujo utilizando herramientas de diseño
Unidad 2 manipular el dibujo utilizando herramientas de diseñojosselinecamargo
 
Tutorial pixel art
Tutorial pixel artTutorial pixel art
Tutorial pixel artY-Green
 
Lenguaje de programación logo
Lenguaje de programación logoLenguaje de programación logo
Lenguaje de programación logoAracelyLeyton
 
5°-grado-Animacion-con-dialogos-usando-Scratch.pdf
5°-grado-Animacion-con-dialogos-usando-Scratch.pdf5°-grado-Animacion-con-dialogos-usando-Scratch.pdf
5°-grado-Animacion-con-dialogos-usando-Scratch.pdfssuser42eafa
 
TALLER SCRATCH 1º ó 2º ESO (1).pdf
TALLER SCRATCH 1º ó 2º ESO (1).pdfTALLER SCRATCH 1º ó 2º ESO (1).pdf
TALLER SCRATCH 1º ó 2º ESO (1).pdfsergiomaureira4
 
Actividad no.1 (Visual Basic)
Actividad no.1 (Visual Basic)Actividad no.1 (Visual Basic)
Actividad no.1 (Visual Basic)Jose Torres
 
Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)
Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)
Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)Josseline Camargo D'l Angel
 
Unidad 2 Manipular el Dibujo Utilizando Herramientas de Diseño
Unidad 2 Manipular el Dibujo Utilizando Herramientas de DiseñoUnidad 2 Manipular el Dibujo Utilizando Herramientas de Diseño
Unidad 2 Manipular el Dibujo Utilizando Herramientas de DiseñoCesar Govea Rodriguez
 

Semelhante a Programación con Pygame VII (20)

4 manipular botones
4 manipular botones4 manipular botones
4 manipular botones
 
Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)
 
4manipularbotones 121006192501-phpapp02 (1)
4manipularbotones 121006192501-phpapp02 (1)4manipularbotones 121006192501-phpapp02 (1)
4manipularbotones 121006192501-phpapp02 (1)
 
Taller de introduccion a python con turtle
Taller de  introduccion a python  con  turtleTaller de  introduccion a python  con  turtle
Taller de introduccion a python con turtle
 
Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)
 
Tutorial game maker
Tutorial game makerTutorial game maker
Tutorial game maker
 
Practicas: "MICROSOFT WORD"
Practicas: "MICROSOFT WORD"Practicas: "MICROSOFT WORD"
Practicas: "MICROSOFT WORD"
 
Unidad 2
Unidad 2Unidad 2
Unidad 2
 
GAME MAKER
GAME MAKERGAME MAKER
GAME MAKER
 
Scratch informacion
Scratch informacionScratch informacion
Scratch informacion
 
Unidad 4
Unidad 4Unidad 4
Unidad 4
 
Unidad 2 manipular el dibujo utilizando herramientas de diseño
Unidad 2 manipular el dibujo utilizando herramientas de diseñoUnidad 2 manipular el dibujo utilizando herramientas de diseño
Unidad 2 manipular el dibujo utilizando herramientas de diseño
 
Tutorial pixel art
Tutorial pixel artTutorial pixel art
Tutorial pixel art
 
Lenguaje de programación logo
Lenguaje de programación logoLenguaje de programación logo
Lenguaje de programación logo
 
5°-grado-Animacion-con-dialogos-usando-Scratch.pdf
5°-grado-Animacion-con-dialogos-usando-Scratch.pdf5°-grado-Animacion-con-dialogos-usando-Scratch.pdf
5°-grado-Animacion-con-dialogos-usando-Scratch.pdf
 
Unida 2
Unida 2Unida 2
Unida 2
 
TALLER SCRATCH 1º ó 2º ESO (1).pdf
TALLER SCRATCH 1º ó 2º ESO (1).pdfTALLER SCRATCH 1º ó 2º ESO (1).pdf
TALLER SCRATCH 1º ó 2º ESO (1).pdf
 
Actividad no.1 (Visual Basic)
Actividad no.1 (Visual Basic)Actividad no.1 (Visual Basic)
Actividad no.1 (Visual Basic)
 
Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)
Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)
Unidad 2 manipular el dibujo utilizando herramientas de diseño (1)
 
Unidad 2 Manipular el Dibujo Utilizando Herramientas de Diseño
Unidad 2 Manipular el Dibujo Utilizando Herramientas de DiseñoUnidad 2 Manipular el Dibujo Utilizando Herramientas de Diseño
Unidad 2 Manipular el Dibujo Utilizando Herramientas de Diseño
 

Mais de Fernando Salamero

(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no propone(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no proponeFernando Salamero
 
Ciencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no proponeCiencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no proponeFernando Salamero
 
(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la Física(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la FísicaFernando Salamero
 
(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la Física(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la FísicaFernando Salamero
 
Timeline - En busca de la Física
Timeline - En busca de la FísicaTimeline - En busca de la Física
Timeline - En busca de la FísicaFernando Salamero
 
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (IX)
Programación de Videojuegos con Python y Pilas (IX)Programación de Videojuegos con Python y Pilas (IX)
Programación de Videojuegos con Python y Pilas (IX)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)Fernando Salamero
 

Mais de Fernando Salamero (19)

(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no propone(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
 
Ciencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no proponeCiencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no propone
 
(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la Física(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la Física
 
(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la Física(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la Física
 
Timeline - En busca de la Física
Timeline - En busca de la FísicaTimeline - En busca de la Física
Timeline - En busca de la Física
 
Jovenes físicos
Jovenes físicosJovenes físicos
Jovenes físicos
 
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
 
Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)
 
Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)
 
Programación de Videojuegos con Python y Pilas (IX)
Programación de Videojuegos con Python y Pilas (IX)Programación de Videojuegos con Python y Pilas (IX)
Programación de Videojuegos con Python y Pilas (IX)
 
Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)
 
Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)
 
Python básico II
Python básico IIPython básico II
Python básico II
 
Python (ejercicios)
Python (ejercicios)Python (ejercicios)
Python (ejercicios)
 
Python (práctica 4)
Python (práctica 4)Python (práctica 4)
Python (práctica 4)
 
Python (práctica 3)
Python (práctica 3)Python (práctica 3)
Python (práctica 3)
 
Python (práctica 2)
Python (práctica 2)Python (práctica 2)
Python (práctica 2)
 
Iniciación a python
Iniciación a pythonIniciación a python
Iniciación a python
 
Aventura
AventuraAventura
Aventura
 

Último

c3.hu3.p1.p3.El ser humano como ser histórico.pptx
c3.hu3.p1.p3.El ser humano como ser histórico.pptxc3.hu3.p1.p3.El ser humano como ser histórico.pptx
c3.hu3.p1.p3.El ser humano como ser histórico.pptxMartín Ramírez
 
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdfTema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdfDaniel Ángel Corral de la Mata, Ph.D.
 
Fundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdfFundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdfsamyarrocha1
 
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptxMonitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptxJUANCARLOSAPARCANARE
 
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdfTarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdfManuel Molina
 
PPT_Formación integral y educación CRESE (1).pdf
PPT_Formación integral y educación CRESE (1).pdfPPT_Formación integral y educación CRESE (1).pdf
PPT_Formación integral y educación CRESE (1).pdfEDILIAGAMBOA
 
Metabolismo 3: Anabolismo y Fotosíntesis 2024
Metabolismo 3: Anabolismo y Fotosíntesis 2024Metabolismo 3: Anabolismo y Fotosíntesis 2024
Metabolismo 3: Anabolismo y Fotosíntesis 2024IES Vicent Andres Estelles
 
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdfOswaldoGonzalezCruz
 
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxLINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxdanalikcruz2000
 
Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...
Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...
Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...fcastellanos3
 
Fisiologia.Articular. 3 Kapandji.6a.Ed.pdf
Fisiologia.Articular. 3 Kapandji.6a.Ed.pdfFisiologia.Articular. 3 Kapandji.6a.Ed.pdf
Fisiologia.Articular. 3 Kapandji.6a.Ed.pdfcoloncopias5
 
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfEstrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfAlfredoRamirez953210
 
Día de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundialDía de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundialpatriciaines1993
 
PINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).ppt
PINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).pptPINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).ppt
PINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).pptAlberto Rubio
 
Estrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdfEstrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdfromanmillans
 

Último (20)

c3.hu3.p1.p3.El ser humano como ser histórico.pptx
c3.hu3.p1.p3.El ser humano como ser histórico.pptxc3.hu3.p1.p3.El ser humano como ser histórico.pptx
c3.hu3.p1.p3.El ser humano como ser histórico.pptx
 
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdfTema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
 
Fundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdfFundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdf
 
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptxMonitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
 
Sesión La luz brilla en la oscuridad.pdf
Sesión  La luz brilla en la oscuridad.pdfSesión  La luz brilla en la oscuridad.pdf
Sesión La luz brilla en la oscuridad.pdf
 
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdfTarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
 
PPT_Formación integral y educación CRESE (1).pdf
PPT_Formación integral y educación CRESE (1).pdfPPT_Formación integral y educación CRESE (1).pdf
PPT_Formación integral y educación CRESE (1).pdf
 
Earth Day Everyday 2024 54th anniversary
Earth Day Everyday 2024 54th anniversaryEarth Day Everyday 2024 54th anniversary
Earth Day Everyday 2024 54th anniversary
 
Metabolismo 3: Anabolismo y Fotosíntesis 2024
Metabolismo 3: Anabolismo y Fotosíntesis 2024Metabolismo 3: Anabolismo y Fotosíntesis 2024
Metabolismo 3: Anabolismo y Fotosíntesis 2024
 
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
 
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxLINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
 
VISITA À PROTEÇÃO CIVIL _
VISITA À PROTEÇÃO CIVIL                  _VISITA À PROTEÇÃO CIVIL                  _
VISITA À PROTEÇÃO CIVIL _
 
Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...
Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...
Estas son las escuelas y colegios que tendrán modalidad no presencial este lu...
 
Fisiologia.Articular. 3 Kapandji.6a.Ed.pdf
Fisiologia.Articular. 3 Kapandji.6a.Ed.pdfFisiologia.Articular. 3 Kapandji.6a.Ed.pdf
Fisiologia.Articular. 3 Kapandji.6a.Ed.pdf
 
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfEstrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
 
Día de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundialDía de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundial
 
PINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).ppt
PINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).pptPINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).ppt
PINTURA ITALIANA DEL CINQUECENTO (SIGLO XVI).ppt
 
Estrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdfEstrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdf
 
DIA INTERNACIONAL DAS FLORESTAS .
DIA INTERNACIONAL DAS FLORESTAS         .DIA INTERNACIONAL DAS FLORESTAS         .
DIA INTERNACIONAL DAS FLORESTAS .
 
PPTX: La luz brilla en la oscuridad.pptx
PPTX: La luz brilla en la oscuridad.pptxPPTX: La luz brilla en la oscuridad.pptx
PPTX: La luz brilla en la oscuridad.pptx
 

Programación con Pygame VII

  • 1. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO Aventura: Ficción Interactiva (Parte del código de recorte basado en un script original de Tiny Ducks On Wheels) Introducción El objetivo del programa es aprender una serie de técnicas y disponer de código que nos sirva para realizar juegos de ficción interactiva con PyGame, es decir, juegos conversacionales (del estilo de “The House”) con imágenes. Para ello, el programa se organiza en torno a tres clases y una función que podéis modificar o ampliar en vuestros propios programas: 1. La clase Narrar Un objeto de este tipo es el que se utilizar para poner en pantalla la descripción del lugar en el que se encuentra el jugador. También puede usarse para responder a sus peticiones. Cuando se crea el objeto, hay que proporcionarle una surface (sobre la que se dibujará), un rect (que marcará la zona donde ha de dibujarse), un tipo de letra y un color (que se emplearán al dibujar el texto) y el color de fondo. 2. La clase Hablar El objeto de este tipo hace las veces del cuadro donde el jugador escribe las acciones que desea realizar. Al crearse el objeto, debemos pasarle también una surface y un rect, un tipo de letra, su color y el color de fondo. PÁGINA 1 DE 10 CC: FERNANDO SALAMERO
  • 2. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO 3. La clase Juego Se trata del tipo de objeto más importante del juego, pues representa el status en el que se encuentra; localización, acciones... Como allí donde esté el jugador debe proporcionársele una descripción del entorno y, además, debe poder decir lo que quiere hacer, esta clase está ligada a las clases Narrar y Hablar. En consecuencia, cuando se crea uno de estos objetos hay que proporcionarle, una vez más, una surface (sobre lo que dibujar), una imagen (que representará el lugar en el que nos encontramos), un objeto de tipo Narrar y otro de tipo Hablar. 4. La función procesar() Esta función se encargará de procesar las órdenes del jugador para realizar las correspondientes acciones, es decir, es el parser. En un juego completo, aquí está el núcleo del desarrollo de la aventura, ya que se usará para tomar objetos, cambiar de localización, luchar, etc. Como las acciones dependerán de la situación en la que nos encontremos en el juego, cuando se invoca a la función se le ha de pasar como argumento un objeto de tipo Juego. Como quiera que el programa tiene por objetivo aprender la técnica, no es un juego realmente operativo. Sólo están implementados los comandos “norte”, “sur” y “salir” y sólo están incluidos dos lugares (y por tanto, dos imágenes). Veamos el código: PÁGINA 2 DE 10 CC: FERNANDO SALAMERO
  • 3. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO Importación de Librerías y Definición de Constantes Ya de sobras conocido; las librerías habituales, la inicialización de PyGame, la creación del objeto visor con la surface del juego y las declaraciones de los colores que vamos a usar con los textos y el diálogo. Clase JUEGO 1. En el constructor de la clase, es decir, la función __init__(), lo que hacemos es almacenar como atributos los argumentos que se le pasan para que la clase los pueda utilizar posteriormente cuando se desee. Estos atributos (a los que se accede como sabemos, con self.nombre_del_atributo) son surface, image (hemos usado image y no imagen, como nombre, por similitud a la clase pygame.sprite.Sprite), narrar y hablar. Ya hemos explicado más arriba su significado. 2. La función update() se encarga de actualizar y dibujar en pantalla la situación en la que nos encontramos en el juego (observa, de nuevo, que hemos elegido un nombre familiar...). Fíjate el orden en el que lo hacemos. Primero se dibuja la imagen de fondo (‘el paisaje’). A continuación se llama al método update() del objeto narrar para que dibuje sobre el paisaje lo que ocurre en el juego. Finalmente se llama a la función escuchar() del propio objeto para que, como veremos enseguida, se esté atento al teclado y se procesen las teclas que se vayan pulsando. 3. escuchar() se encarga de ir escribiendo en pantalla lo que se escribe hasta que se pulsa la tecla return (K_RETURN). La técnica es interesante, pues al contrario que con los programas escritos para la linea de comandos, en las surfaces de PyGame no se puede escribir directamente al estilo del conocido raw_input(). Veamos cómo se ha implementado: Lo primero es calcular cuántas letras nos caben en el cuadrado de texto que hará las veces de diálogo. Veremos en breve que el objeto hablar tiene un atributo de tipo Rect (que llamaremos rect) que indica la zona en la que se va a poner en pantalla. Así que podemos averiguar su anchura total en pixeles con hablar.rect.w . Si lo dividimos por la anchura de una letra típica, como la letra ‘a’, sabremos cuántas letras nos van a caber. Afortunadamente, el objeto de tipo hablar tendrá también un atributo de tipo Font (llamado tipoLetra) que posee (mira la documentación) una función miembro ( size() ) que nos da la anchura en pixeles de un carácter. ¡Estupendo! Almacenaremos cuántas letras nos caben en la variable maximo. Es más fácil verlo que contarlo: maximo = self.hablar.rect.w / self.hablar.tipoLetra.size('a')[0] (el [0] del final es por que, como habrás visto en la documentación, la función size() nos devuelve una tupla con la anchura y la altura, así que nos interesa el primer elemento). Probablemente, si has probado a escribir texto con PyGame habrás tenido problemas con los acentos o con los caracteres no anglosajones como ‘ñ’. Para que se muestren correctamente, necesitamos pasarle los textos con codificación unicode. No te preocupes; basta añadirle una u como prefijo a una cadena de texto para que se considere como unicode. Es por eso por lo que se ha escrito self.hablar.frase = u'' PÁGINA 3 DE 10 CC: FERNANDO SALAMERO
  • 4. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO para inicializar una cadena de texto (en blanco) a la que se añadirán las teclas que se vayan pulsando. De nuevo, frase será un atributo del objeto hablar que se encargará de memorizar las órdenes que se vayan dando en el juego. Lo siguiente es dibujar el cuadrado que enmarca la zona donde se escribirán nuestras ordenes. La función cuadrado() del objeto hablar se encargará de ello. Naturalmente, si queremos que se muestre inmediatamente en pantalla, tendremos que invocar a pygame.display.update(). Vamos a la parte final. Necesitamos un bucle que vaya capturando las teclas pulsadas y que termine cuando se pulse return. La variable booleana hablando nos ayudará en la tarea; dentro del bucle, miramos la cola de eventos de la forma habitual y si la tecla pulsada es K_RETURN, hablando se pone a False, el bucle acabará y se saldrá de la función escuchar(). Si la tecla pulsada es otra, querremos escribirla en pantalla. Afortunadamente, PyGame dispone de evento.unicode que nos da, precisamente, el texto de la tecla pulsada en codificación unicode. La función que se encargará de usar esta pulsación para escribir en pantalla será la función update() del objeto hablar: self.hablar.update(evento.unicode) Un matiz. Si la tecla pulsada es la de borrar (K_BACKSPACE), querremos que se elimine la última tecla pulsada, de allí la instrucción self.hablar.frase = self.hablar.frase[:-1] que hace precisamente eso (y no hay que pasarle ningún valor para dibujar). Además, hay que controlar que el número de teclas pulsadas no superen el máximo deseado (en caso contrario, el texto se saldría del cuadro), lo que se consigue mirando si len(self.hablar.frase) < maximo. Clase Hablar Se encarga de mostrar y almacenar las órdenes del jugador. 1. __init__(), como es habitual, guarda como atributos los valores que se pasan al objeto cuando se crea. Además, se definen dos atributos más: margen marca el tamaño del margen, ya que si el texto comienza a escribirse justo en el borde del cuadro queda poco elegante; y frase contendrá, como hemos visto, lo que escribe el jugador. 2. La función cuadrado() realza la zona en la que se va a escribir. Para que no tape la parte de la imagen de fondo que tiene detrás tendremos que aplicarle transparencia. ¿Cómo hacerlo? Primero creamos una surface del tamaño del rect del objeto que llamamos cuadrado. Indicamos que vamos a usar transparencia con el ya conocido convert_alpha(). ¿Cuánta transparencia? Eso se indica con set_alpha() ; cuanto menor sea el valor que le pasemos, tanto más transparente será. Finalmente, pintamos el cuadrado entero del color deseado con fill() y se dibuja el resultado sobre la surface que se ha pasado al objeto (típicamente, nuestro visor). 3. Al método update(), si recordamos lo que hemos visto en la clase Juego, le pasamos el valor de evento.unicode (la tecla pulsada). Ese parámetro lo hemos llamado tecla en la implementación de la función. El objetivo es añadir dicha tecla a la variable frase y dibujar el resultado. PÁGINA 4 DE 10 CC: FERNANDO SALAMERO
  • 5. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO Las primeras dos líneas posicionan dónde va a escribirse, dejando el margen pertinente. A continuación se añade a frase el valor de tecla (todo está en unicode, así que es correcto), se dibuja el marco semitransparente, se dibuja el texto y se actualiza la pantalla para que se muestre. ¡Muy bien! Clase Narrar Muestra la descripción del lugar donde se encuentra el jugador o cualquier otro mensaje que se desee como respuesta a una acción, a través de su atributo texto. La idea es hacerlo de forma similar a la clase anterior pero ahora el problema es distinto. El texto entero ya lo tenemos pero, por contra, puede ser muy largo y ocupar muchas líneas. La clase se encargará de ajustar automáticamente el texto al tamaño disponible. 1. __init__() almacena, como es habitual, los parámetros con los que se crea el objeto en atributos propios (para usarlos posteriormente). Hay un añadido, como ya hemos comentado, texto. 2. cortaTexto() es un método que toma como argumento un número que representa el tamaño máximo en pixeles que puede ocupar una línea de texto. El objetivo de la función es, partiendo del texto almacenado en texto, dividirlo en una lista de líneas que respeten el ancho dado. Con ello se consigue que sea cual sea el valor de texto, se ajuste y quepa dentro de la zona donde se va a escribir. Para realizarlo, y usando nuestra vieja amiga split(), el texto se divide en una lista de líneas de partida (para conservar los puntos y aparte que pudiera tener): lineas = self.texto.split("n") (el código especial ‘n’ es la marca de nueva línea en Linux). A continuación creamos una lista vacía, resultado, en donde se irán añadiendo las lineas con el tamaño correcto. El resto del trabajo se realiza con un bucle for que recorre todas las lineas anteriores. Para cada una de ellas, palabras contiene su lista de palabras (de nuevo usando split()). La idea es ir añadiendo palabras, calcular cuanto tamaño tiene cada una, y si no se supera el tamaño máximo ir a por la siguiente. En el momento en el que se supere dicho tope, se cambia de linea (es decir, se añade la línea a la lista y se empiezan a mirar las siguientes palabras). Intenta seguir el proceso. Ten en cuenta que se calcula el ancho en pixeles de un texto con size(), que se añaden elementos a la lista con el método append() de los objetos list, y que para concatenar textos se usa el método join() de los objetos str. En cualquier caso, la función termina devolviendo como valor de salida a resultado, la lista de líneas deseada. 3. La función update() toma como único argumento un número, margen, cuyo significado es evidente por el nombre. Comenzamos calculando la posición en la que situar el texto horizontalmente, dejando el margen y obteniendo la lista de líneas que se van a escribir, lineas, llamando al método cortaTexto() que hemos visto hace un momento. Observa que se ha tenido en cuenta también el margen para indicar el máximo tamaño disponible (se resta dos veces, contando ambos lados). Para centrar el texto verticalmente, necesitamos saber cuanto ocupan las líneas. En nuestro auxilio viene el método get_linesize() de los objetos Font. Nos devuelve la altura en pixeles que ocupa una linea de texto con ese tipo de letra. Una vez conocido, para conseguir que el texto quede en la parte central de la zona de impresión, calculamos su coordenada vertical así: PÁGINA 5 DE 10 CC: FERNANDO SALAMERO
  • 6. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO posy = self.rect.top + (self.rect.h - alturaLinea * len(lineas)) / 2 (observa que a la altura de la zona que ocupa el texto, se le resta la altura total de todas las líneas y el resultado se divide por dos para que el margen sea el mismo por arriba que por abajo; probablemente necesitarás hacerte un dibujo para entenderlo). Ya podemos pasar a dibujar. Primero, de forma similar a como hacía la función cuadrado() en la clase Hablar, dibujamos el cuadrado de fondo semitransparente. A continuación, recorremos todas las líneas del texto y las dibujamos. Fíjate que después de dibujar una línea, se añade a posy el valor de la altura de la línea calculada para que la siguiente se dibuje debajo, en el lugar correcto. Y, finalmente, se vuelca todo en pantalla para que lo visualice el jugador. función procesar() En un juego real esta función sería bastante más complicada y extensa y ésta es la razón por lo que se implementa como una función externa y no como un método más de la clase Juego. De hecho, para poder modificarlo, juego se pasa como argumento a la función. Nuestro procesar() simplemente comprueba cuál es la imagen de fondo actual (es decir, juego.image) para actuar convenientemente. Si se trata de castillo sólo haremos caso cuando la frase que ha escrito el jugador sea ‘norte’; entonces cambiamos la imagen a patio y la descripción a frase2. Algo similar ocurre cuando la imagen actual es patio; la única salida es al sur y sólo se obedece en tal caso. Por otra parte, si el jugador escribe ‘salir’ el juego debe terminar. Lo dicho, en un juego serio aquí se harían muchas comprobaciones. Además, nadie nos impide añadir más atributos a la clase Juego para que se almacene más información sobre el jugador (objetos que lleva, salud, armas, etc). Recuerda que en el juego ‘TheHouse’, el parser era bastante largo y usaba bastantes variables de estado. Cuerpo Principal del Juego Llegamos al último bloque del juego. Para empezar, cargamos las imágenes de fondo castillo y patio y definimos las descripciones de ambas localizaciones, frase1 y frase2. En un juego completo, lo ideal sería una lista o un diccionario y no variables sueltas. Continuamos definiendo los tipos de letra para la descripción de los lugares y las situaciones (letraNarrar) y para el diálogo con el ordenador (letraHablar). También se definen las zonas donde se van a mostrar con sendos Rect (dondeTexto y dondeComando). Justo antes del bucle del juego se crean los objetos que lo controlan; narrar, hablar y juego. En la creación de este último se usan los dos anteriores. Observa que para inicializar el juego necesitamos proporcionarle los datos de por donde empezar. La imagen de fondo se pasa al crearlo (castillo) y la descripción del lugar se pone a mano con narrar.texto = frase1 Finalmente, el bucle del juego realiza una y otra vez las dos tareas obvias; mostrar en pantalla la situación actualizada y esperar las acciones del usuario con juego.update() y procesar lo que haya introducido el jugador con procesar(juego). PÁGINA 6 DE 10 CC: FERNANDO SALAMERO
  • 7. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO # -*- coding: utf-8 -*- #------------------------------------------------------------------- # aventura.py # (cortaTexto basado en un script de Tiny Ducks On Wheels) #------------------------------------------------------------------- import pygame, sys from pygame.locals import * AMARILLO = (200,200,0) BLANCO = (200,200,200) VERDE = (0,100,0) LILA = (50,0,50) pygame.init() visor = pygame.display.set_mode((800,600)) #------------------------------------------------------------------- # Clase Juego # (Clase principal que coordina las demás) #------------------------------------------------------------------- class Juego: def __init__(self, surface, imagen, narrar, hablar): self.surface = surface self.image = imagen self.narrar = narrar self.hablar = hablar def update(self): self.surface.blit(self.image, (0,0)) self.narrar.update(10) self.escuchar() def escuchar(self): maximo = self.hablar.rect.w / self.hablar.tipoLetra.size('a')[0] self.hablar.frase = u'' self.hablar.cuadrado() pygame.display.update() hablando = True while hablando: for evento in pygame.event.get(): if evento.type == QUIT: pygame.quit() sys.exit() elif evento.type == KEYDOWN: PÁGINA 7 DE 10 CC: FERNANDO SALAMERO
  • 8. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO if evento.key == K_RETURN: hablando = False elif evento.key == K_BACKSPACE: self.hablar.frase = self.hablar.frase[:-1] self.hablar.update(u'') elif len(self.hablar.frase) < maximo: self.hablar.update(evento.unicode) #------------------------------------------------------------------- # Clase Hablar # ( Gestiona ka introducción de texto del usaurio) #------------------------------------------------------------------- class Hablar: def __init__(self, surface, rect, tipoLetra, colorTexto, colorFondo): self.surface = surface self.rect = rect self.tipoLetra = tipoLetra self.color = colorTexto self.colorFondo = colorFondo self.margen = 10 self.frase = u'' def cuadrado(self): cuadrado = pygame.Surface((self.rect.w,self.rect.h)) cuadrado.convert_alpha() cuadrado.set_alpha(200) cuadrado.fill(self.colorFondo) self.surface.blit(cuadrado, self.rect.topleft) def update(self, tecla): x = self.rect.left + self.margen y = self.rect.top + self.margen self.frase += tecla self.cuadrado() self.surface.blit(self.tipoLetra.render(self.frase, True, self.color), (x,y)) pygame.display.update() #------------------------------------------------------------------- # Clase Narrar # ( Muestra las descripciones de las situaciones) #------------------------------------------------------------------- class Narrar: def __init__(self, surface, rect, tipoLetra, colorTexto, colorFondo): self.surface = surface self.rect = rect self.tipoLetra = tipoLetra self.color = colorTexto PÁGINA 8 DE 10 CC: FERNANDO SALAMERO
  • 9. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO self.colorFondo = colorFondo self.texto = u'' def cortaTexto(self, anchoTotal): lineas = self.texto.split("n") resultado = [] for linea in lineas: palabras = linea.split(" ") comienzo = 0 i=0 while i < len(palabras): ancho = self.tipoLetra.size(" ".join(palabras[comienzo:i+1]))[0] if ancho > anchoTotal: resultado.append(" ".join(palabras[comienzo:i])) comienzo = i i -= 1 elif i is len(palabras) - 1: resultado.append(" ".join(palabras[comienzo:i + 1])) i += 1 return resultado def update(self, margen): posx = self.rect.left + margen lineas = self.cortaTexto(self.rect.width - 2*margen) alturaLinea = self.tipoLetra.get_linesize() posy = self.rect.top + (self.rect.h - alturaLinea * len(lineas)) / 2 cuadrado = pygame.Surface((self.rect.w, self.rect.h)) cuadrado.convert_alpha() cuadrado.set_alpha(200) cuadrado.fill(self.colorFondo) self.surface.blit(cuadrado, (self.rect.left,self.rect.top)) for linea in lineas: self.surface.blit(self.tipoLetra.render(linea, True, self.color), (posx, posy)) posy = posy + alturaLinea pygame.display.update() #------------------------------------------------------------------- # Función procesar() # ( El parser del juego) #------------------------------------------------------------------- def procesar(juego): if juego.image == castillo and juego.hablar.frase == 'norte': juego.image = patio juego.narrar.texto = frase2 elif juego.image == patio and juego.hablar.frase == 'sur': PÁGINA 9 DE 10 CC: FERNANDO SALAMERO
  • 10. PROGRAMA: AVENTURA CURSO: 1º BACHILLERATO juego.image = castillo juego.narrar.texto = frase1 elif juego.hablar.frase == 'salir': pygame.quit() sys.exit() #------------------------------------------------------------------- # Cuerpo Principal del Juego #------------------------------------------------------------------- castillo = pygame.image.load('castillo.jpg').convert() patio = pygame.image.load('patio.png').convert() frase1 = u'Abres los Ojos...nNo recuerdas nada. ¿Dónde estás? Al norte hay una puerta.' frase2 = u'Un patio se abre ante ti. Al sur está la puerta que has traspasado.' letraHablar = pygame.font.Font('Grandezza.ttf', 24) letraNarrar = pygame.font.Font('Adolphus.ttf', 24) dondeTexto = pygame.Rect((100,300,600, 200)) dondeComando = pygame.Rect((100,550,600,40)) narrar = Narrar(visor, dondeTexto, letraNarrar, AMARILLO, LILA) hablar = Hablar(visor, dondeComando, letraHablar, BLANCO, VERDE) juego = Juego(visor, castillo, narrar, hablar) narrar.texto = frase1 while True: juego.update() procesar(juego) PÁGINA 10 DE 10 CC: FERNANDO SALAMERO