Diferencia entre revisiones de «Python»

De Wikitronica
Saltar a: navegación, buscar
Línea 249: Línea 249:
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
import os, sys, math, pygame
 
import os, sys, math, pygame
 
 
from pygame.locals import *
 
from pygame.locals import *
  
 
#Definir Colores
 
#Definir Colores
 
 
negro = 0, 0, 0
 
negro = 0, 0, 0
 
 
blanco = 255, 255, 255
 
blanco = 255, 255, 255
 
 
rojo = 255, 0, 0
 
rojo = 255, 0, 0
 
 
verde = 0, 255, 0
 
verde = 0, 255, 0
 
 
azul = 0, 0, 255
 
azul = 0, 0, 255
  
 
#Preparar el Screen
 
#Preparar el Screen
 
 
screen = pygame.display.set_mode((800, 600))
 
screen = pygame.display.set_mode((800, 600))
  
 
#Definicion de la clase circulo
 
#Definicion de la clase circulo
 
 
class Circulo:
 
class Circulo:
  
def __init__(self, (x,y), size, color=(255,255,255), width=1):
+
    def __init__(self, (x,y), size, color=(255,255,255), width=1):
 +
          self.x = x
 +
          self.y = y
 +
          self.size = size
 +
          self.color = color
 +
          self.width = width
  
self.x = x
+
    def display(self):
 
+
          pygame.draw.circle(screen, self.color, (self.x, self.y), self.size,self.width)
self.y = y
+
 
+
self.size = size
+
 
+
self.color = color
+
 
+
self.width = width
+
 
+
def display(self):
+
 
+
pygame.draw.circle(screen, self.color, (self.x, self.y), self.size,self.width)
+
  
 
#Creacion de objetos
 
#Creacion de objetos
 
 
circulo1 = Circulo((100,100), 30, azul, 0)
 
circulo1 = Circulo((100,100), 30, azul, 0)
 
 
circulo2 = Circulo((200,300), 40, verde, 8)
 
circulo2 = Circulo((200,300), 40, verde, 8)
 
 
circulo3 = Circulo((600,500), 20)
 
circulo3 = Circulo((600,500), 20)
 
 
circulo4 = Circulo((700,300), 50,rojo,4)
 
circulo4 = Circulo((700,300), 50,rojo,4)
  
 
#Generar Reloj
 
#Generar Reloj
 
 
clock = pygame.time.Clock()
 
clock = pygame.time.Clock()
  
 
#Ciclo continuo del programa
 
#Ciclo continuo del programa
 
 
fps = 30 #30 cuadros por segundo
 
fps = 30 #30 cuadros por segundo
 
 
correr = True
 
correr = True
  
 
while correr:
 
while correr:
 +
    clock.tick(fps)
 +
          for event in pygame.event.get():
 +
              if event.type == pygame.QUIT:
 +
                    correr = False
  
clock.tick(fps)
+
    screen.fill(negro)
 
+
    circulo1.display()
for event in pygame.event.get():
+
    circulo2.display()
 
+
    circulo3.display()
if event.type == pygame.QUIT:
+
    circulo4.display()
 
+
    pygame.display.flip()
correr = False
+
 
+
screen.fill(negro)
+
 
+
circulo1.display()
+
 
+
circulo2.display()
+
 
+
circulo3.display()
+
 
+
circulo4.display()
+
 
+
pygame.display.flip()
+
  
 
pygame.quit()
 
pygame.quit()
 
 
sys.exit()
 
sys.exit()
 
</syntaxhighlight>
 
</syntaxhighlight>

Revisión del 21:00 21 abr 2013


Inicializaciones

Módulos

Los módulos son archivos que contienen las definiciones y argumentos utilizados en Python, por lo que se debe comenzar el programa importando los que necesitemos, esto se realiza a través del comando import. Algunos módulos son standard, como sys, mientras que otros dependen de lo que se quiera realizar, como pygame o serial.

Además, se pueden importar archivos .py que contengan definiciones o funciones que deseemos utilizar en nuestro programa, y, de esta manera, un programa muy largo se puede fragmentar en varios archivos distintos.

Por ejemplo, un modelo de inicialización de módulos sería:

import sys, pygame       #Importa modulo pygame
from pygame.locals import *
import serial            #Importa modulo para comunicacion serial

El * colocado importa todas las definiciones menos aquellas que comiencen por guión bajo (_).

Si se desea utilizar pygame, se debe iniciar utilizando pygame.init() en la función principal.

Imágenes y audio

Para utilizar imágenes o audio en el programa (utilizando pygame), primero los archivos deben estar en la misma carpeta del proyecto, luego se deben cargar empleando:

#Para cargar imagenes
foto = pygame.image.load("foto.jpg")

