[..Tuto ..] pygame: re dimensionar ventana y pantalla de videojuegos
Upcoming SlideShare
Loading in...5
×
 

[..Tuto ..] pygame: re dimensionar ventana y pantalla de videojuegos

on

  • 701 views

En este tutorial se explicará un método para re-dimensionar la ventana de videojuegos ...

En este tutorial se explicará un método para re-dimensionar la ventana de videojuegos
programados en python y pygame, manteniendo las proporciones de la pantalla de
videojuegos, es decir las imágenes del escenario que contenga el juego.

Statistics

Views

Total Views
701
Views on SlideShare
343
Embed Views
358

Actions

Likes
0
Downloads
9
Comments
0

6 Embeds 358

http://ingenieria-dragogear.blogspot.mx 278
http://ingenieria-dragogear.blogspot.com 44
http://ingenieria-dragogear.blogspot.com.es 21
http://ingenieria-dragogear.blogspot.com.ar 10
http://www.ingenieria-dragogear.blogspot.mx 4
http://ingenieria-dragogear.blogspot.ch 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

[..Tuto ..] pygame: re dimensionar ventana y pantalla de videojuegos [..Tuto ..] pygame: re dimensionar ventana y pantalla de videojuegos Document Transcript

  • [..Tuto ..] Pygame: re-dimensionar ventana y pantalla de videojuegos http://ingenieria-dragogear.blogspot.mx/ Por: José Iván González Torres 4 de julio del 2013 Colaboración de: Regina Esmeralda Hernandez Acuña 1
  • Índice de contenido Introducción.............................................................................................................................................3 1.0 Script mapa0.py..................................................................................................................................4 2.0 Script mapeo.py..................................................................................................................................5 2.1 Importar.........................................................................................................................................9 2.2 Definir cargar imagen....................................................................................................................9 2.3 Definir multiplicar_lista..............................................................................................................10 2.4 Clase mapeo.................................................................................................................................11 2.5 Definir escalar..............................................................................................................................11 2.6 Definir función intangibles..........................................................................................................14 3.0 Script motor.py:................................................................................................................................14 3.1 Constantes y variables.................................................................................................................16 3.2 Definir el bucle de juego.............................................................................................................17 3.3 Re-dimecionara ventana y escalar pantalla.................................................................................17 3.4 Dibujar juego...............................................................................................................................21 Resultados..............................................................................................................................................22 2
  • Introducción En este tutorial se explicará un método para re-dimensionar la ventana de videojuegos programados en python y pygame, manteniendo las proporciones de la pantalla de videojuegos, es decir las imágenes del escenario que contenga el juego. Para lograr la comprensión de este tutorial se analizaran tres scripts “motor.py”, “mapeo.py” y “mapa0.py” todos esto parte de este tutorial y puestos a la disposición del público bajo las licencias “LGPL” junto con una imagen “Terreno-[..IDG..].png” bajo licencia “creative commons atribución”, lo que le permite al público utilizar este material para experimentar o para realizar tus propios proyectos de forma libre siempre y cuando se mencione al autor de dicho material. Todo este material se puede descargar de forma gratuita desde el blog: http://ingenieria-dragogear.blogspot.mx/ Este tutorial es de nivel medio por lo que el lector debe tener conocimientos de python y de pygame. Se recomienda se revise este documento primero y si el lector supone que necesita saber un poco más para entender este tutorial se recomienda ver los video- tutoriales de “Chelin Tutorials” y las diapositivas de “Fernando Salamero”, ambos muy buenos, e aquí los enlaces a cada sitio: Chelin Tutorials http://chelintutorials.blogspot.mx/ http://www.youtube.com/user/ChelinTutorials Fernando Salamero http://www.slideshare.net/fsalamero http://www.slideshare.net/fsalamero/programacin-con-pygame-i Niveles de tutoriales según el autor: Nivel básico: Se explican las formas en que se manejan las herramientas y como funcionan limitándose a ejemplos pequeños del funcionamiento de sus partes y a definiciones sencillas, en este caso las herramientas son python y pygame. Nivel medio: Se explica la forma en que las herramientas y sus distintas partes funcionan a un nivel práctico,demostrando la función que ejercen dentro de un sistema, poniendo poco énfasis en la descripción de las partes de las herramientas. Nivel avanzado: En este nivel solo se tratan mecánicas, usos alternativos y contextos de la forma en la que se pueden usar la herramientas explicando de forma general la función que ejercen en un sistema. 3
  • 1.0 Script mapa0.py En esté escript se le dice a “mapeo.py” como acomodar los tiles y cuales se van a usar, en esta versión de mapa, se utilizan palabras clave para identificar cada tile. Cada lista equivale a una fila donde cada una de las palabras clave es parte de una columna según su posición en la lista, dando como resultado un mapa con 7 filas y 12 columnas. También se incluye una lista auxiliar donde se agregan cada una de las listas que conforman la estructura del escenario del videojuego. L1 = ("c1","c2","c3","c4","c5","c6","c7","c8","c9","o1","o2","o3") L2 = ("o4","o5","o6","o7","o8","o9","o10","o11","o12","o13","o14","o15") L3 = ("o16","o17","o18","o19","o20","o21","o22","o23","o24","o25","o26","o27") L4 = ("t1","t2","t3","t4","t5","t6","t7","t8","t9","t10","t11","t12") L5 = ("t13","t14","t15","t16","t17","t18","t19","t20","t21","t22","t23","t24") L6 = ("t25","t26","t27","t28","t29","t30","t31","t32","h0","h0","h0","h0") L7 = ("h0","h0","h0","h0","h0","h0","h0","h0","h0","h0","h0","h0") mapa = (L1,L2,L3,L4,L5,L6,L7) Esta es la imagen que se utilizara como tileset para crear los escenarios, el tamaño de cada tile es de 100x100 pixeles. Se analiza primero este script para que se entienda mejor como trabaja “mapeo.py”. 4
  • 2.0 Script mapeo.py Este script se utiliza para darle forma al escenario del juego. Utilizando una única imagen se pueden crear escenarios muy variados, de esta forma se reduce el peso del videojuego y se le da más versatilidad. # -*- coding: utf-8 -*- import pygame from pygame import* pygame.init() def cargar_imagen(archivo_de_imagen, transparencia = 1): try: imagen = pygame.image.load(archivo_de_imagen) except pygame.error, message: print "No pudo cargar la imagen" raise SystemExit, message imagen.convert() if transparencia: color_de_transparencia = imagen.get_at((0,0)) imagen.set_colorkey(color_de_transparencia, RLEACCEL) return imagen def multiplicar_lista(lista, multiplo): lista_nueva = [] for x in lista: lista_nueva.append(int(x*multiplo)) return lista_nueva class mapeo(): def __init__(self,superficie, imagen, mapa): self.mapa = mapa self.superficie = superficie self.imagen_base = cargar_imagen(imagen,1) self.imagen = self.imagen_base self.da = 100 #Distancia entre cuadros base self.db = self.da #Distancia entre cuadros # Nada self.ah0 = (0,0,100,100) # Cielo self.ac1 = (100,0,100,100) #Naranja self.ac2 = (200,0,100,100) #Negro self.ac3 = (300,0,100,100) #Blanco self.ac4 = (0,100,100,100) #Rojo self.ac5 = (100,100,100,100) #Amarillo self.ac6 = (200,100,100,100) #Verde 5
  • self.ac7 = (300,100,100,100) #Cian self.ac8 = (400,100,100,100) #Azul self.ac9 = (500,100,100,100) #Morado # Ostaculos self.ao1 = (400,0,100,100) #Contencion Amarilla self.ao2 = (500,0,100,100) #Naranja self.ao3 = (0,300,100,100) #Bloque brillante Rojo self.ao4 = (100,300,100,100) #Amarillo self.ao5 = (200,300,100,100) #Verde self.ao6 = (300,300,100,100) #Cian self.ao7 = (400,300,100,100) #Azul self.ao8 = (500,300,100,100) #Morado self.ao9 = (400,400,100,100) #Naranja self.ao10 = (500,400,100,100) #Gris self.ao11 = (0,400,100,100) #Bloques Rojo self.ao12 = (100,400,100,100) #Amarillo self.ao13 = (200,400,100,100) #Verde self.ao14 = (300,400,100,100) #Azul self.ao15 = (0,500,100,100) #Cian self.ao16 = (100,500,100,100) #Morado self.ao17 = (200,500,100,100) #Naranja self.ao18 = (300,500,100,100) #Gris self.ao19 = (400,500,100,100) #Caja brillante morado self.ao20 = (500,500,100,100) #Naranja self.ao21 = (0,600,100,100) #Rojo self.ao22 = (100,600,100,100) #Amarillo self.ao23 = (200,600,100,100) #Verde self.ao24 = (300,600,100,100) #Cian self.ao25 = (400,600,100,100) #Azul self.ao26 = (500,600,100,100) #Gris self.ao27 = (600,600,100,100) #Reja # Terreno self.at1 = (600,0,100,100) #Blanco self.at2 = (700,0,100,100) self.at3 = (600,300,100,100) self.at4 = (700,300,100,100) self.at5 = (800,0,100,100) #Rojo self.at6 = (900,0,100,100) self.at7 = (800,300,100,100) self.at8 = (900,300,100,100) self.at9 = (1000,0,100,100) #Amarillo self.at10 = (1100,0,100,100) self.at11 = (1000,300,100,100) self.at12 = (1100,300,100,100) self.at13 = (600,100,100,100) #Verde self.at14 = (700,100,100,100) 6
  • self.at15 = (600,400,100,100) self.at16 = (700,400,100,100) self.at17 = (800,100,100,100) #Cian self.at18 = (900,100,100,100) self.at19 = (800,400,100,100) self.at20 = (900,400,100,100) self.at21 = (1000,100,100,100)#Azul self.at22 = (1100,100,100,100) self.at23 = (1000,400,100,100) self.at24 = (1100,400,100,100) self.at25 = (600,200,100,100)#Morado self.at26 = (700,200,100,100) self.at27 = (600,500,100,100) self.at28 = (700,500,100,100) self.at29 = (800,200,100,100)#Naranja self.at30 = (900,200,100,100) self.at31 = (800,500,100,100) self.at32 = (900,500,100,100) def escalar(self, proporcion): self.imagen = self.imagen_base self.imagen = pygame.transform.scale(self.imagen,(int(1200* proporcion),int(700* proporcion))) self.db = self.da*proporcion # Nada self.h0 = multiplicar_lista(self.ah0,proporcion) # Cielo self.c1 = multiplicar_lista(self.ac1,proporcion) self.c2 = multiplicar_lista(self.ac2,proporcion) self.c3 = multiplicar_lista(self.ac3,proporcion) self.c4 = multiplicar_lista(self.ac4,proporcion) self.c5 = multiplicar_lista(self.ac5,proporcion) self.c6 = multiplicar_lista(self.ac6 ,proporcion) self.c7 = multiplicar_lista(self.ac7,proporcion) self.c8 = multiplicar_lista(self.ac8,proporcion) self.c9 = multiplicar_lista(self.ac9,proporcion) # Ostaculos self.o1 = multiplicar_lista(self.ao1,proporcion) self.o2 = multiplicar_lista(self.ao2,proporcion) self.o3 = multiplicar_lista(self.ao3,proporcion) self.o4 = multiplicar_lista(self.ao4,proporcion) self.o5 = multiplicar_lista(self.ao5,proporcion) self.o6 = multiplicar_lista(self.ao6,proporcion) self.o7 = multiplicar_lista(self.ao7,proporcion) self.o8 = multiplicar_lista(self.ao8,proporcion) self.o9 = multiplicar_lista(self.ao9,proporcion) 7
  • self.o10 = multiplicar_lista(self.ao10,proporcion) self.o11 = multiplicar_lista(self.ao11,proporcion) self.o12 = multiplicar_lista(self.ao12,proporcion) self.o13 = multiplicar_lista(self.ao13,proporcion) self.o14 = multiplicar_lista(self.ao14,proporcion) self.o15 = multiplicar_lista(self.ao15,proporcion) self.o16 = multiplicar_lista(self.ao16,proporcion) self.o17 = multiplicar_lista(self.ao17,proporcion) self.o18 = multiplicar_lista(self.ao18,proporcion) self.o19 = multiplicar_lista(self.ao19,proporcion) self.o20 = multiplicar_lista(self.ao20,proporcion) self.o21 = multiplicar_lista(self.ao21,proporcion) self.o22 = multiplicar_lista(self.ao22,proporcion) self.o23 = multiplicar_lista(self.ao23,proporcion) self.o24 = multiplicar_lista(self.ao24,proporcion) self.o25 = multiplicar_lista(self.ao25,proporcion) self.o26 = multiplicar_lista(self.ao26,proporcion) self.o27 = multiplicar_lista(self.ao27,proporcion) # Terreno self.t1 = multiplicar_lista(self.at1,proporcion) self.t2 = multiplicar_lista(self.at2,proporcion) self.t3 = multiplicar_lista(self.at3,proporcion) self.t4 = multiplicar_lista(self.at4,proporcion) self.t5 = multiplicar_lista(self.at5,proporcion) self.t6 = multiplicar_lista(self.at6,proporcion) self.t7 = multiplicar_lista(self.at7,proporcion) self.t8 = multiplicar_lista(self.at8,proporcion) self.t9 = multiplicar_lista(self.at9,proporcion) self.t10 = multiplicar_lista(self.at10,proporcion) self.t11 = multiplicar_lista(self.at11,proporcion) self.t12 = multiplicar_lista(self.at12,proporcion) self.t13 = multiplicar_lista(self.at13,proporcion) self.t14 = multiplicar_lista(self.at14,proporcion) self.t15 = multiplicar_lista(self.at15,proporcion) self.t16 = multiplicar_lista(self.at16,proporcion) self.t17 = multiplicar_lista(self.at17,proporcion) self.t18 = multiplicar_lista(self.at18,proporcion) self.t19 = multiplicar_lista(self.at19,proporcion) self.t20 = multiplicar_lista(self.at20,proporcion) self.t21 = multiplicar_lista(self.at21,proporcion) self.t22 = multiplicar_lista(self.at22,proporcion) self.t23 = multiplicar_lista(self.at23,proporcion) self.t24 = multiplicar_lista(self.at24,proporcion) self.t25 = multiplicar_lista(self.at25,proporcion) self.t26 = multiplicar_lista(self.at26,proporcion) self.t27 = multiplicar_lista(self.at27,proporcion) 8
  • self.t28 = multiplicar_lista(self.at28,proporcion) self.t29 = multiplicar_lista(self.at29,proporcion) self.t30 = multiplicar_lista(self.at30,proporcion) self.t31 = multiplicar_lista(self.at31,proporcion) self.t32 = multiplicar_lista(self.at32,proporcion) def intangibles(self): y_contador = 0 for x in self.mapa.mapa: x_contador = 0 for y in x: y = "self." + y y = eval(y) self.superficie.blit(self.imagen,(x_contador*self.db, y_contador*self.db),y) x_contador += 1 y_contador += 1 2.1 Importar En esta parte del script se le dice a python que se quiere usar acentos y la letra ”ñ” por medio de “# -*- coding: utf-8 -*-”, luego importamos pygame y lo inicializamos. # -*- coding: utf-8 -*- import pygame from pygame import* pygame.init() 2.2 Definir cargar imagen Aquí se define una función para cargar el tileset, es decir la imagen que contendrá los cuadros que conformaran las ensenas del videojuego y como parámetros se requiere la ubicación de la imagen y si esta contiene transparencias, en este caso por defecto se coloco “1” al parámetro de transparencia. def cargar_imagen(archivo_de_imagen, transparencia = 1): try: imagen = pygame.image.load(archivo_de_imagen) except pygame.error, message: print "No pudo cargar la imagen" raise SystemExit, message imagen.convert() if transparencia: color_de_transparencia = imagen.get_at((0,0)) imagen.set_colorkey(color_de_transparencia, RLEACCEL) return imagen 9
  • Con “try” se intenta cargar la imagen, si no se logra, la función imprimirá en la terminal un mensaje de "No pudo cargar la imagen" y el programa se cerrará, en caso contrario la función proseguirá y aplicará una conversión de imagen, lo cual mejora el rendimiento al manejar las imágenes en pygame. Si la imagen lo requiere se le aplica transparencia transformando el color del pixel superior izquierdo en el color de transparencia de la imagen. 2.3 Definir multiplicar_lista Para comprender el “¿por qué?” de esta función, se debe comprender la composición de los tiles. Un tile es una fragmento de imagen que se define por una variable o una contante, por ejemplo: c1 = (100,0,100,100) Aquí “c1” esta conformado por una tupla de cuatro valores , el primero indica su posición en el eje “x” y el segundo su posición en el eje “y”, el tercero indica su extensión en el eje “x” con respecto al primer numero de la tupla y el cuarto es la extensión con respecto al segundo número de la tupla, es decir “c1” se ubica en el punto (100,0) y se extiende (100,100) de forma que el cuadro se definiría del punto (100,0) hasta el punto (200,100). Esta es una función para multiplicara las dimensiones de los tiles según la proporción a la que la ventana se extienda o se encoja. La función necesita dos parámetros, una lista que contenga números y un número para multiplicar. Para la función se crea la variable “lista_nueva = []” y después se recorre con un ciclo “for”, para agregar a la “lista_nueva” el valor del número recorrido multiplicado por el parámetro “multiplo”, al término del ciclo “for” la función devuelve la “lista_nueva” def multiplicar_lista(lista, multiplo): lista_nueva = [] for x in lista: lista_nueva.append(int(x*multiplo)) return lista_nueva 10
  • 2.4 Clase mapeo La clase mapeo será la responsable de leer el “mapa0.py” e identificar y dibujar en la pantalla del juego los tiles para la escena. Para esta clase se necesitan tres parámetros, la superficie donde se dibujará la escena, la imagen del tileset y el mapa (mapa0.py). Como la imagen va a ser re-dimensionada se carga la imagen original en “self.imagen_base” y luego se copea en “self.imagen” para evitar el deterior de la imagen en cada transformación de escala. De la misma forma se guarda una constante de distancia “self.da” y se copea en “self.db”, esto se hace con el fin de conservar la proporción de la distancia entre tiles. class mapeo(): def __init__(self,superficie, imagen, mapa): self.mapa = mapa self.superficie = superficie self.imagen_base = cargar_imagen(imagen,1) self.imagen = self.imagen_base self.da = 100 #Distancia entre cuadros base self.db = self.da #Distancia entre cuadros En esta sección solo se listan los tiles base para que puedan ser codificados, se incluyen algunas notas para identificar a tile corresponde cada constante. # Nada self.ah0 = (0,0,100,100) # Cielo self.ac1 = (100,0,100,100) #Naranja self.ac2 = (200,0,100,100) #Negro self.ac3 = (300,0,100,100) #Blanco ... ... self.at32 = (900,500,100,100) 2.5 Definir escalar El propósito de esta función es ajustar los tiles con ayuda de la función “multiplicar_lista()” para que se escalen respecto al tamaño de la ventana, para lograrlo se necesita un parámetro que de la proporción, con un valor unitario base, es decir: 1 = 100%, 0.5 = 50%, 2.17 = 217%, etc.. def escalar(self, proporcion): self.imagen = self.imagen_base self.imagen = pygame.transform.scale(self.imagen,(int(1200* proporcion),int(700* proporcion))) self.db = self.da*proporcion 11
  • Una vez se tenga la proporción, la función “escalar” puede trabajar empezando por volver a copiar la imagen base en “self.imagen” para luego escalarla con “pygame.transform.scale(self.imagen,(int(1200* proporcion),int(700* proporcion)))” donde 1200 es el ancho de la imagen original y 700 el alto, Como se ve en los ejemplos ambos valores se convierten en enteros después de multiplicarse por la proporción, esto se hace con el fin de evitar errores posteriores al introducir valores flotantes (valores con decimales) donde corresponden valores enteros. Luego se escala la distancia entre tile “self.db” para que la distancia corresponda al tamaño de los tiles. Se podría usar el tamaño de un tile para ahorrar líneas, pero esto daría como resultado una mala distribución de los tiles, haciendo que sobren o falten píxeles y dejando huecos en los bordes derecho e inferior de la pantalla del juego. En esta imagen los tiles están bien distribuidos llenando por completo la pantalla de juego, también se aprecia que entre tiles existen pequeños espacios negros (color de fondo de la pantalla), esto es por que la distancia entre tiles es flotante (con desimanes) y el tamaño de los tiles es entero, a pesar de eso esta distribución de tiles es mucho mejor que la siguiente. 12
  • Aquí los tiles están perfectamente unidos, pero la distribución es mala, por lo que se puede notar un espacio vacío abajo y a la derecha de la pantalla de juego. Entre más tiles se usen en este caso más grande será el vacío que se observe y más será el desvío de los gráficos lo que provocaría problemas al jugador, como chocar contra paredes invisibles. En esta imagen se puede apreciar la diferencia entre ventana y pantalla de juego. La parte que sigue es bastante sencilla, se utiliza la funcion “multiplicar_lista()” que se hizo anteriormente para escalar las dimensiones de cada tile. # Nada self.h0 = multiplicar_lista(self.ah0,proporcion) # Cielo self.c1 = multiplicar_lista(self.ac1,proporcion) self.c2 = multiplicar_lista(self.ac2,proporcion) ... ... self.t32 = multiplicar_lista(self.at32,proporcion) Tal vez existen formas que permitan nombrar y re-dimensionar tiles de forma más automática, pero de esta manera se tiene un mayor control de los tiles. 13
  • 2.6 Definir función intangibles Esta función es la que gratificará y posicionará los tiles en la pantalla de juego, se nombro intangibles a la función por que grafica únicamente el fondo, por lo que los tiles de “intangible” no interactúan con el protagonista del juego. def intangibles(self): y_contador = 0 for x in self.mapa.mapa: x_contador = 0 for y in x: y = "self." + y y = eval(y) self.superficie.blit(self.imagen,(x_contador*self.db, y_contador*self.db),y) x_contador += 1 y_contador += 1 En este caso ya no se necesita de ningún parámetro externo por que la clase “mapeo()” ya tiene todo lo necesario. Se crean dos variables para que hagan de contadores, uno para recorrer la lista mapa de “mapa0.py” y otro para contar los elementos de cada lista, que serian los tiles. Estos contadores también ayudan a posicionar cada tile. Para automatizar y evitar escribir “self.” en el script “mapa0.py” se suman dos cadenas y luego se evaluan para convertirse en el valor que deben representar: y = "self." + y y = eval(y) Por último se vacían los tiles en la superficie predeterminada en la posición que el “contador_x” y el “contador_y” multiplicados por la proporción “self.db” indiquen. 3.0 Script motor.py: Esté script se utiliza para gestionar la ventana y poner a funcionar los otros dos scripts. # -*- coding: utf-8 -*- import sys, pygame from pygame.locals import* import mapeo, mapa0 pygame.init() #..Constantes..# VENTANA_ALTO = 700 VENTANA_ANCHO = 1200 PANTALLA_ALTO = 700 PANTALLA_ANCHO = 1200 RELOJ = pygame.time.Clock() 14
  • pygame.display.set_caption("H-DQ:B0") VENTANA = pygame.display.set_mode((VENTANA_ANCHO, VENTANA_ALTO),RESIZABLE,32) PANTALLA = pygame.Surface((PANTALLA_ANCHO, PANTALLA_ALTO)) FONDO = mapeo.mapeo(PANTALLA,"Terreno-[..IDG..].png", mapa0) FONDO.escalar(1) PANTALLA_POSX = 0 PANTALLA_POSY = 0 def motor(): llave = True while llave: RELOJ.tick(4) #..Gestion de parametros..# for EVENTO in pygame.event.get(): if EVENTO.type == QUIT: #Cerrar ventana pygame.quit() sys.exit() if EVENTO.type == VIDEORESIZE: # Tamaño de ventana minimo 360x210 PANTALLA_POSX = 0 PANTALLA_POSY = 0 VENTANA_ANCHO,VENTANA_ALTO = EVENTO.dict['size'] if VENTANA_ANCHO < 360: VENTANA_ANCHO = 360 if VENTANA_ALTO < 210: VENTANA_ALTO = 210 pygame.display.set_mode((VENTANA_ANCHO,VENTANA_ALTO),RESIZABLE,32) proporcion_x = int((VENTANA_ALTO/700.0)*1200) proporcion_y = int((VENTANA_ANCHO/1200.0)*700) if proporcion_x > VENTANA_ANCHO: #Ajustrat pantalla a tamaño de ventana PANTALLA_ANCHO = VENTANA_ANCHO PANTALLA_ALTO = proporcion_y FONDO.escalar(VENTANA_ANCHO/1200.0) PANTALLA = pygame.Surface((PANTALLA_ANCHO, PANTALLA_ALTO)) PANTALLA_POSY = (VENTANA_ALTO/2)-(proporcion_y/2) else: PANTALLA_ALTO = VENTANA_ALTO PANTALLA_ANCHO = proporcion_x FONDO.escalar(VENTANA_ALTO/700.0) PANTALLA = pygame.Surface((PANTALLA_ANCHO, PANTALLA_ALTO)) PANTALLA_POSX = (VENTANA_ANCHO/2)-(proporcion_x/2) VENTANA.fill((255,255,255)) PANTALLA.fill((0,0,0)) 15
  • FONDO.superficie = PANTALLA FONDO.intangibles() VENTANA.blit(PANTALLA,(PANTALLA_POSX, PANTALLA_POSY)) pygame.display.update() motor() 3.1 Constantes y variables Después de importar las librerías necesarias incluyendo los scripts de “mapeo.py” y “mapa0.py” se crean algunas constantes y variables para darle los preparamentos de inicio a la ventana, pantalla y los otros scripts. #..Constantes..# VENTANA_ALTO = 700 VENTANA_ANCHO = 1200 PANTALLA_ALTO = 700 PANTALLA_ANCHO = 1200 RELOJ = pygame.time.Clock() pygame.display.set_caption("H-DQ:B0") VENTANA = pygame.display.set_mode((VENTANA_ANCHO, VENTANA_ALTO),RESIZABLE,32) PANTALLA = pygame.Surface((PANTALLA_ANCHO, PANTALLA_ALTO)) FONDO = mapeo.mapeo(PANTALLA,"Terreno-[..IDG..].png", mapa0) FONDO.escalar(1) PANTALLA_POSX = 0 PANTALLA_POSY = 0 Se crea el reloj para definir la velocidad a la que va a correr el videojuego y se crea una ventana con la opción de “RESIZABLE” para poder re-dimensionar y una superficie que será la pantalla del videojuego. Para el fondo se utiliza el script de “mapeo.py” declarando de la siguiente forma: “FONDO = mapeo.mapeo(PANTALLA,"Terreno-[..IDG..].png", mapa0)” Donde la “PANTALLA” es la superficie donde se dibujarán los tils, ,"Terreno- [..IDG..].png" la imagen que se utilizará como tileset y “mapa0” es la forma en que se distribuirán los tils. Se activa por lo menos una vez el método “escalar” de “FONDO” para que se añadan las dimensiones de los tils ya que esto no se declaran al inicio de la función “mapeo”. Por último se declara la posición base de la pantalla de juego con “PANTALLA_POSX = 0”, “PANTALLA_POSY = 0”. 16
  • 3.2 Definir el bucle de juego Para el bucle del juego se define un función “motor()” que contiene la variable “llave = True” para controlar el inicio y fin del bucle y en “RELOJ.tick(4)” se le da un valor para probar y experimentar, para este tutorial bastará con 4. def motor(): llave = True while llave: RELOJ.tick(4) Este es la gestión de eventos normal, para abrir y cerrar el juego. #..Gestion de parametros..# for EVENTO in pygame.event.get(): if EVENTO.type == QUIT: #Cerrar ventana pygame.quit() sys.exit() Para lograr que la pantalla mantenga una escala, se tiene que detectar cuando la ventana sea re-dimensionada if EVENTO.type == VIDEORESIZE: # Tamaño de ventana minimo 360x210 PANTALLA_POSX = 0 PANTALLA_POSY = 0 VENTANA_ANCHO,VENTANA_ALTO = EVENTO.dict['size'] if VENTANA_ANCHO < 360: VENTANA_ANCHO = 360 if VENTANA_ALTO < 210: VENTANA_ALTO = 210 En esta parte se guarda el tamaño actual de la ventana con ”VENTANA_ANCHO, VENTANA_ALTO” y luego se compara con las cantidades 360 y 210 para establecerlas como el tamaño mínimo de la ventana. En esta parte solo se le dice a la ventana que tome el tamaño indicado por ”VENTANA_ANCHO, VENTANA_ALTO” pygame.display.set_mode((VENTANA_ANCHO,VENTANA_ALTO),RESIZABLE,32) 3.3 Re-dimecionara ventana y escalar pantalla Para lograr una correcta proporción de la pantalla de juego es necesario proporcionar su largo con respecto al ancho de la ventana o proporcionar su ancho con respecto del largo de la ventana y luego hacer una comparación para saber cual de los dos tamaños de pantalla se ajusta mejor a la ventana. A continuas algunos ejemplos: 17
  • Ventana inicial. Cuadro negro = ventana Cuadro rojo = pantalla Largo actual de la ventana = LAV =1200 Altura actual de la ventana = AAV =700 Largo base de pantalla = LBP = 1200 Altura base de pantalla = ABP = 700 proporción_x = 1200 proporción_y = 700 La ventana y la pantalla son del mismo tamaño, este es el estado en el que inicia el juego. Si el largo de la pantalla es igual al largo de la ventana entonces: Cuadro negro = ventana Cuadro rojo = pantalla Largo actual de la ventana = LAV =900 Altura actual de la ventana = AAV =600 Largo base de pantalla = LBP = 1200 Altura base de pantalla = ABP = 700 proporción_x = LAV = 900 proporción_y = (LAV/LBP)*ABP = (900/1200)*700= 525 La pantalla se ajusta a la ventana sin pasarse, manteniendo sus proporciones y aprovechando lo mejor posible el espacio de la ventana. 18
  • Si la altura de la pantalla es igual a la altura de la ventana entonces: Cuadro negro = ventana Cuadro rojo = pantalla Largo actual de la ventana = LAV =900 Altura actual de la ventana = AAV =600 Largo base de pantalla = LBP = 1200 Altura base de pantalla = ABP = 700 proporción_x = LAV = (AAV/ABP)*LBP = (600/700)*1200 = 1028.57 redondeado es = 1029 proporción_y = AAV = 600 La pantalla es más larga que la ventana. Si el largo de la pantalla es igual al largo de la ventana entonces: Cuadro negro = ventana Cuadro rojo = pantalla Largo actual de la ventana = LAV =1000 Altura actual de la ventana = AAV =500 Largo base de pantalla = LBP = 1200 Altura base de pantalla = ABP = 700 proporción_x = LAV = 1000 proporción_y = (LAV/LBP)*ABP = (1000/1200)*700 = 583.33 redondeado es = 583 La pantalla es más alta que la ventana. 19
  • Si la altura de la pantalla es igual a la altura de la ventana entonces: Cuadro negro = ventana Cuadro rojo = pantalla Largo actual de la ventana = LAV =1000 Altura actual de la ventana = AAV =500 Largo base de pantalla = LBP = 1200 Altura base de pantalla = ABP = 700 proporción_x = LAV = (AAV/ABP)*LBP = (500/700)*1200 = 857.14 redondeado es = 857 proporción_y = AAV = 500 La pantalla se ajusta a la ventana sin pasarse, manteniendo sus proporciones y aprovechando lo mejor posible el espacio de la ventana. Como se vio en los ejemplos anteriores, solo es aplicar una regla de tres para obtener la proporción_x, y la proporción_y, luego estas proporciones se comparan con la dimensiones de la ventana y se elige la proporción que este dentro de los límites de la ventana. proporcion_x = int((VENTANA_ALTO/700.0)*1200) proporcion_y = int((VENTANA_ANCHO/1200.0)*700) if proporcion_x > VENTANA_ANCHO: #Ajustrat pantalla a tamaño de ventana PANTALLA_ANCHO = VENTANA_ANCHO PANTALLA_ALTO = proporcion_y FONDO.escalar(VENTANA_ANCHO/1200.0) PANTALLA = pygame.Surface((PANTALLA_ANCHO, PANTALLA_ALTO)) PANTALLA_POSY = (VENTANA_ALTO/2)-(proporcion_y/2) else: PANTALLA_ALTO = VENTANA_ALTO PANTALLA_ANCHO = proporcion_x FONDO.escalar(VENTANA_ALTO/700.0) PANTALLA = pygame.Surface((PANTALLA_ANCHO, PANTALLA_ALTO)) PANTALLA_POSX = (VENTANA_ANCHO/2)-(proporcion_x/2) 20
  • Como una adición estética se centra la pantalla de juego, dentro de la ventana, para esto dependiendo del ajuste que se le hizo a la pantalla se centrará a lo ancho o a lo alto de la ventana. Para centrarlo a lo ancho de la ventana, se divide entre dos el ancho de la pantalla y la ventana, luego la diferencia entre ambos dará el resultado de la posición que debe tomar en “x”. En el código se expresa de esta manera: PANTALLA_POSX = (VENTANA_ANCHO/2)-(proporcion_x/2) Para ajustarlo a lo alto se hace exactamente lo mismo pero en vez de considerar las anchuras se consideran las altura quedando el código de este modo: PANTALLA_POSY = (VENTANA_ALTO/2)-(proporcion_y/2) 3.4 Dibujar juego Por último se hacen los llenados (fill) y los vaciados (blit), estos se tiene que hacer en un cierto orden, pues los primeros llenados y vaciados son los que se dibujan hasta el fondo, por lo que los colores de llenadas son los primeros que se hacen. Se llena primero la ventana, luego la pantalla, a “FONDO” se le reasigna la superficie de dibujo (esta asignación se puede hacer dentro de los evento de “VIDEORESIZE” ), luego se dibuja el fondo con “FONDO.intangibles()” y más adelante se vacía en la ventana la pantalla de juego de esta manera “VENTANA.blit(PANTALLA,(PANTALLA_POSX, PANTALLA_POSY))”, por último se actualizan la ventana con “ pygame.display.update()”. VENTANA.fill((255,255,255)) PANTALLA.fill((0,0,0)) FONDO.superficie = PANTALLA FONDO.intangibles() VENTANA.blit(PANTALLA,(PANTALLA_POSX, PANTALLA_POSY)) pygame.display.update() motor() Ya que el bucle del juego fue declarada como una función este se debe de llamara con “motor()” que sería el nombre de la función. 21
  • Resultados 22
  • 23