Ver Mensaje Individual
  #1 (permalink)  
Antiguo 14/06/2016, 12:56
Koan
 
Fecha de Ingreso: diciembre-2009
Ubicación: Spain
Mensajes: 180
Antigüedad: 14 años, 3 meses
Puntos: 9
Problema con la gravedad en Pygame

Hola de nuevo!

Bueno, el titulo lo dice todo. Despues de probar algunas cosas con el modulo Pygame, me he atascado con la gravedad. Esta claro que es algo tan sencillo como manejar la coordenada Y. De esa forma nuestro personaje desciende si no colisiona con un objeto definido.

Dos problemas me han surgido:

1. Que se queda pegado al objeto que colisiona y no obedece a la ordenes del teclado.

2. Si aumentamos la gravedad, nuestro personaje se detiene al colisionar. Pero deja unos pixeles de distancia el objeto que colisiona.

Este es el codigo que seguro tendra errores:

Código Python:
Ver original
  1. import pygame
  2. from pygame.locals import *
  3. import sys
  4. import os
  5.  
  6. os.environ['SDL_VIDEO_CENTERED'] = '1'
  7. pygame.init()
  8.  
  9. ANCHO = 1024
  10. ALTO = 768
  11.  
  12. # pygame.NOFRAME sin margenes
  13. ventana = pygame.display.set_mode((ANCHO, ALTO))
  14.  
  15. NEGRO = (0, 0, 0)
  16. AZUL = (0, 0, 255)
  17. VERDE = (0, 192, 0)
  18.  
  19. # Clases -----------------------------------------------------------------------
  20. class Pared(pygame.sprite.Sprite):
  21.     def __init__(self, x, y, largo, alto, color):
  22.         pygame.sprite.Sprite.__init__(self)
  23.         self.image = pygame.Surface((largo, alto))
  24.         self.image.fill(color)
  25.         self.rect = self.image.get_rect()
  26.         self.rect.centerx = ANCHO/2
  27.         self.rect.centery = ALTO/2
  28.         self.velocidad = 0  
  29.     def update(self):
  30.         ventana.blit(self.image, self.rect)
  31.  
  32. class Personaje(pygame.sprite.Sprite):
  33.     def __init__(self, x, y):
  34.         pygame.sprite.Sprite.__init__(self)
  35.         self.image = pygame.Surface((64, 64))
  36.         self.image.fill(VERDE)
  37.         self.rect = self.image.get_rect()
  38.         self.rect.x = x
  39.         self.rect.y = y
  40.        
  41.     def __str__(self):
  42.         return ('Coordenada X: ' + str(self.rect.x) + ' Coordenada Y: ' + str(self.rect.y))
  43.        
  44.     def mover(self, x,y):
  45.         self.rect.move_ip(x, y)
  46.        
  47.     def colision(self, other):
  48.         return self.rect.colliderect(other)
  49.    
  50.     def update(self):
  51.         ventana.blit(self.image, self.rect)
  52.        
  53. class Enemigos(pygame.sprite.Sprite):
  54.     pass
  55. # ------------------------------------------------------------------------------
  56.        
  57. muro = Pared(0, 0, 800, 32, AZUL)
  58. heroe = Personaje(100, 100)
  59.  
  60.  
  61.  
  62. def run():
  63.     fps = pygame.time.Clock()
  64.     salir = False
  65.     heroe.velocidad = 4
  66.     gravedad = 8
  67.     while not salir:
  68.         for evento in pygame.event.get():
  69.             # con raton: pygame.MOUSEBUTTONDOWN
  70.             if evento.type == pygame.QUIT:
  71.                 salir = True
  72.                
  73.          # Movimiento del personaje          
  74.         oldx = heroe.rect.x
  75.         oldy = heroe.rect.y
  76.         tecla = pygame.key.get_pressed()
  77.        
  78.         if tecla[K_LEFT] and not tecla[K_RIGHT]:                        
  79.             heroe.mover(-heroe.velocidad, 0)          
  80.                                                                    
  81.         elif tecla[K_RIGHT] and not tecla[K_LEFT]:
  82.             heroe.mover(heroe.velocidad, 0)          
  83.         elif tecla[K_UP] and not tecla[K_DOWN]:
  84.             heroe.mover(0, -heroe.velocidad)        
  85.         elif tecla[K_DOWN] and not tecla[K_UP]:
  86.             heroe.mover(0, heroe.velocidad)
  87.            
  88.         # Muestra las coordenadas del personaje por consola
  89.         print(heroe)
  90.        
  91.         # Gravedad
  92.         if not heroe.colision(muro):
  93.             heroe.mover(0, gravedad)
  94.        
  95.         # Colision con el muro
  96.         if heroe.colision(muro):
  97.             heroe.rect.x = oldx
  98.             heroe.rect.y = oldy
  99.        
  100.         # Evita que salga por los extremos de la ventana
  101.         if heroe.rect.left < 0:
  102.             heroe.rect.left = 0
  103.         elif heroe.rect.right > ANCHO:
  104.             heroe.rect.right = ANCHO
  105.         elif heroe.rect.top < 0:
  106.             heroe.rect.top = 0
  107.         elif heroe.rect.bottom > ALTO:
  108.             heroe.rect.bottom = ALTO
  109.            
  110.            
  111.        
  112.         # Actulizacion y dibujo de pantalla
  113.         ventana.fill(NEGRO)
  114.         muro.update()
  115.         heroe.update()
  116.         pygame.display.flip()
  117.         fps.tick(30)
  118. run()
  119. pygame.quit()
  120. sys.exit()

Seguro que debe ser algo tan sencillo como poner algun ELSE en alguna parte del script. Pero no me funcionan.

Si en la variable gravedad ponemos 12, si que se queda bien asentado en el objeto muro. Si ponemos 8, no.