#Para cargar y reproducir audio:
loops = -1     #Cantidad de veces que se repetira la cancion, -1 significa que siempre se repite
start = 0.0    #Determina el tiempo en el que empezara la pieza
pygame.mixer.music.load("cancion.mp3")
pygame.mixer.music.play(loops,start)

#Para dejar de reproducir audio:
pygame.mixer.music.stop()

Los formatos de imagen permitidos por pygame son:

  • JPG
  • PNG
  • GIF (Inanimada)
  • BMP
  • PCX
  • TGA (Sin comprimir)
  • TIF
  • LBM
  • PBM, PGM, PPM
  • XPM

Pantalla

Para configurar las características de la ventana, es decir, su tamaño, el nombre, y la imagen de fondo, se puede proceder como sigue:

#Esta es la funcion principal mencionada previamente

def main():
  
  pygame.init()                                     #Inicio Pygame
  screen = pygame.display.set_mode((1024, 720))     #Crea una ventana de 1024 de ancho por 720 de alto de nombre screen       
  pygame.display.set_caption("Python-Wikitronica")  #Nombre de la ventana (esquina superior izquierda)  
  fondo = pygame.image.load("Fondo.jpg")            #Cargo la imagen de fondo  
  screen.blit(fondo, (0, 0))                        #la dibujo en "screen", en la posicion (0,0)
  pygame.display.flip()                             #Actualizo toda la superficie de la pantalla

Para mejores resultados, hacer la imagen de fondo del mismo tamaño de la pantalla. Y nótese, que se debe mantener el margen en todas las líneas de código porque sino se tendrá el error "IndentationError: unexpected indent"

Escritura y dibujo

Escritura

Para escribir en pantalla, se procede de una manera similar a mostrar una imagen. Primero, se debe determinar la fuente con la cual se escribirá, luego se escribe el mensaje y se muestra en pantalla. Esto se puede realizar de la siguiente forma:

#Opcion 1 para seleccionar la fuente
fuente = pygame.font.Font(None, 25)  #None es el tipo de letra default. 25 es el tamaño de la letra
# Para esta opcion, si se quiere usar una fuente distinta, el archivo debe estar en la misma carpeta del programa y se coloca:
fuente2 = pygame.font.Font("Nombredefuente.ttf", 25)

#Opcion 2
print pygame.font.get_fonts()              #Con este comando se ven todas las fuentes que se tienen instaladas en el sistema
fuente3 = pygame.font.SysFont('arial', 25) #Se coloca cualquiera de esas fuentes

#Se le asigna un mensaje a una variable
texto = "Programa de prueba. Python-Wikitronica"

#Font.render(text, antialias, color, background=None)
mensaje = fuente.render(texto, 1, (0, 0, 0))       #Se escriben en color negro, con el tipo de letra de la variable fuente.
                                                   #background=None (No se pone ningun color de fondo)
#Se muestra en pantalla
SCREEN.blit(mensaje, (400, 400))    #Se muestra en la posición (400,400)
pygame.display.flip()               #Actualizo toda la superficie de la pantalla

Colores

Los colores se basan en el sistema RGB (Red, Green, Blue), y están determinados por un vector de tres coordenadas, donde la primera indica el grado de rojo, la segunda de verde y la tercera de azul. Así, si colocamos 0 en las tres coordenadas se tendrá negro, y si colocamos lo máximo, es decir, 255 ($FF), se tendrá blanco; el resto de los colores se obtiene por mezcla de estas tonalidades.

  • Negro = (0,0,0)
  • Blanco = (255,255,255)
  • Rojo = (255,0,0)
  • Verde = (0,255,0)
  • Azul = (0,0,255)
  • Amarillo = (255,255,0)
  • Magenta =(255,0,255)
  • Cian=(0,255,255)

Ver Tabla de colores para mayor información

Dibujo

Pygame permite dibujar diversas formas geométricas como rectángulos, círculos, elipses, polígonos, líneas, etc; de manera sencilla, utilizando la función draw. La sintaxis de cada una depende de la figura a dibujar, a continuación mostraremos los casos del rectángulo, círculo y arco:

#rect(Surface, color, Rect, width=0)
#El parametro Rect es un vector de 4 coordenadas en donde se coloca (PosX,PosY,Ancho,Largo)

#Creamos un rectangulo blanco en la posicion (20,20) de ancho 100 pixeles y largo 50 pix
rectangulo1=pygame.draw.rect(screen,(255,255,255),(20,20,100,50))

#circle(Surface, color, pos, radius, width=0)
#Creamos un circulo negro de centro (40,40) y radio 15pix
Circulo1=pygame.draw.circle(screen,(0,0,0),(40,40),15)

