Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.44 KB | None | 0 0
  1. import arcade
  2. import os
  3.  
  4. # Constants
  5. SCREEN_WIDTH = 800
  6. SCREEN_HEIGHT = 800
  7. SCREEN_TITLE = "Platformer"
  8.  
  9. # Constants used to scale our sprites from their original size
  10. CHARACTER_SCALING = 1
  11. TILE_SCALING = 1
  12. COIN_SCALING = 0.5
  13. SPRITE_PIXEL_SIZE = 128
  14. GRID_PIXEL_SIZE = (SPRITE_PIXEL_SIZE * TILE_SCALING)
  15. ENEMY_SCALING = 1
  16. SPRITE_SIZE = 32
  17. SPRITE_SCALING = 0.1
  18.  
  19. # Movement speed of player, in pixels per frame
  20. PLAYER_MOVEMENT_SPEED = 2
  21. GRAVITY = 0.1
  22. PLAYER_JUMP_SPEED = 5
  23. GRAVITY_CONSTANT = 1
  24.  
  25. # How many pixels to keep as a minimum margin between the character
  26. # and the edge of the screen.
  27. LEFT_VIEWPORT_MARGIN = 25
  28. RIGHT_VIEWPORT_MARGIN = 500
  29. BOTTOM_VIEWPORT_MARGIN = 0
  30. TOP_VIEWPORT_MARGIN = 200
  31.  
  32. PLAYER_START_X = 32
  33. PLAYER_START_Y = 25
  34.  
  35. # Constants used to track if the player is facing left or right
  36. RIGHT_FACING = 0
  37. LEFT_FACING = 1
  38.  
  39.  
  40. def load_texture_pair(filename):
  41. """
  42. Load a texture pair, with the second being a mirror image.
  43. """
  44. return [
  45. arcade.load_texture(filename, scale=CHARACTER_SCALING),
  46. arcade.load_texture(filename, scale=CHARACTER_SCALING, mirrored=True)
  47. ]
  48.  
  49.  
  50. class PlayerCharacter(arcade.Sprite):
  51. def __init__(self):
  52.  
  53. # Set up parent class
  54. super().__init__()
  55.  
  56. # Default to face-right
  57. self.character_face_direction = RIGHT_FACING
  58.  
  59. # Used for flipping between image sequences
  60. self.cur_texture = 0
  61.  
  62. # Track our state
  63. self.jumping = False
  64. self.climbing = False
  65. self.is_on_ladder = False
  66. self.game_over = False
  67.  
  68. # Adjust the collision box. Default includes too much empty space
  69. # side-to-side. Box is centered at sprite center, (0, 0)
  70. self.points = [[-5.5, -16], [5.5, -16], [5.5, 7], [-5.5, 7]]
  71.  
  72. # --- Load Textures ---
  73.  
  74. # main_path = "images/Female adventurer/PNG/Poses/character_femaleAdventurer"
  75. # main_path = "images/Female person/PNG/Poses/character_femalePerson"
  76. # main_path = "images/Male person/PNG/Poses/character_malePerson"
  77. # main_path = "images/Male adventurer/PNG/Poses/character_maleAdventurer"
  78. # main_path = "images/Zombie/PNG/Poses/character_zombie"
  79. # main_path = "images/Robot/PNG/Poses/character_robot"
  80.  
  81. main_path = "images/player_1/"
  82.  
  83. # Load textures for idle standing
  84. self.idle_texture_pair = load_texture_pair(f"{main_path}idle.png")
  85. self.jump_texture_pair = load_texture_pair(f"{main_path}jump.png")
  86. self.fall_texture_pair = load_texture_pair(f"{main_path}fall.png")
  87.  
  88. # Load textures for walking
  89. self.walk_textures = []
  90. for i in range(4):
  91. texture = load_texture_pair(f"{main_path}walk{i}.png")
  92. self.walk_textures.append(texture)
  93.  
  94. # Load textures for climbing
  95. self.climbing_textures = []
  96. texture = arcade.load_texture(f"{main_path}climb2.png", scale=CHARACTER_SCALING)
  97. self.climbing_textures.append(texture)
  98. texture = arcade.load_texture(f"{main_path}climb1.png", scale=CHARACTER_SCALING)
  99. self.climbing_textures.append(texture)
  100.  
  101. def update_animation(self, delta_time: float = 1/60):
  102.  
  103. # Figure out if we need to flip face left or right
  104. if self.change_x < 0 and self.character_face_direction == RIGHT_FACING:
  105. self.character_face_direction = LEFT_FACING
  106. elif self.change_x > 0 and self.character_face_direction == LEFT_FACING:
  107. self.character_face_direction = RIGHT_FACING
  108. if self.center_x > 960:
  109. self.center_x = 950
  110. #Die if Y is below 0
  111. if self.center_y < -0:
  112. self.center_y = PLAYER_START_Y
  113. self.center_x = PLAYER_START_X
  114. #Next level
  115. if self.center_x > 900 and self.center_y < 90:
  116. arcade.finish_render()
  117. arcade.close_window()
  118. from subprocess import call
  119. call(["python", "level2.py"])
  120.  
  121. # Climbing animation
  122. if self.is_on_ladder:
  123. self.climbing = True
  124. if not self.is_on_ladder and self.climbing:
  125. self.climbing = False
  126. if self.climbing and abs(self.change_y) > 1:
  127. self.cur_texture += 1
  128. if self.cur_texture > 7:
  129. self.cur_texture = 0
  130. if self.climbing:
  131. self.texture = self.climbing_textures[self.cur_texture // 4]
  132. return
  133.  
  134. # Jumping animation
  135. if self.jumping and not self.is_on_ladder:
  136. if self.change_y >= 0:
  137. self.texture = self.jump_texture_pair[self.character_face_direction]
  138. else:
  139. self.texture = self.fall_texture_pair[self.character_face_direction]
  140. return
  141.  
  142.  
  143.  
  144. # Idle animation
  145. if self.change_x == 0:
  146. self.texture = self.idle_texture_pair[self.character_face_direction]
  147. return
  148.  
  149. # Walking animation
  150. self.cur_texture += 1
  151. if self.cur_texture > 3:
  152. self.cur_texture = 0
  153. self.texture = self.walk_textures[self.cur_texture][self.character_face_direction]
  154.  
  155. #boundary
  156.  
  157. if self.left < 0:
  158. self.left = 0
  159. elif self.right > SCREEN_WIDTH * 3:
  160. self.right = SCREEN_WIDTH - 1
  161.  
  162. if self.bottom < 0:
  163. self.bottom = 0
  164. elif self.top > SCREEN_HEIGHT * 3:
  165. self.top = SCREEN_HEIGHT - 1
  166.  
  167.  
  168. class MyGame(arcade.Window):
  169. """
  170. Main application class.
  171. """
  172.  
  173. def __init__(self):
  174. """
  175. Initializer for the game
  176. """
  177.  
  178. # Call the parent class and set up the window
  179. super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
  180.  
  181. # Set the path to start with this program
  182. file_path = os.path.dirname(os.path.abspath(__file__))
  183. os.chdir(file_path)
  184.  
  185. # Track the current state of what key is pressed
  186. self.left_pressed = False
  187. self.right_pressed = False
  188. self.up_pressed = False
  189. self.down_pressed = False
  190. self.jump_needs_reset = False
  191.  
  192. # These are 'lists' that keep track of our sprites. Each sprite should
  193. # go into a list.
  194. self.coin_list = None
  195. self.wall_list = None
  196. self.background_list = None
  197. self.ladder_list = None
  198. self.player_list = None
  199. self.enemy_list = None
  200. self.moving_wall_list = None
  201. # Separate variable that holds the player sprite
  202. self.player_sprite = None
  203.  
  204. # Our 'physics' engine
  205. self.physics_engine = None
  206.  
  207. # Used to keep track of our scrolling
  208. self.view_bottom = 0
  209. self.view_left = 0
  210.  
  211. self.end_of_map = 0
  212.  
  213. # Keep track of the score
  214. self.score = 0
  215.  
  216. # Load sounds
  217. self.collect_coin_sound = arcade.load_sound("sounds/coin1.wav")
  218. self.jump_sound = arcade.load_sound("sounds/jump1.wav")
  219. self.game_over = arcade.load_sound("sounds/gameover1.wav")
  220.  
  221. def setup(self):
  222. """ Set up the game here. Call this function to restart the game. """
  223.  
  224. # Used to keep track of our scrolling
  225. self.view_bottom = 0
  226. self.view_left = 0
  227.  
  228. # Keep track of the score
  229. self.score = 0
  230.  
  231. # Create the Sprite lists
  232. self.player_list = arcade.SpriteList()
  233. self.background_list = arcade.SpriteList()
  234. self.wall_list = arcade.SpriteList()
  235. self.coin_list = arcade.SpriteList()
  236. self.enemy_list = arcade.SpriteList()
  237. self.movingplatforms_list = arcade.SpriteList()
  238.  
  239.  
  240. # Set up the player, specifically placing it at these coordinates.
  241. # self.player_sprite = arcade.Sprite("images/player_1/player_stand.png", CHARACTER_SCALING)
  242. self.player_sprite = PlayerCharacter()
  243. self.player_sprite.center_x = PLAYER_START_X
  244. self.player_sprite.center_y = PLAYER_START_Y
  245. self.player_list.append(self.player_sprite)
  246.  
  247. # --- Load in a map from the tiled editor ---
  248.  
  249. # Name of the layer in the file that has our platforms/walls
  250. platforms_layer_name = 'Platforms'
  251. moving_platforms_layer_name = 'Moving Platforms'
  252.  
  253. # Name of the layer that has items for pick-up
  254. coins_layer_name = 'Coins'
  255.  
  256. # Map name
  257. map_name = f"LEVEL_1.tmx"
  258.  
  259. # Read in the tiled map
  260. my_map = arcade.tilemap.read_tmx(map_name)
  261.  
  262. # Calculate the right edge of the my_map in pixels
  263. self.end_of_map = my_map.map_size.width * GRID_PIXEL_SIZE
  264.  
  265. # -- Platforms
  266. self.wall_list = arcade.tilemap.process_layer(my_map, platforms_layer_name, TILE_SCALING)
  267.  
  268. # -- Moving Platforms
  269. moving_platforms_list = arcade.tilemap.process_layer(my_map, moving_platforms_layer_name, TILE_SCALING)
  270. for sprite in moving_platforms_list:
  271. sprite.boundary_top = sprite.center_y + 300
  272. sprite.boundary_bottom = sprite.center_y - 75
  273. sprite.change_y = 2
  274. self.movingplatforms_list.append(sprite)
  275. self.wall_list.append(sprite)
  276.  
  277.  
  278. # -- Spike #1
  279. enemy = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  280.  
  281. enemy.bottom = 48
  282. enemy.left = 112
  283.  
  284. #Spike #2
  285. enemy2 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  286. enemy2.bottom = 48
  287. enemy2.left = 128
  288. #Spike #3
  289. enemy3 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  290. enemy3.bottom = 48
  291. enemy3.left = 144
  292. #Spike #4
  293. enemy4 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  294. enemy4.bottom = 48
  295. enemy4.left = 160
  296. #Spike #5
  297. enemy5 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  298. enemy5.bottom = 48
  299. enemy5.left = 176
  300. #Spike #6
  301. enemy6 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  302. enemy6.bottom = 80
  303. enemy6.left = 720
  304. #Spike #7
  305. enemy7 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  306. enemy7.bottom = 160
  307. enemy7.left = 21*16
  308. #Spike #8
  309. enemy8 = arcade.Sprite("images/enemies/spike.png", ENEMY_SCALING)
  310. enemy8.bottom = 160
  311. enemy8.left = 22*16
  312.  
  313.  
  314.  
  315. # Set enemy initial speed
  316. enemy.change_x = 0
  317. self.enemy_list.append(enemy)
  318. self.enemy_list.append(enemy2)
  319. self.enemy_list.append(enemy3)
  320. self.enemy_list.append(enemy4)
  321. self.enemy_list.append(enemy5)
  322. self.enemy_list.append(enemy6)
  323. self.enemy_list.append(enemy7)
  324. self.enemy_list.append(enemy8)
  325.  
  326. # -- Background objects
  327. self.background_list = arcade.tilemap.process_layer(my_map, "Background", TILE_SCALING)
  328.  
  329. # -- End Flagpole
  330. self.end_list = arcade.tilemap.process_layer(my_map, "End", TILE_SCALING)
  331.  
  332. # -- Background objects
  333. self.ladder_list = arcade.tilemap.process_layer(my_map, "Ladders", TILE_SCALING)
  334.  
  335. # -- Coins
  336. self.coin_list = arcade.tilemap.process_layer(my_map, coins_layer_name, TILE_SCALING)
  337.  
  338. # --- Other stuff
  339. # Set the background color
  340. if my_map.background_color:
  341. arcade.set_background_color(my_map.background_color)
  342.  
  343. # Create the 'physics engine'
  344. self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,
  345. self.wall_list,
  346. gravity_constant=GRAVITY,
  347. ladders=self.ladder_list)
  348.  
  349. def on_draw(self):
  350. """ Render the screen. """
  351.  
  352. # Clear the screen to the background color
  353. arcade.start_render()
  354.  
  355. # Draw our sprites
  356. self.background_list.draw()
  357. self.wall_list.draw()
  358. self.ladder_list.draw()
  359. self.coin_list.draw()
  360. self.player_list.draw()
  361. self.end_list.draw()
  362. self.enemy_list.draw()
  363. self.movingplatforms_list.draw()
  364. # Draw our score on the screen, scrolling it with the viewport
  365.  
  366. def process_keychange(self):
  367. """
  368. Called when we change a key up/down or we move on/off a ladder.
  369. """
  370. # Process up/down
  371. if self.up_pressed and not self.down_pressed:
  372. if self.physics_engine.is_on_ladder():
  373. self.player_sprite.change_y = PLAYER_MOVEMENT_SPEED
  374. elif self.physics_engine.can_jump() and not self.jump_needs_reset:
  375. self.player_sprite.change_y = PLAYER_JUMP_SPEED
  376. self.jump_needs_reset = True
  377. arcade.play_sound(self.jump_sound)
  378. elif self.down_pressed and not self.up_pressed:
  379. if self.physics_engine.is_on_ladder():
  380. self.player_sprite.change_y = -PLAYER_MOVEMENT_SPEED
  381.  
  382. # Process up/down when on a ladder and no movement
  383. if self.physics_engine.is_on_ladder():
  384. if not self.up_pressed and not self.down_pressed:
  385. self.player_sprite.change_y = 0
  386. elif self.up_pressed and self.down_pressed:
  387. self.player_sprite.change_y = 0
  388.  
  389. # Process left/right
  390. if self.right_pressed and not self.left_pressed:
  391. self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
  392. elif self.left_pressed and not self.right_pressed:
  393. self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
  394. else:
  395. self.player_sprite.change_x = 0
  396.  
  397. def on_key_press(self, key, modifiers):
  398. """Called whenever a key is pressed. """
  399.  
  400. if key == arcade.key.UP or key == arcade.key.W:
  401. self.up_pressed = True
  402. elif key == arcade.key.DOWN or key == arcade.key.S:
  403. self.down_pressed = True
  404. elif key == arcade.key.LEFT or key == arcade.key.A:
  405. self.left_pressed = True
  406. elif key == arcade.key.RIGHT or key == arcade.key.D:
  407. self.right_pressed = True
  408.  
  409. self.process_keychange()
  410.  
  411. def on_key_release(self, key, modifiers):
  412. """Called when the user releases a key. """
  413.  
  414. if key == arcade.key.UP or key == arcade.key.W:
  415. self.up_pressed = False
  416. self.jump_needs_reset = False
  417. elif key == arcade.key.DOWN or key == arcade.key.S:
  418. self.down_pressed = False
  419. elif key == arcade.key.LEFT or key == arcade.key.A:
  420. self.left_pressed = False
  421. elif key == arcade.key.RIGHT or key == arcade.key.D:
  422. self.right_pressed = False
  423.  
  424. self.process_keychange()
  425.  
  426. def on_update(self, delta_time):
  427. """ Movement and game logic """
  428.  
  429. # Call update on all sprites (The sprites don't do much in this
  430. # example though.)
  431. self.physics_engine.update()
  432.  
  433. # Update animations
  434. if self.physics_engine.can_jump():
  435. self.player_sprite.can_jump = False
  436. else:
  437. self.player_sprite.can_jump = True
  438.  
  439. if self.physics_engine.is_on_ladder() and not self.physics_engine.can_jump():
  440. self.player_sprite.is_on_ladder = True
  441. self.process_keychange()
  442. else:
  443. self.player_sprite.is_on_ladder = False
  444. self.process_keychange()
  445.  
  446. self.coin_list.update_animation(delta_time)
  447. self.background_list.update_animation(delta_time)
  448. self.player_list.update_animation(delta_time)
  449.  
  450.  
  451. #die if self.game_over is true
  452. if self.game_over:
  453. self.player_sprite.center_x = PLAYER_START_X
  454. self.player_sprite.center_y = PLAYER_START_Y
  455. self.game_over = False
  456.  
  457. # Update walls, used with moving platforms
  458. self.wall_list.update()
  459.  
  460. # Update the player based on the physics engine
  461. if not self.game_over:
  462. # Move the enemies
  463. self.enemy_list.update()
  464.  
  465. # Check each enemy
  466. for enemy in self.enemy_list:
  467. # If the enemy hit a wall, reverse
  468. if len(arcade.check_for_collision_with_list(enemy, self.wall_list)) > 0:
  469. enemy.change_x *= 0
  470. # If the enemy hit the left boundary, reverse
  471. elif enemy.boundary_left is not None and enemy.left < enemy.boundary_left:
  472. enemy.change_x *= 0
  473. # If the enemy hit the right boundary, reverse
  474. elif enemy.boundary_right is not None and enemy.right > enemy.boundary_right:
  475. enemy.change_x = 0
  476.  
  477. # Update the player using the physics engine
  478. self.physics_engine.update()
  479.  
  480. # See if the player hit a worm. If so, game over.
  481. if len(arcade.check_for_collision_with_list(self.player_sprite, self.enemy_list)) > 0:
  482. self.game_over = True
  483.  
  484.  
  485. # See if we hit any coins
  486. coin_hit_list = arcade.check_for_collision_with_list(self.player_sprite,
  487. self.coin_list)
  488.  
  489. # Loop through each coin we hit (if any) and remove it
  490. for coin in coin_hit_list:
  491.  
  492. # Figure out how many points this coin is worth
  493. if 'Points' not in coin.properties:
  494. print("Warning, collected a coin without a Points property.")
  495. else:
  496. points = int(coin.properties['Points'])
  497. self.score += points
  498.  
  499. # Remove the coin
  500. coin.remove_from_sprite_lists()
  501. arcade.play_sound(self.collect_coin_sound)
  502.  
  503. # Track if we need to change the viewport
  504. changed_viewport = True
  505.  
  506. # --- Manage Scrolling ---
  507.  
  508. # Scroll left
  509. left_boundary = self.view_left + LEFT_VIEWPORT_MARGIN
  510. if self.player_sprite.left < left_boundary:
  511. self.view_left -= left_boundary - self.player_sprite.left
  512. changed_viewport = True
  513.  
  514. # Scroll right
  515. right_boundary = self.view_left + SCREEN_WIDTH - RIGHT_VIEWPORT_MARGIN
  516. if self.player_sprite.right > right_boundary:
  517. self.view_left += self.player_sprite.right - right_boundary
  518. changed_viewport = True
  519.  
  520. # Scroll up
  521. # top_boundary = self.view_bottom + SCREEN_HEIGHT - TOP_VIEWPORT_MARGIN
  522. # if self.player_sprite.top > top_boundary:
  523. # self.view_bottom += self.player_sprite.top - top_boundary
  524. # changed_viewport = True
  525.  
  526. # Scroll down
  527. bottom_boundary = self.view_bottom + BOTTOM_VIEWPORT_MARGIN
  528. if self.player_sprite.bottom < bottom_boundary:
  529. self.view_bottom -= bottom_boundary - self.player_sprite.bottom
  530. changed_viewport = True
  531.  
  532. if changed_viewport:
  533. # Only scroll to integers. Otherwise we end up with pixels that
  534. # don't line up on the screen
  535. self.view_bottom = int(self.view_bottom)
  536. self.view_left = int(self.view_left)
  537.  
  538. # Do the scrolling
  539. self.view_right = SCREEN_WIDTH + self.view_left-400
  540. if self.view_left < 2:
  541. self.view_left = 2
  542. if SCREEN_WIDTH + self.view_left-400 > 960:
  543. self.view_left = 960+400-SCREEN_WIDTH
  544. if self.view_bottom < 0:
  545. self.view_bottom = 0
  546. arcade.set_viewport(self.view_left,
  547. SCREEN_WIDTH + self.view_left-400,
  548. self.view_bottom,
  549. SCREEN_HEIGHT + self.view_bottom-400)
  550.  
  551.  
  552. def main():
  553. """ Main method """
  554. window = MyGame()
  555. window.setup()
  556. arcade.run()
  557.  
  558. class Start_screen(arcade.Window):
  559. #will class what we are doing is creating a tpye of varible. The tpye of varible is called Game
  560.  
  561. def __init__(self):
  562. '''
  563. when making a class we always start with the initializer function
  564. we call this function __init__. Self is what holds all of the information inside the class.
  565. '''
  566.  
  567. super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
  568. # this one here is kind of weird. We recall the function __init__ from inside the function __init__
  569. # but we call it as a super so it does some weird stuff and opens the window for the game.
  570.  
  571.  
  572.  
  573. def setup(self):
  574. self.background = None
  575. def on_draw(self):
  576. #The name is very important. Based on the name the class will run the function at different times
  577. # here you will draw your character and your background, really anything that you want on the screen
  578. arcade.start_render()
  579. self.background = arcade.load_texture("images/start.png")
  580. arcade.draw_texture_rectangle(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
  581.  
  582. def on_key_press(self, key, modifiers):
  583.  
  584. if key == arcade.key.ENTER:
  585. arcade.close_window()
  586. main()
  587. if key == arcade.key.ESCAPE:
  588. arcade.close_window()
  589.  
  590.  
  591. def mainstart():
  592. #
  593. start = Start_screen()
  594. start.setup()
  595. arcade.run()
  596.  
  597.  
  598. if __name__ == "__main__":
  599.  
  600. mainstart()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement