Windspar

Pygame Simple Jump Game Example

Jan 21st, 2021 (edited)
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.41 KB | None | 0 0
  1. import pygame
  2. import random
  3. from pygame.sprite import Group, Sprite
  4.  
  5. spritecollide = pygame.sprite.spritecollide
  6.  
  7. class DisplayEngine:
  8.     def __init__(self, caption, width, height, flags=0):
  9.         pygame.display.set_caption(caption)
  10.         self.surface = pygame.display.set_mode((width, height), flags)
  11.         self.rect = self.surface.get_rect()
  12.         self.clock = pygame.time.Clock()
  13.         self.running = False
  14.         self.delta = 0
  15.         self.fps = 60
  16.  
  17.     def main_loop(self, game):
  18.         self.running = True
  19.         while self.running:
  20.             for event in pygame.event.get():
  21.                 if event.type == pygame.QUIT:
  22.                     self.running = False
  23.                 else:
  24.                     game.event(event)
  25.  
  26.             game.draw(self.surface)
  27.             game.update(self.delta)
  28.             pygame.display.flip()
  29.             self.delta = self.clock.tick(self.fps)
  30.  
  31. class Player(Sprite):
  32.     def __init__(self, position):
  33.         Sprite.__init__(self)
  34.         self.image = pygame.Surface((30, 30))
  35.         self.rect = self.image.get_rect(midbottom=position)
  36.         self.position = pygame.Vector2(self.rect.center)
  37.         self.image.fill(pygame.Color("gold"))
  38.  
  39.     def clamp(self, rect):
  40.         clamp = self.rect.clamp(rect)
  41.         if self.rect.x != clamp.x:
  42.             self.position.x = clamp.centerx
  43.  
  44.         if self.rect.y != clamp.y:
  45.             self.position.y = clamp.centery
  46.  
  47.         self.rect = clamp
  48.  
  49.     def move(self, x, y):
  50.         self.position.x += x
  51.         self.position.y += y
  52.         self.rect.center = tuple(map(int, self.position))
  53.  
  54.     def move_clamp(self, x, y, rect):
  55.         self.move(x, y)
  56.         self.clamp(rect)
  57.  
  58.     def offset(self, top, bottom):
  59.         diff = 0
  60.         if self.position.y < top:
  61.             diff = top - self.position.y
  62.             self.position.y = top
  63.  
  64.         elif self.position.y > bottom:
  65.             diff = bottom - self.position.y
  66.             self.position.y = bottom
  67.  
  68.         self.rect.center = tuple(map(int, self.position))
  69.         return diff
  70.  
  71. class Platform(Sprite):
  72.     def __init__(self, image, position, groups):
  73.         Sprite.__init__(self, groups)
  74.         self.image = image
  75.         self.rect = self.image.get_rect(topleft=position)
  76.         self.y = self.rect.y
  77.  
  78.     def update(self, map_position):
  79.         self.rect.y = self.y + map_position
  80.  
  81. class PlatformData:
  82.     def __init__(self, count, sprites, game_width, game_height):
  83.         self.images = []
  84.         self.sprites = sprites
  85.         self.group = Group()
  86.  
  87.         self.height = 10
  88.         self.count = count
  89.         self.next_level = game_height - 50
  90.         self.color = pygame.Color("lawngreen")
  91.         self.widths = tuple(range(50, 120, 10))
  92.         self.game_width = game_width
  93.  
  94.         image = pygame.Surface((game_width, self.height))
  95.         image.fill(pygame.Color('firebrick'))
  96.         position = (0, game_height - self.height)
  97.         self.bottom_platform = Platform(image, position, (sprites, self.group))
  98.  
  99.         self.create_images()
  100.         self.create()
  101.  
  102.     def create_images(self):
  103.         for width in self.widths:
  104.             surface = pygame.Surface((width, self.height))
  105.             surface.fill(self.color)
  106.             self.images.append(surface)
  107.  
  108.     def create(self):
  109.         for c in range(self.count):
  110.             image = random.choice(self.images)
  111.             width = image.get_width()
  112.             x = random.randint(0, self.game_width - width)
  113.             y = random.randint(60, 120)
  114.             self.next_level -= y
  115.             position = x, self.next_level
  116.             Platform(image, position, (self.group, self.sprites))
  117.  
  118. class PlayerMovement:
  119.     climbing_state = 1
  120.     jumping_state = 2
  121.     landed_state = 3
  122.     falling_state = 4
  123.  
  124.     def __init__(self, game):
  125.         self.game = game
  126.         self.acc = 0.08
  127.         self.velocity = 0
  128.         self.max_jump = 120
  129.         self.jump_count = 0
  130.         self.velocity_start = 0.2
  131.         self.state = PlayerMovement.landed_state
  132.  
  133.         self.last_platform = game.platforms.bottom_platform
  134.  
  135.     def collision(self):
  136.         collision = spritecollide(self.game.player, self.game.platforms.group, False)
  137.  
  138.         value = len(collision)
  139.         if value > 0:
  140.             self.last_platform = collision[0]
  141.  
  142.         return value
  143.  
  144.     def fall(self):
  145.         if self.state not in (PlayerMovement.jumping_state, PlayerMovement.falling_state):
  146.             rect = self.game.player.rect.copy()
  147.             rect.y += 1
  148.  
  149.             if not rect.colliderect(self.last_platform.rect):
  150.                 self.state = PlayerMovement.falling_state
  151.                 self.velocity = self.velocity_start
  152.  
  153.     def is_climbing(self, delta):
  154.         y = self.velocity_start * delta
  155.         self.game.player.move(0, -y)
  156.  
  157.         if self.collision() == 0:
  158.             self.game.player.rect.bottom = self.last_platform.rect.top
  159.             self.game.player.position.y = self.game.player.rect.centery
  160.             self.state = PlayerMovement.landed_state
  161.  
  162.     def is_jumping(self, keys, delta):
  163.         if self.jump_count < self.max_jump:
  164.             if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]:
  165.                 y = self.velocity * delta
  166.                 self.game.player.move(0, -y)
  167.                 self.jump_count += y
  168.             else:
  169.                 self.state = PlayerMovement.falling_state
  170.                 self.jump_count = 0
  171.         else:
  172.             self.state = PlayerMovement.falling_state
  173.             self.jump_count = 0
  174.  
  175.     def is_falling(self, delta):
  176.         if self.collision() > 0:
  177.             self.state = PlayerMovement.climbing_state
  178.         else:
  179.             y = self.velocity * delta
  180.             self.game.player.move(0, y)
  181.  
  182.     def can_jump(self, keys, delta):
  183.         if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]:
  184.             self.state = PlayerMovement.jumping_state
  185.             self.velocity = self.velocity_start
  186.  
  187.     def allowed(self, keys, delta):
  188.         if keys[pygame.K_LEFT] or keys[pygame.K_a]:
  189.             x = -self.acc * delta
  190.             self.game.player.move_clamp(x, 0, self.game.engine.rect)
  191.             self.fall()
  192.  
  193.         if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
  194.             x = self.acc * delta
  195.             self.game.player.move_clamp(x, 0, self.game.engine.rect)
  196.             self.fall()
  197.  
  198.     def update(self, keys, delta):
  199.         if self.state == PlayerMovement.climbing_state:
  200.             self.is_climbing(delta)
  201.  
  202.         elif self.state == PlayerMovement.jumping_state:
  203.             self.is_jumping(keys, delta)
  204.  
  205.         elif self.state == PlayerMovement.falling_state:
  206.             self.is_falling(delta)
  207.  
  208.         elif self.state == PlayerMovement.landed_state:
  209.             self.can_jump(keys, delta)
  210.  
  211.         self.allowed(keys, delta)
  212.  
  213. class JumpGame:
  214.     def __init__(self, engine):
  215.         self.engine = engine
  216.         self.map_position = 0
  217.         self.sprites = Group()
  218.         self.background_color = pygame.Color("dodgerblue")
  219.         self.platforms = PlatformData(1000, self.sprites, *self.engine.rect.size)
  220.         self.max_height = self.engine.rect.height - self.platforms.height
  221.         self.bottom = int(engine.rect.height * 0.7)
  222.         self.top = int(engine.rect.height * 0.3)
  223.  
  224.         position = engine.rect.centerx, engine.rect.bottom - self.platforms.height
  225.         self.player = Player(position)
  226.         self.sprites.add(self.player)
  227.         self.movement = PlayerMovement(self)
  228.  
  229.     def draw(self, surface):
  230.         surface.fill(self.background_color)
  231.         self.sprites.draw(surface)
  232.  
  233.     def event(self, event):
  234.         pass
  235.  
  236.     def fall(self):
  237.         if self.player.landed:
  238.             collision = spritecollide(self.player, self.platforms.group, False)
  239.  
  240.             if len(collision) == 0:
  241.                 self.player.landed = False
  242.                 self.player.velocity = self.velocity
  243.  
  244.     def update(self, delta):
  245.         self.platforms.group.update(self.map_position)
  246.         keys = pygame.key.get_pressed()
  247.         self.movement.update(keys, delta)
  248.         self.map_position += self.player.offset(self.top, self.bottom)
  249.  
  250.         #if self.map_position > self.max_height:
  251.             #self.map_position = self.max_height
  252.  
  253.  
  254. def main():
  255.     random.seed(10) # same map every game.
  256.     pygame.init()
  257.     engine = DisplayEngine("Jump Game", 250, 600)
  258.     game = JumpGame(engine)
  259.     engine.main_loop(game)
  260.  
  261. main()
  262.  
Add Comment
Please, Sign In to add comment