#arc(Surface, color, Rect, start_angle, stop_angle, width=1) Rect establece al area que llenara el arco
#Se crea un arco azul que empieza en pi y termina en 2pi, el angulo se mide en radianes
Arco1=pygame.draw.arc(screen,(0,0,255),(20,20,100,50),3.1416,3.1416*2)

Eventos de teclado

A partir de pygame se puede ver si determinada tecla está presionada de una manera sencilla utilizando los eventos de teclado. Éstos se colocan dentro de un for que "captura" el evento y luego se ve si la tecla (representadas por constantes en pygame) está presionada o no.

for event in pygame.event.get():     #capturo el evento   
    if event.type == pygame.KEYDOWN: #Caso para tecla presionada  
       if event.key== K_a:           #Si la tecla es la letra a
           #realizo cualquier accion
       elif event.key == K_UP:       #Si la tecla es la flecha hacia arriba
           #realizo accion
    elif event.type == pygame.KEYUP: #Caso para teclas levantadas
        #Realizo accion

Nótese que el margen es el que establece qué está dentro de cada condicional. Ver el apartado Teclas de la sección de referencias para mayor información sobre las constantes.

Pygame también permite tomar en cuenta los modificadores de teclado como caps lock, numlock, ctrl, etc; esto se ve a través de los KMODS, por ejemplo:

for event in pygame.event.get():     #capturo el evento   
    if event.type == pygame.KEYDOWN: #Caso para tecla presionada        
         if pygame.key.get_mods() & KMOD_SHIFT: #Si la tecla shift esta presionada
             #realizo cualquier accion

La siguiente figura corresponde a un ejemplo de los puntos 1, 2 y 3

Ejemplo de los puntos 1, 2 y 3



Programación Orientada a Objetos

Python puede funcionar con programación orientada a objetos, de forma similar a como lo hace JAVA. En este tipo de programación se definen una clases, que son análogas a las structuras en C, salvo que dichas clases incluyen además ciertas operaciones (funciones) que puede ejecutar el objeto. Esto quiere, a muy groso modo, lo siguiente:


  • Uno puede definir tipos de objetos llamados clases. Por ejemplo: las clases de los círculos, los perros, etc.
  • Estas clases tienen atributos propios de sí. Por ejemplo: los círculos tienen radio, centro, color, etc.
  • Las clases incluyen funciones, que son operaciones que pueden realizar en un determinado momento. Por ejemplo: un círculo puede aparecer en pantalla, moverse, etc.
  • Las clases pueden generar varios objetos, que son especies de variables de un determinado tipo de dato, salvo por que incluyen las funciones ya mencionadas.
  • Si se genera más de un objeto de una determinada clase, ambos objetos serán en esencia idénticos a menos que utilicemos un constructor para diferenciarlos.
  • Un constructor es una función que inicializa los parámetros de nuestro objeto y que permite distinguirlo de los demás dándole un nombre y características distintas.
  • Una determinada clase puede tener más de un constructor si es necesario.


Definición de una Clase

Ahora veamos más en detalle cada una de las partes de una definición de clase: Lo primero que debemos hacer es colocar la etiqueta "class" seguida del nombre que le queremos colocar a nuestra clase, lo segundo es declarar el inicializador (constructor) con los campos que tendrá. Este constructor es una función llamada "__init__" que recibe al propio objeto "__init__(self)" y a toda una serie de parámetros que le colocamos a nuestro objeto. En este caso, además del propio objeto, tenemos como elementos: la posición (x,y) el radio (size), el color, y el espesor. Para este constructor en particular, si se crea el objeto, puede no especificársele ni el color ni el espesor, ya que tienen valores por defecto, sin embargo, todos los demás datos deben ser indicados para cada objeto de la clase.

#Creacion de la clase circulo

class Circulo:

     def __init__(self, x, y, size, color = (255,255,255), width=1):
          self.x = x
          self.y = y
          self.size = size
          self.color = color
          self.width = width

Definida la clase del ejemplo, las siguientes son llamadas posibles para crear objetos

#Creacion de objetos de clase circulo
     mi_circulo1 = Circulo(100, 100, 30, (255,0,0), 0) #Crea un circulo con centro en (100,100) radio 30, color rojo y espesor=0 (completamente relleno)
     mi_circulo2 = Circulo(300, 200, 50)               #Crea un circulo con centro en (300,200) radio 50, color blanco y espesor = 1
     mi_circulo3 = Circulo(300, 500, 60, (0,0,255))    #Crea un circulo con centro en (300,500) radio 60, color azul y espesor = 1

