Ver Mensaje Individual
  #2 (permalink)  
Antiguo 14/06/2016, 22:58
Avatar de razpeitia
razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 8 meses
Puntos: 1360
Respuesta: Problema con la gravedad en Pygame

Pues no era tan fácil como ponerle un else.

Algunas cosas:
1. Maneja velocidades por separado
2. Maneja contadores de tiempo o de fps
3. Maneja estados

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.         self.velocidad_x = 0
  41.         self.velocidad_y = 0
  42.         self.state_y = 'falling'
  43.         self.jump_timer = 0
  44.         self.falling_timer = 0
  45.  
  46.     def __str__(self):
  47.         return ('Coordenada X: ' + str(self.rect.x) + ' Coordenada Y: ' + str(self.rect.y))
  48.  
  49.     def mover_x(self):
  50.         self.rect.move_ip(self.velocidad_x, 0)
  51.  
  52.     def mover_y(self):
  53.         self.rect.move_ip(0, self.velocidad_y)
  54.  
  55.     def mover(self):
  56.         self.rect.move_ip(self.velocidad_x, self.velocidad_y)
  57.  
  58.     def colision(self, other):
  59.         return self.rect.colliderect(other)
  60.  
  61.     def update(self):
  62.         ventana.blit(self.image, self.rect)
  63.  
  64. class Enemigos(pygame.sprite.Sprite):
  65.     pass
  66. # ------------------------------------------------------------------------------
  67.  
  68. muro = Pared(0, 0, 800, 32, AZUL)
  69. heroe = Personaje(100, 100)
  70.  
  71.  
  72.  
  73. def run():
  74.     fps = pygame.time.Clock()
  75.     salir = False
  76.     heroe.velocidad_y = 4
  77.     heroe.velocidad_x = 0
  78.     gravedad = 8
  79.     myfont = pygame.font.SysFont("monospace", 15)
  80.  
  81.     while not salir:
  82.         for evento in pygame.event.get():
  83.             # con raton: pygame.MOUSEBUTTONDOWN
  84.             if evento.type == pygame.QUIT:
  85.                 salir = True
  86.  
  87.          # Movimiento del personaje
  88.         tecla = pygame.key.get_pressed()
  89.  
  90.         if tecla[K_q]:
  91.             break
  92.  
  93.         if tecla[K_LEFT] and not tecla[K_RIGHT]:
  94.             heroe.velocidad_x = -4
  95.         elif tecla[K_RIGHT] and not tecla[K_LEFT]:
  96.             heroe.velocidad_x = 4
  97.         else:
  98.             heroe.velocidad_x = 0
  99.         heroe.mover_x()
  100.         if heroe.colision(muro):
  101.             if heroe.velocidad_x > 0:
  102.                 heroe.rect.right = muro.rect.left
  103.             if heroe.velocidad_x < 0:
  104.                 heroe.rect.left = muro.rect.right
  105.  
  106.         # Estado a velocidad
  107.         if heroe.state_y == 'falling':
  108.             heroe.velocidad_y = heroe.falling_timer * gravedad
  109.             heroe.falling_timer += 0.15
  110.         elif heroe.state_y == 'jumping':
  111.             heroe.velocidad_y = (heroe.jump_timer / 15.0) * -gravedad
  112.             heroe.jump_timer -= 1
  113.         elif heroe.state_y == 'standing':
  114.             heroe.velocidad_y = 0
  115.             heroe.jump_timer = 30
  116.             heroe.falling_timer = 0
  117.  
  118.         if tecla[K_UP]:
  119.             if heroe.state_y == 'standing':
  120.                 heroe.state_y = 'jumping'
  121.         else:
  122.             if heroe.state_y == 'jumping':
  123.                 heroe.state_y = 'falling'
  124.         if heroe.jump_timer <= 0:
  125.             heroe.state_y = 'falling'
  126.  
  127.         heroe.mover_y()
  128.         if heroe.colision(muro):
  129.             if heroe.state_y == 'falling':
  130.                 heroe.rect.bottom = muro.rect.top
  131.                 heroe.state_y = 'standing'
  132.             elif heroe.state_y == 'jumping':
  133.                 heroe.rect.top = muro.rect.bottom
  134.         if heroe.state_y == 'standing':
  135.             heroe.velocidad_y = 1
  136.             heroe.mover_y()
  137.             ground = heroe.rect.bottom > ALTO
  138.             wall_colision = heroe.colision(muro)
  139.             heroe.velocidad_y = -1
  140.             heroe.mover_y()
  141.             heroe.velocidad_y = 0
  142.  
  143.             if not wall_colision and not ground:
  144.                 heroe.state_y = 'falling'
  145.  
  146.         # Evita que salga por los extremos de la ventana
  147.         if heroe.rect.left < 0:
  148.             heroe.rect.left = 0
  149.         elif heroe.rect.right > ANCHO:
  150.             heroe.rect.right = ANCHO
  151.         if heroe.rect.top < 0:
  152.             heroe.rect.top = 0
  153.         elif heroe.rect.bottom > ALTO:
  154.             heroe.rect.bottom = ALTO
  155.             heroe.state_y = 'standing'
  156.  
  157.         # Actulizacion y dibujo de pantalla
  158.         ventana.fill(NEGRO)
  159.         muro.update()
  160.         heroe.update()
  161.         # render text
  162.         if heroe.state_y == 'jumping':
  163.             label = myfont.render("%s %.03f" % (heroe.state_y, heroe.jump_timer), 1, (0,255,0))
  164.         elif heroe.state_y == 'falling':
  165.             label = myfont.render("%s %.03f" % (heroe.state_y, heroe.falling_timer), 1, (0,255,0))
  166.         else:
  167.             label = myfont.render("%s" % (heroe.state_y,), 1, (0,255,0))
  168.         ventana.blit(label, (800, 100))
  169.         pygame.display.flip()
  170.         fps.tick(30)
  171. run()
  172. pygame.quit()
  173. sys.exit()