深圳幻海软件技术有限公司 欢迎您!

使你的Python游戏玩家能够向前和向后跑

2023-02-27

使用Pygame模块来使你的Python平台开启侧滚效果,来让你的玩家自由奔跑。这是仍在进行中的关于使用Pygame模块来在Python3中在创建电脑游戏的第九部分。在这一系列关于使用Pygame模块来在Python3中创建电脑游戏的先前文章中,你已经设计了你的关卡设计布局,但是你的关卡的一些部分可

使用 Pygame 模块来使你的 Python 平台开启侧滚效果,来让你的玩家自由奔跑。

这是仍在进行中的关于使用 Pygame 模块来在 Python 3 中在创建电脑游戏的第九部分。

在这一系列关于使用 Pygame 模块来在 Python 3 中创建电脑游戏的先前文章中,你已经设计了你的关卡设计布局,但是你的关卡的一些部分可能已近超出你的屏幕的可视区域。在平台类游戏中,这个问题的普遍解决方案是,像术语“侧滚side-scroller”表明的一样,滚动。

滚动的关键是当玩家精灵接近屏的幕边缘时,使在玩家精灵周围的平台移动。这样给予一种错觉,屏幕是一个在游戏世界中穿梭追拍的摄像机

这个滚动技巧需要两个在屏幕边缘的绝对区域,在绝对区域内的点处,在世界滚动期间,你的化身静止不动。

在侧滚动条中放置卷轴

如果你希望你的玩家能够后退,你需要一个触发点来向前和向后。这两个点仅仅是两个变量。设置它们各个距各个屏幕边缘大约 100 或 200 像素。在你的设置部分中创建变量。在下面的代码中,前两行用于上下文说明,所以仅需要添加这行后的代码:

  1. player_list.add(player)
  2. steps = 10
  3. forwardX  = 600
  4. backwardX = 230
  • 1.
  • 2.
  • 3.
  • 4.

在主循环中,查看你的玩家精灵是否在 forwardxbackwardx 滚动点处。如果是这样,向左或向右移动使用的平台,取决于世界是向前或向后移动。在下面的代码中,代码的最后三行仅供你参考:

  1.         # scroll the world forward
  2.         if player.rect.x >= forwardx:
  3.                 scroll = player.rect.x - forwardx
  4.                 player.rect.x = forwardx
  5.                 for p in plat_list:
  6.                         p.rect.x -= scroll
  7.  
  8.         # scroll the world backward
  9.         if player.rect.x <= backwardx:
  10.                 scroll = backwardx - player.rect.x
  11.                 player.rect.x = backwardx
  12.                 for p in plat_list:
  13.                         p.rect.x += scroll
  14.  
  15.         ## scrolling code above
  16.     world.blit(backdrop, backdropbox)
  17.     player.gravity() # check gravity
  18.     player.update()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

启动你的游戏,并尝试它。

 

Scrolling the world in Pygame

滚动像预期的一样工作,但是你可能注意到一个发生的小问题,当你滚动你的玩家和非玩家精灵周围的世界时:敌人精灵不随同世界滚动。除非你要你的敌人精灵要无休止地追逐你的玩家,你需要修改敌人代码,以便当你的玩家快速撤退时,敌人被留在后面。

敌人卷轴

在你的主循环中,你必须对卷轴平台为你的敌人的位置的应用相同的规则。因为你的游戏世界将(很可能)有不止一个敌人在其中,该规则应该被应用于你的敌人列表,而不是一个单独的敌人精灵。这是分组类似元素到列表中的优点之一。

前两行用于上下文注释,所以只需添加这两行后面的代码到你的主循环中:

  1.     # scroll the world forward
  2.     if player.rect.x >= forwardx:
  3.         scroll = player.rect.x - forwardx
  4.         player.rect.x = forwardx
  5.         for p in plat_list:
  6.             p.rect.x -= scroll
  7.         for e in enemy_list:
  8.             e.rect.x -= scroll
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

来滚向另一个方向:

  1.     # scroll the world backward
  2.     if player.rect.x <= backwardx:
  3.         scroll = backwardx - player.rect.x
  4.         player.rect.x = backwardx
  5.         for p in plat_list:
  6.             p.rect.x += scroll
  7.         for e in enemy_list:
  8.             e.rect.x += scroll
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

再次启动游戏,看看发生什么。

