una tratamiento recorrer procesamiento para manipular librerias imagenes imagen filtros descomponer crear convertir con como binario python pygame game-engine

tratamiento - librerias para procesamiento de imagenes en python



¿Cómo escalas una resolución de diseño a otras resoluciones con Pygame? (2)

La mejor manera de hacerlo es bajando imágenes, a fin de preservar la calidad de la imagen. Aquí hay dos opciones:

Opción 1

Este método es probablemente el más rápido.

  1. Crea imágenes para que sean compatibles con la resolución más grande que pretendas admitir.
  2. Crea una pantalla con el tamaño deseado del usuario.

    screen = pygame.display.set_mode((user_x, user_y))

  3. Imágenes a escala reducida en el momento de la carga

    image = pygame.image.load("a.png").convert_alpha() pygame.transform.scale(image, (screen.width() / your_max_width, screen.height() / your_max_height), DestSurface=image)

  4. Ahora, blit ellos normalmente. Debería funcionar a velocidades normales.

opcion 2

  1. Crea una pantalla con el tamaño deseado del usuario.

    screen = pygame.display.set_mode((user_x, user_y))

  2. A continuación, crea un pygame. Superficie con la resolución más alta que intentas respaldar.

    surface = pygame.Surface((1920, 1080))

  3. Luego, haz que todo quede en esa superficie.

    surface.blit(image, rect) # Etc...

  4. Después de que se completen todos los blits, reduzca la escala de la superficie (según sea necesario) a la resolución que desee el usuario. Preferiblemente, solo permitiría resoluciones con la misma relación de aspecto.

    pygame.transform.scale(surface, ((screen.width() / your_max_width, screen.height() / your_max_height), DestSurface=surface)

  5. Finalmente, recorte la superficie de la pantalla y muéstrela.

    screen.blit(surface, (0, 0)) pygame.display.update()

Este proceso (downscaling) le permite preservar la calidad de la imagen mientras le permite al usuario elegir su resolución de pantalla. Será más lento porque estás manipulando imágenes constantemente.

Entonces, en cada ejemplo de Pygame que he visto, parece haber una resolución para que el juego se juegue y eso es todo. No hay opciones para configurar resoluciones más altas o más bajas. Si cambias la resolución a través de display.set_mode, entonces la escala de las texturas / gráficos del juego desaparece y el juego se vuelve injugable.

En todos los ejemplos que he visto, parece que tendrías que crear conjuntos de texturas de diferentes tamaños para cada resolución objetivo ... Lo cual parece ridículo. Eso me lleva a mi pregunta.

Si diseño un juego basado en una resolución estándar de 480x270, ¿es posible escalar la salida de esa superficie a 1080p (o 1440p, 4k, etc.) al mismo tiempo que utilizo los activos del juego creados para 480x270? Si es así, ¿alguien puede publicar un ejemplo de cómo se puede lograr esto? Cualquier consejo o puntero también sería apreciado.


Pasó un tiempo retocando y armando una demo mostrando cómo abordar este problema. Búscate una imagen para probar y coloca la ruta de la cadena a esa imagen en el script para obtener el valor de imagePath.

La funcionalidad de este script es simple. Cuando presiona hacia la izquierda o hacia la derecha en las teclas de flecha, la resolución de la pantalla recorre una tupla de resoluciones aceptables y la pantalla cambia de tamaño según corresponda mientras escala su imagen de prueba a la nueva resolución.

import pygame,sys from pygame import * from pygame.locals import * displayIndex = 0 pygame.init() ##standard 16:9 display ratios DISPLAYS = [(1024,576),(1152,648),(1280,720),(1600,900),(1920,1080),(2560,1440)] screen = pygame.display.set_mode(DISPLAYS[displayIndex]) screen.fill((0,0,0)) ### change image path to a string that names an image you''d like to load for testing. I just used a smiley face from google image search. ### Put it in the same place as this file or set up your paths appropriately imagePath = "Smiley-icon.png" class Icon(pygame.sprite.Sprite): def __init__(self,x,y): pygame.sprite.Sprite.__init__(self) self.smileyImage = pygame.image.load(imagePath) self.image = self.smileyImage.convert_alpha() ### need to assume a default scale, DISPLAYS[0] will be default for us self.rect = self.image.get_rect() self.posX = x self.posY = y self.rect.x = x self.rect.y = y self.defaultx = (float(self.rect[2])/DISPLAYS[0][0])*100 self.defaulty = (float(self.rect[3])/DISPLAYS[0][1])*100 ## this is the percent of the screen that the image should take up in the x and y planes def updateSize(self,): self.image = ImageRescaler(self.smileyImage,(self.defaultx,self.defaulty)) self.rect = self.image.get_rect() self.rect.x = self.posX self.rect.y = self.posY def ImageRescaler(image,originalScaleTuple): #be sure to restrict to only proper ratios newImage = pygame.transform.scale(image,(int(DISPLAYS[displayIndex][0]*(originalScaleTuple[0]/100)), int(DISPLAYS[displayIndex][1]*(originalScaleTuple[1]/100)))) return newImage def resizeDisplay(): screen = pygame.display.set_mode(DISPLAYS[displayIndex]) ## this is where you''d have''d probably want your sprite groups set to resize themselves ## Just gonna call it on icon here icon.updateSize() icon = Icon(100,100) while True: screen.fill((0,0,0)) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == KEYDOWN: if event.key == K_LEFT: displayIndex -=1 if displayIndex < 0: displayIndex = 5 resizeDisplay() elif event.key == K_RIGHT: displayIndex+=1 if displayIndex > 5: displayIndex = 0 resizeDisplay() screen.blit(icon.image,(icon.rect.x,icon.rect.y)) pygame.display.update()