Página 1 de 1

¿Como aplicar el Delta Time para movimientos suaves?

Publicado: 01 Jun 2016, 21:21
por Spectro
Hola de nuevo!

Estoy usando el modulo Pygame de Python (como comente en post anteriores) y ahora me surge otro problemilla. Tambien me ocurria cuando usaba el engine Game maker. Es decir, aunque ajusto el tema de velocidad del sprite (numero de pixels que se desplaza en cada fotograma) siempre se ve dicho sprite con parpadeo o a tirones. Tambien ajusto a 30 o 60 fps. Pero ni con esas.

De momento es una imagen sin animacion. Tambien, en el mismo codigo, creo una surface que se mueve de izquierda a derecha. Preguntando al Sr. Google me indico el tema del Delta Time. Osea, que el espacio de tiempo que hay entre cada fotograma siempre sea identico. Probe algun codigo que mostraban de ejemplo. Pero no me dio resultado.

En todo caso la formula que suelen decir es esta (cabe decir que convenientemente implementada dentro del codigo):

Código: Seleccionar todo

reloj = pygame.time.Clock()
while True:
   
    deltatime = clock.tick(60)   
    velocidad = 1 / float(deltatime)

   
    px *= mx * velocidad
    py *= my * velocidad


Este es el codigo que he creado para testeos. El personaje se mueve con las teclas del cursor. Dicho personaje es una imagen ubicado en la misma carpeta de nuestro script. En mi caso el archivo se llama spr_0.png. Pero marea solo como se desplaza. Da igual que vaya a poca o mucha velocidad. Pega tirones y parpadeos. Osea, como algunos sprites de Spectrum.

Mi codigo de Python/Pygame:

Código: Seleccionar todo

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


os.environ['SDL_VIDEO_CENTERED'] = '1'

pygame.init()

largo, ancho = 640, 480
pygame.display.set_caption('Colision basica')
pantalla = pygame.display.set_mode((largo, ancho))

# Creacion de objetos ---------------
bloque = pygame.Surface((50, 50))
bloque.fill((0,0,0))
rectangulo_bloque = bloque.get_rect()
rectangulo_bloque.left = 50
rectangulo_bloque.top = 50
# -----------------------------------

# Creacion de clases ---------------------
class Seres(pygame.sprite.Sprite):
   
    def __init__(self, imagen):
        self.image = pygame.image.load(imagen)
        self.rect = self.image.get_rect()
        self.rect.left = 50
        self.rect.top = 200
        self.velocidad = 10
       
    def mover(self, direc):
        if direc == 'left':
            self.rect.left -= self.velocidad
        elif direc == 'right':
            self.rect.left += self.velocidad
        elif direc == 'up':
            self.rect.top -= self.velocidad
        elif direc == 'down':
            self.rect.top += self.velocidad
           
    def __str__(self):
        return(str(self.velocidad))
   
# -----------------------------------------

heroe = Seres('spr_0.png')
def main():
   
    reloj = pygame.time.Clock()
         
    # velocidad del bloque 
    vel_x = 16
    vel_y = 16     
   
    salir = False
    while not salir:         
       
        for evento in pygame.event.get():
            if evento.type == pygame.QUIT:
                salir = True
               
        tecla = pygame.key.get_pressed()
        if tecla[K_LEFT] and not tecla[K_RIGHT]:
            heroe.mover('left')                         
        elif tecla[K_RIGHT] and not tecla[K_LEFT]:
            heroe.mover('right')           
        elif tecla[K_UP] and not tecla[K_DOWN]:
            heroe.mover('up')           
        elif tecla[K_DOWN] and not tecla[K_UP]:
            heroe.mover('down')                                                                 
                                             
        # Evita que el personaje salga de la pantalla       
        if heroe.rect.right > largo:
            heroe.rect.right = largo
        elif heroe.rect.left < 0:
            heroe.rect.left = 0
        elif heroe.rect.top < 0:
            heroe.rect.top = 0
        elif heroe.rect.bottom > ancho:
            heroe.rect.bottom = ancho
       
        # Movimiento del objeto bloque
        rectangulo_bloque.left += vel_x
        if rectangulo_bloque.left < 0 or rectangulo_bloque.right > largo:
            vel_x = -vel_x       
           
       
        # Dibujado de pantalla y actualizacion
        pantalla.fill((255, 255, 255))
        pantalla.blit(bloque, rectangulo_bloque)
        pantalla.blit(heroe.image, heroe.rect)
        pygame.display.update()
        reloj.tick(30)       
                       

# Run
main()

# Salir
pygame.quit()
sys.exit

Re: ¿Como aplicar el Delta Time para movimientos suaves?

Publicado: 01 Jun 2016, 22:24
por robcfg
Buenas!

El delta time es el tiempo que transcurre entre un fotograma del juego y el siguiente.

Se usa a grosso modo para actualizar las entidades del juego de forma coherente cuando la velocidad de refresco no es constante.

Así, si en un segundo un muñeco se mueve 10 pixeles y te llega un delta time de 3.2 segundos, el muñeco lo tienes que desplazar 10*3.2 = 32 pixels.

Respecto a tu problema, no se si la librería te pasa un delta time por algún lado, si te avisa de cuando puedes actualizar y pintar tu juego o si cuando vuelcas a pantalla, lo hace sincronizando con el refresco de pantalla.

El caso es que no se está sincronizando el pintado del juego con el de la pantalla y por eso se producen los efectos que describes.

Re: ¿Como aplicar el Delta Time para movimientos suaves?

Publicado: 02 Jun 2016, 20:01
por Spectro
Gracias por la explicacion, robcfg. De todas formas debo seguir investigando. De momento no se implementarlo bien. Y eso que he visto algunos codigos por la red. Pero el personaje va a trompicones y no tiene ese movimiento suave y sin parpadeos. Pero claro, pues ser de muchos factores mas. Por ejemplo, del codigo dentro del bucle while. Seguire mirando a ver...

Saludos!

Re: ¿Como aplicar el Delta Time para movimientos suaves?

Publicado: 02 Jun 2016, 20:33
por robcfg
Podría ser que estuvieras haciendo todos los cálculos con números enteros y que eso te redondee los valores a 0 o un valor más grande en vez de calcular un valor intermedio.

Re: ¿Como aplicar el Delta Time para movimientos suaves?

Publicado: 02 Jun 2016, 21:37
por mentalthink

Re: ¿Como aplicar el Delta Time para movimientos suaves?

Publicado: 03 Jun 2016, 20:32
por Spectro
mentalthink escribió:Creo que esto te podrá ayudar.
http://stackoverflow.com/questions/9276 ... ame-python


Precisamente fue una de las paginas que visite. Pero bueno, haciendo pruebas y tal, no lo solucione. De momento lo dejare un poco aparcado para ir avanzando en otros temas. Gracias...