这里是到目前为止你已经为这个 Python 平台所写所有的代码:

  1. #!/usr/bin/env python3
  2. # draw a world
  3. # add a player and player control
  4. # add player movement
  5. # add enemy and basic collision
  6. # add platform
  7. # add gravity
  8. # add jumping
  9. # add scrolling
  10.  
  11. # GNU All-Permissive License
  12. # Copying and distribution of this file, with or without modification,
  13. # are permitted in any medium without royalty provided the copyright
  14. # notice and this notice are preserved. This file is offered as-is,
  15. # without any warranty.
  16.  
  17. import pygame
  18. import sys
  19. import os
  20.  
  21. '''
  22. Objects
  23. '''
  24.  
  25. class Platform(pygame.sprite.Sprite):
  26. # x location, y location, img width, img height, img file
  27. def __init__(self,xloc,yloc,imgw,imgh,img):
  28. pygame.sprite.Sprite.__init__(self)
  29. self.image = pygame.image.load(os.path.join('images',img)).convert()
  30. self.image.convert_alpha()
  31. self.rect = self.image.get_rect()
  32. self.rect.y = yloc
  33. self.rect.x = xloc
  34.  
  35. class Player(pygame.sprite.Sprite):
  36. '''
  37. Spawn a player
  38. '''
  39. def __init__(self):
  40. pygame.sprite.Sprite.__init__(self)
  41. self.movex = 0
  42. self.movey = 0
  43. self.frame = 0
  44. self.health = 10
  45. self.collide_delta = 0
  46. self.jump_delta = 6
  47. self.score = 1
  48. self.images = []
  49. for i in range(1,9):
  50. img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
  51. img.convert_alpha()
  52. img.set_colorkey(ALPHA)
  53. self.images.append(img)
  54. self.image = self.images[0]
  55. self.rect = self.image.get_rect()
  56.  
  57. def jump(self,platform_list):
  58. self.jump_delta = 0
  59.  
  60. def gravity(self):
  61. self.movey += 3.2 # how fast player falls
  62. if self.rect.y > worldy and self.movey >= 0:
  63. self.movey = 0
  64. self.rect.y = worldy-ty
  65. def control(self,x,y):
  66. '''
  67. control player movement
  68. '''
  69. self.movex += x
  70. self.movey += y
  71. def update(self):
  72. '''
  73. Update sprite position
  74. '''
  75. self.rect.x = self.rect.x + self.movex
  76. self.rect.y = self.rect.y + self.movey
  77.  
  78. # moving left
  79. if self.movex < 0:
  80. self.frame += 1
  81. if self.frame > ani*3:
  82. self.frame = 0
  83. self.image = self.images[self.frame//ani]
  84.  
  85. # moving right
  86. if self.movex > 0:
  87. self.frame += 1
  88. if self.frame > ani*3:
  89. self.frame = 0
  90. self.image = self.images[(self.frame//ani)+4]
  91.  
  92. # collisions
  93. enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
  94. for enemy in enemy_hit_list:
  95. self.health -= 1
  96. #print(self.health)
  97.  
  98. plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
  99. for p in plat_hit_list:
  100. self.collide_delta = 0 # stop jumping
  101. self.movey = 0
  102. if self.rect.y > p.rect.y:
  103. self.rect.y = p.rect.y+ty
  104. else:
  105. self.rect.y = p.rect.y-ty
  106. ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
  107. for g in ground_hit_list:
  108. self.movey = 0
  109. self.rect.y = worldy-ty-ty
  110. self.collide_delta = 0 # stop jumping
  111. if self.rect.y > g.rect.y:
  112. self.health -=1
  113. print(self.health)
  114. if self.collide_delta < 6 and self.jump_delta < 6:
  115. self.jump_delta = 6*2
  116. self.movey -= 33 # how high to jump
  117. self.collide_delta += 6
  118. self.jump_delta += 6
  119. class Enemy(pygame.sprite.Sprite):
  120. '''
  121. Spawn an enemy
  122. '''
  123. def __init__(self,x,y,img):
  124. pygame.sprite.Sprite.__init__(self)
  125. self.image = pygame.image.load(os.path.join('images',img))
  126. self.movey = 0
  127. #self.image.convert_alpha()
  128. #self.image.set_colorkey(ALPHA)
  129. self.rect = self.image.get_rect()
  130. self.rect.x = x
  131. self.rect.y = y
  132. self.counter = 0
  133.  
  134. def move(self):
  135. '''
  136. enemy movement
  137. '''
  138. distance = 80
  139. speed = 8
  140.  
  141. self.movey += 3.2
  142. if self.counter >= 0 and self.counter <= distance:
  143. self.rect.x += speed
  144. elif self.counter >= distance and self.counter <= distance*2:
  145. self.rect.x -= speed
  146. else:
  147. self.counter = 0
  148. self.counter += 1
  149.  
  150. if not self.rect.y >= worldy-ty-ty:
  151. self.rect.y += self.movey
  152.  
  153. plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
  154. for p in plat_hit_list:
  155. self.movey = 0
  156. if self.rect.y > p.rect.y:
  157. self.rect.y = p.rect.y+ty
  158. else:
  159. self.rect.y = p.rect.y-ty
  160.  
  161. ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
  162. for g in ground_hit_list:
  163. self.rect.y = worldy-ty-ty
  164.  
  165. class Level():
  166. def bad(lvl,eloc):
  167. if lvl == 1:
  168. enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
  169. enemy_list = pygame.sprite.Group() # create enemy group
  170. enemy_list.add(enemy) # add enemy to group
  171. if lvl == 2:
  172. print("Level " + str(lvl) )
  173.  
  174. return enemy_list
  175.  
  176. def loot(lvl,lloc):
  177. print(lvl)
  178.  
  179. def ground(lvl,gloc,tx,ty):
  180. ground_list = pygame.sprite.Group()
  181. i=0
  182. if lvl == 1:
  183. while i < len(gloc):
  184. ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
  185. ground_list.add(ground)
  186. i=i+1
  187.  
  188. if lvl == 2:
  189. print("Level " + str(lvl) )
  190.  
  191. return ground_list
  192.  
  193. def platform(lvl,tx,ty):
  194. plat_list = pygame.sprite.Group()
  195. ploc = []
  196. i=0
  197. if lvl == 1:
  198. ploc.append((0,worldy-ty-128,3))
  199. ploc.append((300,worldy-ty-256,3))
  200. ploc.append((500,worldy-ty-128,4))
  201.  
  202. while i < len(ploc):
  203. j=0
  204. while j <= ploc[i][2]:
  205. plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
  206. plat_list.add(plat)
  207. j=j+1
  208. print('run' + str(i) + str(ploc[i]))
  209. i=i+1
  210.  
  211. if lvl == 2:
  212. print("Level " + str(lvl) )
  213.  
  214. return plat_list
  215.  
  216. '''
  217. Setup
  218. '''
  219. worldx = 960
  220. worldy = 720
  221.  
  222. fps = 40 # frame rate
  223. ani = 4 # animation cycles
  224. clock = pygame.time.Clock()
  225. pygame.init()
  226. main = True
  227.  
  228. BLUE = (25,25,200)
  229. BLACK = (23,23,23 )
  230. WHITE = (254,254,254)
  231. ALPHA = (0,255,0)
  232.  
  233. world = pygame.display.set_mode([worldx,worldy])
  234. backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
  235. backdropbox = world.get_rect()
  236. player = Player() # spawn player
  237. player.rect.x = 0
  238. player.rect.y = 0
  239. player_list = pygame.sprite.Group()
  240. player_list.add(player)
  241. steps = 10
  242. forwardx = 600
  243. backwardx = 230
  244.  
  245. eloc = []
  246. eloc = [200,20]
  247. gloc = []
  248. #gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
  249. tx = 64 #tile size
  250. ty = 64 #tile size
  251.  
  252. i=0
  253. while i <= (worldx/tx)+tx:
  254. gloc.append(i*tx)
  255. i=i+1
  256.  
  257. enemy_list = Level.bad( 1, eloc )
  258. ground_list = Level.ground( 1,gloc,tx,ty )
  259. plat_list = Level.platform( 1,tx,ty )
  260.  
  261. '''
  262. Main loop
  263. '''
  264. while main == True:
  265. for event in pygame.event.get():
  266. if event.type == pygame.QUIT:
  267. pygame.quit(); sys.exit()
  268. main = False
  269.  
  270. if event.type == pygame.KEYDOWN:
  271. if event.key == pygame.K_LEFT or event.key == ord('a'):
  272. print("LEFT")
  273. player.control(-steps,0)
  274. if event.key == pygame.K_RIGHT or event.key == ord('d'):
  275. print("RIGHT")
  276. player.control(steps,0)
  277. if event.key == pygame.K_UP or event.key == ord('w'):
  278. print('jump')
  279.  
  280. if event.type == pygame.KEYUP:
  281. if event.key == pygame.K_LEFT or event.key == ord('a'):
  282. player.control(steps,0)
  283. if event.key == pygame.K_RIGHT or event.key == ord('d'):
  284. player.control(-steps,0)
  285. if event.key == pygame.K_UP or event.key == ord('w'):
  286. player.jump(plat_list)
  287.  
  288. if event.key == ord('q'):
  289. pygame.quit()
  290. sys.exit()
  291. main = False
  292.  
  293. # scroll the world forward
  294. if player.rect.x >= forwardx:
  295. scroll = player.rect.x - forwardx
  296. player.rect.x = forwardx
  297. for p in plat_list:
  298. p.rect.x -= scroll
  299. for e in enemy_list:
  300. e.rect.x -= scroll
  301. # scroll the world backward
  302. if player.rect.x <= backwardx:
  303. scroll = backwardx - player.rect.x
  304. player.rect.x = backwardx
  305. for p in plat_list:
  306. p.rect.x += scroll
  307. for e in enemy_list:
  308. e.rect.x += scroll
  309.  
  310. world.blit(backdrop, backdropbox)
  311. player.gravity() # check gravity
  312. player.update()
  313. player_list.draw(world) #refresh player position
  314. enemy_list.draw(world) # refresh enemies
  315. ground_list.draw(world) # refresh enemies
  316. plat_list.draw(world) # refresh platforms
  317. for e in enemy_list:
  318. e.move()
  319. pygame.display.flip()
  320. clock.tick(fps)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.