Facebook
From Diminutive Owl, 3 Years ago, written in Python.
Embed
Download Paste or View Raw
Hits: 70
  1. import pygame
  2.  
  3. # Global constants
  4.  
  5. # Colors
  6. BLACK = (0, 0, 0)
  7. WHITE = (255, 255, 255)
  8. GREEN = (0, 255, 0)
  9. RED = (255, 0, 0)
  10. BLUE = (0, 0, 255)
  11.  
  12. # Screen dimensions
  13. SCREEN_WIDTH = 800
  14. SCREEN_HEIGHT = 600
  15.  
  16.  
  17. class Player(pygame.sprite.Sprite):
  18.     """
  19.    This class represents the bar at the bottom that the player controls.
  20.    """
  21.  
  22.     # -- Methods
  23.     def __init__(self):
  24.         """ Constructor function """
  25.  
  26.         # Call the parent's constructor
  27.         super().__init__()
  28.  
  29.         # Create an image of the block, and fill it with a color.
  30.         # This could also be an image loaded from the disk.
  31.         width = 40
  32.         height = 60
  33.         self.image = pygame.Surface([width, height])
  34.         self.image.fill(RED)
  35.  
  36.         # Set a reference to the image rect.
  37.         self.rect = self.image.get_rect()
  38.  
  39.         # Set speed vector of player
  40.         self.change_x = 0
  41.         self.change_y = 0
  42.  
  43.         # List of sprites we can bump against
  44.         self.level = None
  45.  
  46.     def update(self):
  47.         """ Move the player. """
  48.  
  49.         # Move left/right
  50.         self.rect.x += self.change_x
  51.  
  52.         # See if we hit anything
  53.         block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
  54.         for block in block_hit_list:
  55.             # If we are moving right,
  56.             # set our right side to the left side of the item we hit
  57.             if self.change_x > 0:
  58.                 self.rect.right = block.rect.left
  59.             elif self.change_x < 0:
  60.                 # Otherwise if we are moving left, do the opposite.
  61.                 self.rect.left = block.rect.right
  62.  
  63.         # Move up/down
  64.         self.rect.y += self.change_y
  65.  
  66.         # Check and see if we hit anything
  67.         block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
  68.         for block in block_hit_list:
  69.  
  70.             # Reset our position based on the top/bottom of the object.
  71.             if self.change_y > 0:
  72.                 self.rect.bottom = block.rect.top
  73.             elif self.change_y < 0:
  74.                 self.rect.top = block.rect.bottom
  75.  
  76.             # Stop our vertical movement
  77.             self.change_y = 0
  78.  
  79.             if isinstance(block, MovingPlatform):
  80.                 self.rect.x += block.change_x
  81.  
  82.     def go_up(self):
  83.         """ Called when user hits the up arrow. """
  84.         self.change_y = -6
  85.  
  86.     def go_down(self):
  87.         """ Called when user hits the down arrow. """
  88.         self.change_y = 6
  89.  
  90.     # Player-controlled movement:
  91.     def go_left(self):
  92.         """ Called when the user hits the left arrow. """
  93.         self.change_x = -6
  94.  
  95.     def go_right(self):
  96.         """ Called when the user hits the right arrow. """
  97.         self.change_x = 6
  98.  
  99.     def stop_x(self):
  100.         """ Called when the user lets off the keyboard. """
  101.         self.change_x = 0
  102.  
  103.     def stop_y(self):
  104.         """ Called when the user lets off the keyboard. """
  105.         self.change_y = 0
  106.  
  107.  
  108. class Platform(pygame.sprite.Sprite):
  109.     """ Platform the user can jump on """
  110.  
  111.     def __init__(self, width, height):
  112.         """ Platform constructor. Assumes constructed with user passing in
  113.            an array of 5 numbers like what's defined at the top of this code.
  114.            """
  115.         super().__init__()
  116.  
  117.         self.image = pygame.Surface([width, height])
  118.         self.image.fill(GREEN)
  119.  
  120.         self.rect = self.image.get_rect()
  121.  
  122.  
  123. class MovingPlatform(Platform):
  124.     """ This is a fancier platform that can actually move. """
  125.     change_x = 0
  126.     change_y = 0
  127.  
  128.     boundary_top = 0
  129.     boundary_bottom = 0
  130.     boundary_left = 0
  131.     boundary_right = 0
  132.  
  133.     player = None
  134.  
  135.     level = None
  136.  
  137.     def update(self):
  138.         """ Move the platform.
  139.            If the player is in the way, it will shove the player
  140.            out of the way. This does NOT handle what happens if a
  141.            platform shoves a player into another object. Make sure
  142.            moving platforms have clearance to push the player around
  143.            or add code to handle what happens if they don't. """
  144.  
  145.         # Move left/right
  146.         self.rect.x += self.change_x
  147.  
  148.         # See if we hit the player
  149.         hit = pygame.sprite.collide_rect(self, self.player)
  150.         if hit:
  151.             # We did hit the player. Shove the player around and
  152.             # assume he/she won't hit anything else.
  153.  
  154.             # If we are moving right, set our right side
  155.             # to the left side of the item we hit
  156.             if self.change_x < 0:
  157.                 self.player.rect.right = self.rect.left
  158.             else:
  159.                 # Otherwise if we are moving left, do the opposite.
  160.                 self.player.rect.left = self.rect.right
  161.  
  162.         # Move up/down
  163.         self.rect.y += self.change_y
  164.  
  165.         # Check and see if we the player
  166.         hit = pygame.sprite.collide_rect(self, self.player)
  167.         if hit:
  168.             # We did hit the player. Shove the player around and
  169.             # assume he/she won't hit anything else.
  170.  
  171.             # Reset our position based on the top/bottom of the object.
  172.             if self.change_y < 0:
  173.                 self.player.rect.bottom = self.rect.top
  174.             else:
  175.                 self.player.rect.top = self.rect.bottom
  176.  
  177.         # Check the boundaries and see if we need to reverse
  178.         # direction.
  179.         if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
  180.             self.change_y *= -1
  181.  
  182.         cur_pos = self.rect.x - self.level.world_shift
  183.         if cur_pos < self.boundary_left or cur_pos > self.boundary_right:
  184.             self.change_x *= -1
  185.  
  186.  
  187. class Level(object):
  188.     """ This is a generic super-class used to define a level.
  189.        Create a child class for each level with level-specific
  190.        info. """
  191.  
  192.     def __init__(self, player):
  193.         """ Constructor. Pass in a handle to player. Needed for when moving
  194.            platforms collide with the player. """
  195.         self.platform_list = pygame.sprite.Group()
  196.         self.enemy_list = pygame.sprite.Group()
  197.         self.player = player
  198.  
  199.         # Background image
  200.         self.background = None
  201.  
  202.         # How far this world has been scrolled left/right
  203.         self.world_shift = 0
  204.         self.level_limit = -1000
  205.  
  206.     # Update everything on this level
  207.     def update(self):
  208.         """ Update everything in this level."""
  209.         self.platform_list.update()
  210.         self.enemy_list.update()
  211.  
  212.     def draw(self, screen):
  213.         """ Draw everything on this level. """
  214.  
  215.         # Draw the background
  216.         screen.fill(BLUE)
  217.  
  218.         # Draw all the sprite lists that we have
  219.         self.platform_list.draw(screen)
  220.         self.enemy_list.draw(screen)
  221.  
  222.     def shift_world(self, shift_x):
  223.         """ When the user moves left/right and we need to scroll everything:
  224.        """
  225.  
  226.         # Keep track of the shift amount
  227.         self.world_shift += shift_x
  228.  
  229.         # Go through all the sprite lists and shift
  230.         for platform in self.platform_list:
  231.             platform.rect.x += shift_x
  232.  
  233.         for enemy in self.enemy_list:
  234.             enemy.rect.x += shift_x
  235.  
  236.  
  237. # Create platforms for the level
  238. class Level1(Level):
  239.     """ Definition for level 1. """
  240.  
  241.     def __init__(self, player):
  242.         """ Create level 1. """
  243.  
  244.         # Call the parent constructor
  245.         Level.__init__(self, player)
  246.  
  247.         self.level_limit = -1500
  248.  
  249.         # Array with width, height, x, and y of platform
  250.         level = [[210, 70, 500, 500],
  251.                  [210, 70, 800, 400],
  252.                  [210, 70, 1000, 500],
  253.                  [210, 70, 1120, 280],
  254.                  ]
  255.  
  256.         # Go through the array above and add platforms
  257.         for platform in level:
  258.             block = Platform(platform[0], platform[1])
  259.             block.rect.x = platform[2]
  260.             block.rect.y = platform[3]
  261.             block.player = self.player
  262.             self.platform_list.add(block)
  263.  
  264.  
  265. def main():
  266.     """ Main Program """
  267.     pygame.init()
  268.  
  269.     # Set the height and width of the screen
  270.     size = [SCREEN_WIDTH, SCREEN_HEIGHT]
  271.     screen = pygame.display.set_mode(size)
  272.  
  273.     pygame.display.set_caption("Platformer with moving platforms")
  274.  
  275.     # Create the player
  276.     player = Player()
  277.  
  278.     # Create all the levels
  279.     level_list = [Level1(player)]
  280.  
  281.     # Set the current level
  282.     current_level_no = 0
  283.     current_level = level_list[current_level_no]
  284.  
  285.     active_sprite_list = pygame.sprite.Group()
  286.     player.level = current_level
  287.  
  288.     player.rect.x = 340
  289.     player.rect.y = SCREEN_HEIGHT - player.rect.height
  290.     active_sprite_list.add(player)
  291.  
  292.     # Loop until the user clicks the close button.
  293.     done = False
  294.  
  295.     # Used to manage how fast the screen updates
  296.     clock = pygame.time.Clock()
  297.  
  298.     # -------- Main Program Loop -----------
  299.     while not done:
  300.         for event in pygame.event.get():
  301.             if event.type == pygame.QUIT:
  302.                 done = True
  303.  
  304.             if event.type == pygame.KEYDOWN:
  305.                 if event.key == pygame.K_a:
  306.                     player.go_left()
  307.                 if event.key == pygame.K_d:
  308.                     player.go_right()
  309.                 if event.key == pygame.K_w:
  310.                     player.go_up()
  311.                 if event.key == pygame.K_s:
  312.                     player.go_down()
  313.  
  314.             if event.type == pygame.KEYUP:
  315.                 if event.key == pygame.K_a and player.change_x < 0:
  316.                     player.stop_x()
  317.                 if event.key == pygame.K_d and player.change_x > 0:
  318.                     player.stop_x()
  319.                 if event.key == pygame.K_w and player.change_y < 0:
  320.                     player.stop_y()
  321.                 if event.key == pygame.K_s and player.change_y > 0:
  322.                     player.stop_y()
  323.  
  324.         # Update the player.
  325.         active_sprite_list.update()
  326.  
  327.         # Update items in the level
  328.         current_level.update()
  329.  
  330.         # If the player gets near the right side, shift the world left (-x)
  331.         if player.rect.right >= 500:
  332.             diff = player.rect.right - 500
  333.             player.rect.right = 500
  334.             current_level.shift_world(-diff)
  335.  
  336.         # If the player gets near the left side, shift the world right (+x)
  337.         if player.rect.left <= 120:
  338.             diff = 120 - player.rect.left
  339.             player.rect.left = 120
  340.             current_level.shift_world(diff)
  341.  
  342.         # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
  343.         current_level.draw(screen)
  344.         active_sprite_list.draw(screen)
  345.  
  346.         # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
  347.  
  348.         # Limit to 60 frames per second
  349.         clock.tick(60)
  350.  
  351.         # Go ahead and update the screen with what we've drawn.
  352.         pygame.display.flip()
  353.  
  354.     # Be IDLE friendly. If you forget this line, the program will 'hang'
  355.     # on exit.
  356.     pygame.quit()
  357.  
  358.  
  359. if __name__ == "__main__":
  360.     main()
  361.