Sin embargo, un objeto es algo vacío si no tiene asociadas las acciones que este puede hacer. La siguiente versión muestra la clase Círculo, esta vez con una acción que le permite aparecer en pantalla; la función display. Nótese que esta acción tiene una única instrucción que llama a pygame.draw.circle, pero la cantidad de instrucciones que puede tener cada acción y la cantidad de acciones por clase no es limitada.

#Creacion de la clase circulo con funciones

class Circulo:

     def __init__(self, x, y, size, color = (255,255,255), width=1):
          self.x = x
          self.y = y
          self.size = size
          self.color = color
          self.width = width

     def display(self):
          pygame.draw.circle(screen, self.color, (self.x, self.y), self.size, self.width)

Declarada esta variante de la clase, pueden crearse objetos circulos que, en cualquier parte del programa, pueden llamarse a aparecer en pantalla mediante la instrucción

#Llamada de la funcion display para un determinado circulo
     mi_circulo1.display()
     mi_circulo3.display()


Ejemplo completo de utilización de Clases

import os, sys, math, pygame
from pygame.locals import *

#Definir Colores
negro = 0, 0, 0
blanco = 255, 255, 255
rojo = 255, 0, 0
verde = 0, 255, 0
azul = 0, 0, 255

#Preparar el Screen
screen = pygame.display.set_mode((800, 600))

#Definicion de la clase circulo
class Circulo:

     def __init__(self, (x,y), size, color=(255,255,255), width=1):
          self.x = x
          self.y = y
          self.size = size
          self.color = color
          self.width = width

     def display(self):
          pygame.draw.circle(screen, self.color, (self.x, self.y), self.size,self.width)

#Creacion de objetos
circulo1 = Circulo((100,100), 30, azul, 0)
circulo2 = Circulo((200,300), 40, verde, 8)
circulo3 = Circulo((600,500), 20)
circulo4 = Circulo((700,300), 50,rojo,4)

#Generar Reloj
clock = pygame.time.Clock()

#Ciclo continuo del programa
fps = 30 #30 cuadros por segundo
correr = True

while correr:
     clock.tick(fps)
          for event in pygame.event.get():
               if event.type == pygame.QUIT:
                    correr = False

     screen.fill(negro)
     circulo1.display()
     circulo2.display()
     circulo3.display()
     circulo4.display()
     pygame.display.flip()

pygame.quit()
sys.exit()


Animaciones

Python presenta muchas ventajas con respecto a otros lenguajes de programación, pero quizás uno de sus puntos más fuertes es la facilidad con la que permite realizar animaciones. Para esto se podría simplemente pedirle al programa que dibuje una secuencia determinada de imágenes a una cierta velocidad, por ejemplo 30 FPS. Sin embargo, esto requiere una gran cantidad de imágenes y existen formas mucho más prácticas de animar objetos, como la que explicaremos a continuación.

Antes que nada se requiere una librería llama Pyeuclid que incluye ya prefabricadas una gran cantidad de funciones de gran utilidad, esta librería se puede obtener aquí: Acceso a Pyeuclid En los vínculos externos seleccionamos euclid.py y se nos despliega una página con todo el contenido del archivo. Este contenido lo debemos guardar en un archivo de extensión ".py" usando por ejemplo notepad o notepad++ y lo colocamos en el mismo directorio del programa de animaciones en el que estamos trabajando.

Hecho esto podemos comenzar a trabajar importando el archivo.




Pyserial

Un módulo de interés al utilizar Python(x,y) combinado con nuestro microcontrolador es Pyserial.

Pyserial es muy amigable y fácil de utilizar pues los grandes conjuntos de instrucciones utilizados para la transmisión y recepción de información a los que estamos acostumbrados se resumen en funciones muy sencillas de manejar.

Al trabajar con puerto serial en Python lo primero que se debe hacer es importar la librería de serial, luego abrir el o los puertos y configurarlos a la velocidad de transmisión deseada. A continuación se muestra un ejemplo de como hacer esto:

import serial                         #Importa modulo para comunicacion serial
ser = serial.Serial('COM10',9600)      #Abre el puerto COM1 y lo configura para transmitir a 9600baud

Es importante saber que puerto es el que deseamos abrir, y la manera de identificarlo es buscándo a través del administrador de dispositivos (Device Manager) ubicado en el panel de control. La siguiente imágen busca ilustrar un poco como conseguir esta información:


Buscar Información Sobre El Puerto Serial



Una vez inicializado el puerto de manera correcta, las rutinas de transmisión y recepción son bien sencillas:


# Para Lectura a través de serial

x = ser.read()       # Capturar un byte por serial y almacenarlo en X
s = ser.read(10)     # Capturar hasta 10 bytes y almacenarlos en S


# Para Escritura a través de serial

ser.write("hello")   # Envia por puerto serial la cadena de caracteres o el caracter escritos


Referencias

Contributors

Anny, GMarzinotto