Python
Contenido
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 determinadoa 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
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
#Creacion de la clase circulo
class Circulo:
def __init__(self, position, size, color = (255,255,255), velocity= eucly.Vector2(0,0), width=1):
self.position = position
self.size = size
self.color = color
self.width = width
self.velocity = velocity
def display(self):
rx, ry = int(self.position.x), int(self.position.y)
pygame.draw.circle(screen, self.color, (rx, ry), self.size, self.width)
def move(self):
self.position = self.position + dtime * self.velocity
def change_velocity(self,velocidad):
self.velocity = velocity
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:
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