Advertisement
PhilipCander

Untitled

Oct 21st, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.18 KB | None | 0 0
  1. """
  2. Sample Python/Pygame Programs
  3. Simpson College Computer Science
  4. http://programarcadegames.com/
  5. http://simpson.edu/computer-science/
  6.  
  7. From:
  8. http://programarcadegames.com/python_examples/f.php?file=platform_moving.py
  9.  
  10. Explanation video: http://youtu.be/YKdOD5VkY48
  11.  
  12. Part of a series:
  13. http://programarcadegames.com/python_examples/f.php?file=move_with_walls_example.py
  14. http://programarcadegames.com/python_examples/f.php?file=maze_runner.py
  15. http://programarcadegames.com/python_examples/f.php?file=platform_jumper.py
  16. http://programarcadegames.com/python_examples/f.php?file=platform_scroller.py
  17. http://programarcadegames.com/python_examples/f.php?file=platform_moving.py
  18. http://programarcadegames.com/python_examples/sprite_sheets/
  19. """
  20. import pygame
  21.  
  22. # Global constants
  23.  
  24. # Colors
  25. BLACK = (0, 0, 0)
  26. WHITE = (255, 255, 255)
  27. GREEN = (0, 255, 0)
  28. RED = (255, 0, 0)
  29. BLUE = (0, 0, 255)
  30.  
  31. # Screen dimensions
  32. SCREEN_WIDTH = 800
  33. SCREEN_HEIGHT = 600
  34.  
  35.  
  36. class Player(pygame.sprite.Sprite):
  37. """
  38. This class represents the bar at the bottom that the player controls.
  39. """
  40.  
  41. # -- Methods
  42. def __init__(self):
  43. """ Constructor function """
  44.  
  45. # Call the parent's constructor
  46. super().__init__()
  47.  
  48. # Create an image of the block, and fill it with a color.
  49. # This could also be an image loaded from the disk.
  50. width = 40
  51. height = 60
  52. self.image = pygame.Surface([width, height])
  53. self.image.fill(RED)
  54.  
  55. # Set a referance to the image rect.
  56. self.rect = self.image.get_rect()
  57.  
  58. # Set speed vector of player
  59. self.change_x = 0
  60. self.change_y = 0
  61.  
  62. # List of sprites we can bump against
  63. self.level = None
  64.  
  65. def update(self):
  66. """ Move the player. """
  67. # Gravity
  68. self.calc_grav()
  69.  
  70. # Move left/right
  71. self.rect.x += self.change_x
  72.  
  73. # See if we hit anything
  74. block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
  75. for block in block_hit_list:
  76. # If we are moving right,
  77. # set our right side to the left side of the item we hit
  78. if self.change_x > 0:
  79. self.rect.right = block.rect.left
  80. elif self.change_x < 0:
  81. # Otherwise if we are moving left, do the opposite.
  82. self.rect.left = block.rect.right
  83.  
  84. # Move up/down
  85. self.rect.y += self.change_y
  86.  
  87. # Check and see if we hit anything
  88. block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
  89. for block in block_hit_list:
  90.  
  91. # Reset our position based on the top/bottom of the object.
  92. if self.change_y > 0:
  93. self.rect.bottom = block.rect.top
  94. elif self.change_y < 0:
  95. self.rect.top = block.rect.bottom
  96.  
  97. # Stop our vertical movement
  98. self.change_y = 0
  99.  
  100. if isinstance(block, MovingPlatform):
  101. self.rect.x += block.change_x
  102.  
  103. def calc_grav(self):
  104. """ Calculate effect of gravity. """
  105. if self.change_y == 0:
  106. self.change_y = 1
  107. else:
  108. self.change_y += .35
  109.  
  110. # See if we are on the ground.
  111. if self.rect.y >= SCREEN_HEIGHT - self.rect.height and self.change_y >= 0:
  112. self.change_y = 0
  113. self.rect.y = SCREEN_HEIGHT - self.rect.height
  114.  
  115. def jump(self):
  116. """ Called when user hits 'jump' button. """
  117.  
  118. # move down a bit and see if there is a platform below us.
  119. # Move down 2 pixels because it doesn't work well if we only move down
  120. # 1 when working with a platform moving down.
  121. self.rect.y += 2
  122. platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
  123. self.rect.y -= 2
  124.  
  125. # If it is ok to jump, set our speed upwards
  126. if len(platform_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT:
  127. self.change_y = -10
  128.  
  129. # Player-controlled movement:
  130. def go_left(self):
  131. """ Called when the user hits the left arrow. """
  132. self.change_x = -6
  133.  
  134. def go_right(self):
  135. """ Called when the user hits the right arrow. """
  136. self.change_x = 6
  137.  
  138. def stop(self):
  139. """ Called when the user lets off the keyboard. """
  140. self.change_x = 0
  141.  
  142.  
  143. class Platform(pygame.sprite.Sprite):
  144. """ Platform the user can jump on """
  145.  
  146. def __init__(self, width, height):
  147. """ Platform constructor. Assumes constructed with user passing in
  148. an array of 5 numbers like what's defined at the top of this code.
  149. """
  150. super().__init__()
  151.  
  152. self.image = pygame.Surface([width, height])
  153. self.image.fill(GREEN)
  154.  
  155. self.rect = self.image.get_rect()
  156.  
  157.  
  158. class MovingPlatform(Platform):
  159. """ This is a fancier platform that can actually move. """
  160. change_x = 0
  161. change_y = 0
  162.  
  163. boundary_top = 0
  164. boundary_bottom = 0
  165. boundary_left = 0
  166. boundary_right = 0
  167.  
  168. player = None
  169.  
  170. level = None
  171.  
  172. def update(self):
  173. """ Move the platform.
  174. If the player is in the way, it will shove the player
  175. out of the way. This does NOT handle what happens if a
  176. platform shoves a player into another object. Make sure
  177. moving platforms have clearance to push the player around
  178. or add code to handle what happens if they don't. """
  179.  
  180. # Move left/right
  181. self.rect.x += self.change_x
  182.  
  183. # See if we hit the player
  184. hit = pygame.sprite.collide_rect(self, self.player)
  185. if hit:
  186. # We did hit the player. Shove the player around and
  187. # assume he/she won't hit anything else.
  188.  
  189. # If we are moving right, set our right side
  190. # to the left side of the item we hit
  191. if self.change_x < 0:
  192. self.player.rect.right = self.rect.left
  193. else:
  194. # Otherwise if we are moving left, do the opposite.
  195. self.player.rect.left = self.rect.right
  196.  
  197. # Move up/down
  198. self.rect.y += self.change_y
  199.  
  200. # Check and see if we the player
  201. hit = pygame.sprite.collide_rect(self, self.player)
  202. if hit:
  203. # We did hit the player. Shove the player around and
  204. # assume he/she won't hit anything else.
  205.  
  206. # Reset our position based on the top/bottom of the object.
  207. if self.change_y < 0:
  208. self.player.rect.bottom = self.rect.top
  209. else:
  210. self.player.rect.top = self.rect.bottom
  211.  
  212. # Check the boundaries and see if we need to reverse
  213. # direction.
  214. if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
  215. self.change_y *= -1
  216.  
  217. cur_pos = self.rect.x - self.level.world_shift
  218. if cur_pos < self.boundary_left or cur_pos > self.boundary_right:
  219. self.change_x *= -1
  220.  
  221.  
  222. class Level(object):
  223. """ This is a generic super-class used to define a level.
  224. Create a child class for each level with level-specific
  225. info. """
  226.  
  227. def __init__(self, player):
  228. """ Constructor. Pass in a handle to player. Needed for when moving
  229. platforms collide with the player. """
  230. self.platform_list = pygame.sprite.Group()
  231. self.enemy_list = pygame.sprite.Group()
  232. self.player = player
  233.  
  234. # Background image
  235. self.background = None
  236.  
  237. # How far this world has been scrolled left/right
  238. self.world_shift = 0
  239. self.level_limit = -1000
  240.  
  241. # Update everythign on this level
  242. def update(self):
  243. """ Update everything in this level."""
  244. self.platform_list.update()
  245. self.enemy_list.update()
  246.  
  247. def draw(self, screen):
  248. """ Draw everything on this level. """
  249.  
  250. # Draw the background
  251. screen.fill(BLUE)
  252.  
  253. # Draw all the sprite lists that we have
  254. self.platform_list.draw(screen)
  255. self.enemy_list.draw(screen)
  256.  
  257. def shift_world(self, shift_x):
  258. """ When the user moves left/right and we need to scroll everything:
  259. """
  260.  
  261. # Keep track of the shift amount
  262. self.world_shift += shift_x
  263.  
  264. # Go through all the sprite lists and shift
  265. for platform in self.platform_list:
  266. platform.rect.x += shift_x
  267.  
  268. for enemy in self.enemy_list:
  269. enemy.rect.x += shift_x
  270.  
  271.  
  272. # Create platforms for the level
  273. class Level_01(Level):
  274. """ Definition for level 1. """
  275.  
  276. def __init__(self, player):
  277. """ Create level 1. """
  278.  
  279. # Call the parent constructor
  280. Level.__init__(self, player)
  281.  
  282. self.level_limit = -1500
  283.  
  284. # Array with width, height, x, and y of platform
  285. level = [[210, 70, 500, 500],
  286. [210, 70, 800, 400],
  287. [210, 70, 1000, 500],
  288. [210, 70, 1120, 280],
  289. ]
  290.  
  291. # Go through the array above and add platforms
  292. for platform in level:
  293. block = Platform(platform[0], platform[1])
  294. block.rect.x = platform[2]
  295. block.rect.y = platform[3]
  296. block.player = self.player
  297. self.platform_list.add(block)
  298.  
  299. # Add a custom moving platform
  300. block = MovingPlatform(70, 40)
  301. block.rect.x = 1350
  302. block.rect.y = 280
  303. block.boundary_left = 1350
  304. block.boundary_right = 1600
  305. block.change_x = 1
  306. block.player = self.player
  307. block.level = self
  308. self.platform_list.add(block)
  309.  
  310.  
  311. # Create platforms for the level
  312. class Level_02(Level):
  313. """ Definition for level 2. """
  314.  
  315. def __init__(self, player):
  316. """ Create level 1. """
  317.  
  318. # Call the parent constructor
  319. Level.__init__(self, player)
  320.  
  321. self.level_limit = -1000
  322.  
  323. # Array with type of platform, and x, y location of the platform.
  324. level = [[210, 70, 500, 550],
  325. [210, 70, 800, 400],
  326. [210, 70, 1000, 500],
  327. [210, 70, 1120, 280],
  328. ]
  329.  
  330. # Go through the array above and add platforms
  331. for platform in level:
  332. block = Platform(platform[0], platform[1])
  333. block.rect.x = platform[2]
  334. block.rect.y = platform[3]
  335. block.player = self.player
  336. self.platform_list.add(block)
  337.  
  338. # Add a custom moving platform
  339. block = MovingPlatform(70, 70)
  340. block.rect.x = 1500
  341. block.rect.y = 300
  342. block.boundary_top = 100
  343. block.boundary_bottom = 550
  344. block.change_y = -1
  345. block.player = self.player
  346. block.level = self
  347. self.platform_list.add(block)
  348.  
  349.  
  350. def main():
  351. """ Main Program """
  352. pygame.init()
  353.  
  354. # Set the height and width of the screen
  355. size = [SCREEN_WIDTH, SCREEN_HEIGHT]
  356. screen = pygame.display.set_mode(size)
  357.  
  358. pygame.display.set_caption("Platformer with moving platforms")
  359.  
  360. # Create the player
  361. player = Player()
  362.  
  363. # Create all the levels
  364. level_list = []
  365. level_list.append(Level_01(player))
  366. level_list.append(Level_02(player))
  367.  
  368. # Set the current level
  369. current_level_no = 0
  370. current_level = level_list[current_level_no]
  371.  
  372. active_sprite_list = pygame.sprite.Group()
  373. player.level = current_level
  374.  
  375. player.rect.x = 340
  376. player.rect.y = SCREEN_HEIGHT - player.rect.height
  377. active_sprite_list.add(player)
  378.  
  379. # Loop until the user clicks the close button.
  380. done = False
  381.  
  382. # Used to manage how fast the screen updates
  383. clock = pygame.time.Clock()
  384.  
  385. # -------- Main Program Loop -----------
  386. while not done:
  387. for event in pygame.event.get():
  388. if event.type == pygame.QUIT:
  389. done = True
  390.  
  391. if event.type == pygame.KEYDOWN:
  392. if event.key == pygame.K_LEFT:
  393. player.go_left()
  394. if event.key == pygame.K_RIGHT:
  395. player.go_right()
  396. if event.key == pygame.K_UP:
  397. player.jump()
  398.  
  399. if event.type == pygame.KEYUP:
  400. if event.key == pygame.K_LEFT and player.change_x < 0:
  401. player.stop()
  402. if event.key == pygame.K_RIGHT and player.change_x > 0:
  403. player.stop()
  404.  
  405. # Update the player.
  406. active_sprite_list.update()
  407.  
  408. # Update items in the level
  409. current_level.update()
  410.  
  411. # If the player gets near the right side, shift the world left (-x)
  412. if player.rect.right >= 500:
  413. diff = player.rect.right - 500
  414. player.rect.right = 500
  415. current_level.shift_world(-diff)
  416.  
  417. # If the player gets near the left side, shift the world right (+x)
  418. if player.rect.left <= 120:
  419. diff = 120 - player.rect.left
  420. player.rect.left = 120
  421. current_level.shift_world(diff)
  422.  
  423. # If the player gets to the end of the level, go to the next level
  424. current_position = player.rect.x + current_level.world_shift
  425. if current_position < current_level.level_limit:
  426. if current_level_no < len(level_list) - 1:
  427. player.rect.x = 120
  428. current_level_no += 1
  429. current_level = level_list[current_level_no]
  430. player.level = current_level
  431. else:
  432. # Out of levels. This just exits the program.
  433. # You'll want to do something better.
  434. done = True
  435.  
  436. # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
  437. current_level.draw(screen)
  438. active_sprite_list.draw(screen)
  439.  
  440. # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
  441.  
  442. # Limit to 60 frames per second
  443. clock.tick(60)
  444.  
  445. # Go ahead and update the screen with what we've drawn.
  446. pygame.display.flip()
  447.  
  448. # Be IDLE friendly. If you forget this line, the program will 'hang'
  449. # on exit.
  450. pygame.quit()
  451.  
  452.  
  453. if __name__ == "__main__":
  454. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement