¿Como aplicar el Delta Time para movimientos suaves?

Foro dedicado a la programación en todo tipo de sistemas clásicos.
Spectro
Spectrum 48K Plus
Spectrum 48K Plus
Mensajes: 46
Registrado: 11 May 2015, 11:49
Sistema Favorito: PC
primer_sistema: Spectrum +2
consola_favorita: Sony PSP
Primera consola: (Otro)
Gracias dadas: 2 veces
Gracias recibidas: 2 veces

¿Como aplicar el Delta Time para movimientos suaves?

Mensajepor Spectro » 01 Jun 2016, 21:21

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

Avatar de Usuario
robcfg
Amiga 1200
Amiga 1200
Mensajes: 2008
Registrado: 07 May 2009, 15:34
Sistema Favorito: Amstrad CPC
primer_sistema: Atari 800XL/600XL
Ubicación: Estocolmo
Gracias dadas: 398 veces
Gracias recibidas: 102 veces

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

Mensajepor robcfg » 01 Jun 2016, 22:24

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.

Spectro
Spectrum 48K Plus
Spectrum 48K Plus
Mensajes: 46
Registrado: 11 May 2015, 11:49
Sistema Favorito: PC
primer_sistema: Spectrum +2
consola_favorita: Sony PSP
Primera consola: (Otro)
Gracias dadas: 2 veces
Gracias recibidas: 2 veces

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

Mensajepor Spectro » 02 Jun 2016, 20:01

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!

Avatar de Usuario
robcfg
Amiga 1200
Amiga 1200
Mensajes: 2008
Registrado: 07 May 2009, 15:34
Sistema Favorito: Amstrad CPC
primer_sistema: Atari 800XL/600XL
Ubicación: Estocolmo
Gracias dadas: 398 veces
Gracias recibidas: 102 veces

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

Mensajepor robcfg » 02 Jun 2016, 20:33

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.

Avatar de Usuario
mentalthink
Amiga 2500
Amiga 2500
Mensajes: 2840
Registrado: 11 Abr 2010, 15:06
Gracias dadas: 45 veces
Gracias recibidas: 14 veces

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

Mensajepor mentalthink » 02 Jun 2016, 21:37


Spectro
Spectrum 48K Plus
Spectrum 48K Plus
Mensajes: 46
Registrado: 11 May 2015, 11:49
Sistema Favorito: PC
primer_sistema: Spectrum +2
consola_favorita: Sony PSP
Primera consola: (Otro)
Gracias dadas: 2 veces
Gracias recibidas: 2 veces

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

Mensajepor Spectro » 03 Jun 2016, 20:32

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...


Volver a “Programación”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados