在你的Python平台类游戏中放一些奖励

开发 后端
这部分是关于在使用 Python 的 Pygame 模块开发的视频游戏总给你的玩家提供收集的宝物和经验值的内容。

在你的Python平台类游戏中放一些奖励

这部分是关于在使用 Python 的 Pygame 模块开发的视频游戏总给你的玩家提供收集的宝物和经验值的内容。

这是正在进行的关于使用 Python 3Pygame 模块创建视频游戏的系列文章的第十部分。以前的文章有:

如果你已经阅读了本系列的前几篇文章,那么你已经了解了编写游戏的所有基础知识。现在你可以在这些基础上,创造一个全功能的游戏。当你第一次学习时,遵循本系列代码示例,这样的“用例”是有帮助的,但是,用例也会约束你。现在是时候运用你学到的知识,以新的方式应用它们了。

如果说,说起来容易做起来难,这篇文章展示了一个如何将你已经了解的内容用于新目的的例子中。具体来说,就是它涵盖了如何使用你以前的课程中已经了解到的来实现奖励系统。

在大多数电子游戏中,你有机会在游戏世界中获得“奖励”或收集到宝物和其他物品。奖励通常会增加你的分数或者你的生命值,或者为你的下一次任务提供信息。

游戏中包含的奖励类似于编程平台。像平台一样,奖励没有用户控制,随着游戏世界的滚动进行,并且必须检查与玩家的碰撞。

创建奖励函数

奖励和平台非常相似,你甚至不需要一个奖励的类。你可以重用 Platform 类,并将结果称为“奖励”。

由于奖励类型和位置可能因关卡不同而不同,如果你还没有,请在你的 Level 中创建一个名为 loot 的新函数。因为奖励物品不是平台,你也必须创建一个新的 loot_list 组,然后添加奖励物品。与平台、地面和敌人一样,该组用于检查玩家碰撞:

  1. def loot(lvl,lloc):
  2. if lvl == 1:
  3. loot_list = pygame.sprite.Group()
  4. loot = Platform(300,ty*7,tx,ty, 'loot_1.png')
  5. loot_list.add(loot)
  6.  
  7. if lvl == 2:
  8. print(lvl)
  9.  
  10. return loot_list

你可以随意添加任意数量的奖励对象;记住把每一个都加到你的奖励清单上。Platform 类的参数是奖励图标的 X 位置、Y 位置、宽度和高度(通常让你的奖励精灵保持和所有其他方块一样的大小最为简单),以及你想要用作的奖励的图片。奖励的放置可以和贴图平台一样复杂,所以使用创建关卡时需要的关卡设计文档。

在脚本的设置部分调用新的奖励函数。在下面的代码中,前三行是上下文,所以只需添加第四行:

  1. enemy_list = Level.bad( 1, eloc )
  2. ground_list = Level.ground( 1,gloc,tx,ty )
  3. plat_list = Level.platform( 1,tx,ty )
  4. loot_list = Level.loot(1,tx,ty)

正如你现在所知道的,除非你把它包含在你的主循环中,否则奖励不会被显示到屏幕上。将下面代码示例的最后一行添加到循环中:

  1.     enemy_list.draw(world)
  2.     ground_list.draw(world)
  3.     plat_list.draw(world)
  4.     loot_list.draw(world)

启动你的游戏看看会发生什么。

 

Loot in Python platformer

你的奖励将会显示出来,但是当你的玩家碰到它们时,它们不会做任何事情,当你的玩家经过它们时,它们也不会滚动。接下来解决这些问题。

滚动奖励

像平台一样,当玩家在游戏世界中移动时,奖励必须滚动。逻辑与平台滚动相同。要向前滚动奖励物品,添加最后两行:

  1.         for e in enemy_list:
  2.             e.rect.x -= scroll
  3.         for l in loot_list:
  4.             l.rect.x -= scroll

要向后滚动,请添加最后两行:

  1.         for e in enemy_list:
  2.             e.rect.x += scroll
  3.         for l in loot_list:
  4.             l.rect.x += scroll

再次启动你的游戏,看看你的奖励物品现在表现得像在游戏世界里一样了,而不是仅仅画在上面。

检测碰撞

就像平台和敌人一样,你可以检查奖励物品和玩家之间的碰撞。逻辑与其他碰撞相同,除了撞击不会(必然)影响重力或生命值。取而代之的是,命中会导致奖励物品会消失并增加玩家的分数。

当你的玩家触摸到一个奖励对象时,你可以从 loot_list 中移除该对象。这意味着当你的主循环在 loot_list 中重绘所有奖励物品时,它不会重绘那个特定的对象,所以看起来玩家已经获得了奖励物品。

Player 类的 update 函数中的平台碰撞检测之上添加以下代码(最后一行仅用于上下文):

  1.                 loot_hit_list = pygame.sprite.spritecollide(self, loot_list, False)
  2.                 for loot in loot_hit_list:
  3.                         loot_list.remove(loot)
  4.                         self.score += 1
  5.                 print(self.score)
  6.  
  7.         plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)

当碰撞发生时,你不仅要把奖励从它的组中移除,还要给你的玩家一个分数提升。你还没有创建分数变量,所以请将它添加到你的玩家属性中,该属性是在 Player 类的 __init__ 函数中创建的。在下面的代码中,前两行是上下文,所以只需添加分数变量:

  1.         self.frame = 0
  2.         self.health = 10
  3.         self.score = 0

当在主循环中调用 update 函数时,需要包括 loot_list

  1.         player.gravity()
  2.         player.update()

如你所见,你已经掌握了所有的基本知识。你现在要做的就是用新的方式使用你所知道的。

在下一篇文章中还有一些提示,但是与此同时,用你学到的知识来制作一些简单的单关卡游戏。限制你试图创造的东西的范围是很重要的,这样你就不会埋没自己。这也使得最终的成品看起来和感觉上更容易完成。

以下是迄今为止你为这个 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. loot_hit_list = pygame.sprite.spritecollide(self, loot_list, False)
  99. for loot in loot_hit_list:
  100. loot_list.remove(loot)
  101. self.score += 1
  102. print(self.score)
  103.  
  104. plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
  105. for p in plat_hit_list:
  106. self.collide_delta = 0 # stop jumping
  107. self.movey = 0
  108. if self.rect.y > p.rect.y:
  109. self.rect.y = p.rect.y+ty
  110. else:
  111. self.rect.y = p.rect.y-ty
  112. ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
  113. for g in ground_hit_list:
  114. self.movey = 0
  115. self.rect.y = worldy-ty-ty
  116. self.collide_delta = 0 # stop jumping
  117. if self.rect.y > g.rect.y:
  118. self.health -=1
  119. print(self.health)
  120. if self.collide_delta < 6 and self.jump_delta < 6:
  121. self.jump_delta = 6*2
  122. self.movey -= 33 # how high to jump
  123. self.collide_delta += 6
  124. self.jump_delta += 6
  125. class Enemy(pygame.sprite.Sprite):
  126. '''
  127. Spawn an enemy
  128. '''
  129. def __init__(self,x,y,img):
  130. pygame.sprite.Sprite.__init__(self)
  131. self.image = pygame.image.load(os.path.join('images',img))
  132. self.movey = 0
  133. #self.image.convert_alpha()
  134. #self.image.set_colorkey(ALPHA)
  135. self.rect = self.image.get_rect()
  136. self.rect.x = x
  137. self.rect.y = y
  138. self.counter = 0
  139.  
  140. def move(self):
  141. '''
  142. enemy movement
  143. '''
  144. distance = 80
  145. speed = 8
  146.  
  147. self.movey += 3.2
  148. if self.counter >= 0 and self.counter <= distance:
  149. self.rect.x += speed
  150. elif self.counter >= distance and self.counter <= distance*2:
  151. self.rect.x -= speed
  152. else:
  153. self.counter = 0
  154. self.counter += 1
  155.  
  156. if not self.rect.y >= worldy-ty-ty:
  157. self.rect.y += self.movey
  158.  
  159. plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
  160. for p in plat_hit_list:
  161. self.movey = 0
  162. if self.rect.y > p.rect.y:
  163. self.rect.y = p.rect.y+ty
  164. else:
  165. self.rect.y = p.rect.y-ty
  166.  
  167. ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
  168. for g in ground_hit_list:
  169. self.rect.y = worldy-ty-ty
  170.  
  171. class Level():
  172. def bad(lvl,eloc):
  173. if lvl == 1:
  174. enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
  175. enemy_list = pygame.sprite.Group() # create enemy group
  176. enemy_list.add(enemy) # add enemy to group
  177. if lvl == 2:
  178. print("Level " + str(lvl) )
  179.  
  180. return enemy_list
  181.  
  182. def loot(lvl,tx,ty):
  183. if lvl == 1:
  184. loot_list = pygame.sprite.Group()
  185. loot = Platform(200,ty*7,tx,ty, 'loot_1.png')
  186. loot_list.add(loot)
  187.  
  188. if lvl == 2:
  189. print(lvl)
  190.  
  191. return loot_list
  192.  
  193. def ground(lvl,gloc,tx,ty):
  194. ground_list = pygame.sprite.Group()
  195. i=0
  196. if lvl == 1:
  197. while i < len(gloc):
  198. ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
  199. ground_list.add(ground)
  200. i=i+1
  201.  
  202. if lvl == 2:
  203. print("Level " + str(lvl) )
  204.  
  205. return ground_list
  206.  
  207. def platform(lvl,tx,ty):
  208. plat_list = pygame.sprite.Group()
  209. ploc = []
  210. i=0
  211. if lvl == 1:
  212. ploc.append((20,worldy-ty-128,3))
  213. ploc.append((300,worldy-ty-256,3))
  214. ploc.append((500,worldy-ty-128,4))
  215.  
  216. while i < len(ploc):
  217. j=0
  218. while j <= ploc[i][2]:
  219. plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
  220. plat_list.add(plat)
  221. j=j+1
  222. print('run' + str(i) + str(ploc[i]))
  223. i=i+1
  224.  
  225. if lvl == 2:
  226. print("Level " + str(lvl) )
  227.  
  228. return plat_list
  229.  
  230. '''
  231. Setup
  232. '''
  233. worldx = 960
  234. worldy = 720
  235.  
  236. fps = 40 # frame rate
  237. ani = 4 # animation cycles
  238. clock = pygame.time.Clock()
  239. pygame.init()
  240. main = True
  241.  
  242. BLUE = (25,25,200)
  243. BLACK = (23,23,23 )
  244. WHITE = (254,254,254)
  245. ALPHA = (0,255,0)
  246.  
  247. world = pygame.display.set_mode([worldx,worldy])
  248. backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
  249. backdropbox = world.get_rect()
  250. player = Player() # spawn player
  251. player.rect.x = 0
  252. player.rect.y = 0
  253. player_list = pygame.sprite.Group()
  254. player_list.add(player)
  255. steps = 10
  256. forwardx = 600
  257. backwardx = 230
  258.  
  259. eloc = []
  260. eloc = [200,20]
  261. gloc = []
  262. #gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
  263. tx = 64 #tile size
  264. ty = 64 #tile size
  265.  
  266. i=0
  267. while i <= (worldx/tx)+tx:
  268. gloc.append(i*tx)
  269. i=i+1
  270.  
  271. enemy_list = Level.bad( 1, eloc )
  272. ground_list = Level.ground( 1,gloc,tx,ty )
  273. plat_list = Level.platform( 1,tx,ty )
  274. loot_list = Level.loot(1,tx,ty)
  275.  
  276. '''
  277. Main loop
  278. '''
  279. while main == True:
  280. for event in pygame.event.get():
  281. if event.type == pygame.QUIT:
  282. pygame.quit(); sys.exit()
  283. main = False
  284.  
  285. if event.type == pygame.KEYDOWN:
  286. if event.key == pygame.K_LEFT or event.key == ord('a'):
  287. print("LEFT")
  288. player.control(-steps,0)
  289. if event.key == pygame.K_RIGHT or event.key == ord('d'):
  290. print("RIGHT")
  291. player.control(steps,0)
  292. if event.key == pygame.K_UP or event.key == ord('w'):
  293. print('jump')
  294.  
  295. if event.type == pygame.KEYUP:
  296. if event.key == pygame.K_LEFT or event.key == ord('a'):
  297. player.control(steps,0)
  298. if event.key == pygame.K_RIGHT or event.key == ord('d'):
  299. player.control(-steps,0)
  300. if event.key == pygame.K_UP or event.key == ord('w'):
  301. player.jump(plat_list)
  302.  
  303. if event.key == ord('q'):
  304. pygame.quit()
  305. sys.exit()
  306. main = False
  307.  
  308. # scroll the world forward
  309. if player.rect.x >= forwardx:
  310. scroll = player.rect.x - forwardx
  311. player.rect.x = forwardx
  312. for p in plat_list:
  313. p.rect.x -= scroll
  314. for e in enemy_list:
  315. e.rect.x -= scroll
  316. for l in loot_list:
  317. l.rect.x -= scroll
  318. # scroll the world backward
  319. if player.rect.x <= backwardx:
  320. scroll = backwardx - player.rect.x
  321. player.rect.x = backwardx
  322. for p in plat_list:
  323. p.rect.x += scroll
  324. for e in enemy_list:
  325. e.rect.x += scroll
  326. for l in loot_list:
  327. l.rect.x += scroll
  328.  
  329. world.blit(backdrop, backdropbox)
  330. player.gravity() # check gravity
  331. player.update()
  332. player_list.draw(world) #refresh player position
  333. enemy_list.draw(world) # refresh enemies
  334. ground_list.draw(world) # refresh enemies
  335. plat_list.draw(world) # refresh platforms
  336. loot_list.draw(world) # refresh loot
  337.  
  338. for e in enemy_list:
  339. e.move()
  340. pygame.display.flip()
  341. clock.tick(fps)

 

责任编辑:庞桂玉 来源: Linux中国
相关推荐

2019-05-27 15:00:17

Pygame游戏平台

2020-01-14 12:05:20

Python游戏引力

2020-11-30 14:00:16

Python游戏编程语言

2019-05-21 13:55:22

Python编程语言游戏

2011-11-30 15:57:18

2009-03-13 09:31:03

.NET整合分布式应用

2013-08-20 13:40:04

独立游戏开发者移动应用PR经验移动应用营销推广

2019-05-21 21:36:42

Python编程语言游戏

2011-07-29 09:33:21

iPhone 设计

2013-04-28 09:44:44

2022-12-22 10:55:24

vivo代码

2015-09-24 14:56:17

变革平台开发云开发

2011-08-19 14:12:39

Web

2010-02-01 14:48:43

2009-05-31 09:45:04

游戏开发美工设计师

2023-09-04 16:55:18

2017-11-29 18:52:13

Python新手编码建议

2010-03-11 18:57:17

Python脚本

2015-08-11 08:51:40

游戏死亡

2019-06-13 18:50:47

支付平台架构设计
点赞
收藏

51CTO技术栈公众号