• 【Pygame实战】只有一个币,投《勇者大冒险》还是《街霸》?(经典复刻,谁的青春回来了?)


    导语

    不知道大家有没有这样的经历,在学校电脑课上打开一个叫做4399的神秘网站,然后精心挑选

    一款小游戏在老师讲课时默默玩耍。

    这种惊心动魄的感觉像极了偷情(滑稽.jpg),而《黄金矿工》、《暴打小朋友》、《森林冰

    火人》、《闪翼拳皇》等等小游戏就是我在电脑课上的情人,其中一款叫做《合金弹头》的游

    戏让我印象尤为深刻。​

    所有文章完整的素材+源码都在👇👇

    粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。

    它最让我感到兴奋的是可以切换各种枪械,那种随着战斗的进行鸟枪换炮的成就感是无与伦比

    的,也是这款游戏让我第一次感受到了突突突的快感。

    最近跟着这款游戏仿造了一款《勇者大冒险》游戏,这是一款横版射击游戏,一上手后我就感

    受到了当初玩合金弹头的味道,小编的青春回来了。好啦,话不多说了哈,我们正式开干叭👇

    正文

    一、运行环境

    小编使用的环境:Python3、Pycharm社区版、Pygame模块。内置模块 你安装 好python环

    境就可以了。

     模块安装:pip install -i https://pypi.douban.com/simple/ +pygame

    二、素材(图片等)

    这款《勇者大冒险》大型游戏有超多的图片素材的下面只是小部分截图太大了。

    当然要有音乐的啦👇

    ​三、代码展示

    1)boss主程序py

    1. # coding: utf-8
    2. import pygame
    3. import sys
    4. from random import randint
    5. from pygame.sprite import Sprite
    6. from pygame.sprite import Group
    7. from bullet import *
    8. # 控制怪物动画的速度
    9. MAN_PAO_SPEED_THRESHOLD = 5
    10. # 定义代表怪物类型的常量(如果程序还需要增加更多怪物,只需在此处添加常量即可)
    11. TYPE_BOSS = 2
    12. class Boss(Sprite):
    13. boss_produce = True
    14. def __init__ (self, view_manager):
    15. super().__init__()
    16. # 定义子弹爆炸时的帧数
    17. self.bullet_number=0
    18. # 定义boss未被加载初始未true
    19. # boss血量
    20. self.hp=20
    21. # 定义怪物X、Y坐标的属性
    22. self.x = 0
    23. self.y = 0
    24. # 定义怪物是否已经死亡的旗标
    25. self.is_die = False
    26. # 绘制怪物图片的左上角的X坐标
    27. self.start_x = 0
    28. # 绘制怪物图片的左上角的Y坐标
    29. self.start_y = 0
    30. # 绘制怪物图片的右下角的X坐标
    31. self.end_x = 0
    32. # 绘制怪物图片的右下角的Y坐标
    33. self.end_y = 0
    34. # 该变量控制用于控制动画刷新的速度
    35. self.draw_count = 0
    36. # 定义当前正在绘制怪物动画的第几帧的变量
    37. self.draw_index = 0
    38. # 用于记录死亡动画只绘制一次,不需要重复绘制
    39. # 每当怪物死亡时,该变量会被初始化为等于死亡动画的总帧数
    40. # 当怪物的死亡动画帧播放完成时,该变量的值变为0。
    41. self.die_max_draw_count = sys.maxsize
    42. # 定义怪物射出的子弹
    43. self.bullet_list = Group()
    44. # 定义Boss速度的初始值
    45. self.SPEED=5
    46. # -------下面代码初始化BOSS X、Y坐标------
    47. self.y = 0
    48. self.x = view_manager.screen_width/2
    49. # 画怪物的方法
    50. def draw(self, screen, view_manager,player):
    51. self.draw_anim(screen, view_manager, view_manager.boss_images
    52. if not self.is_die else view_manager.boss_die_images,player)
    53. # 根据怪物的动画帧图片来绘制怪物动画
    54. def draw_anim(self, screen, view_manager, bitmap_arr,player):
    55. # 如果怪物已经死,且没有播放过死亡动画
    56. #(self.die_max_draw_count等于初始值表明未播放过死亡动画)
    57. if self.is_die and self.die_max_draw_count == sys.maxsize:
    58. # 将die_max_draw_count设置与死亡动画的总帧数相等
    59. self.die_max_draw_count = len(bitmap_arr) # ⑤
    60. self.draw_index %= len(bitmap_arr)
    61. # 获取当前绘制的动画帧对应的位图
    62. bitmap = bitmap_arr[self.draw_index] # ①
    63. if bitmap == None:
    64. return
    65. # 对绘制怪物动画帧位图的X坐标进行微调
    66. self.x -=self.SPEED
    67. # 如果到达屏幕边界则反方向行进
    68. if self.x <=-376 or self.x >= view_manager.screen_width+120:
    69. self.SPEED = -self.SPEED
    70. # 对绘制怪物动画帧位图的Y坐标进行微调
    71. draw_y = self.y
    72. # 画怪物动画帧的位图
    73. if self.SPEED>0:
    74. bitmap=pygame.transform.flip(bitmap,True,False)
    75. screen.blit(bitmap, (self.x, draw_y))
    76. self.start_x = self.x
    77. self.start_y = draw_y
    78. self.end_x = self.start_x + bitmap.get_width()
    79. self.end_y = self.start_y + bitmap.get_height()
    80. self.draw_count += 1
    81. # 控制人、飞机的发射子弹的速度
    82. if self.draw_count >= TYPE_BOSS: # ③
    83. # boss只在最后一帧才发射子弹
    84. if self.draw_index == len(bitmap_arr)-1 and self.x%40==0:
    85. self.add_bullet()
    86. self.draw_index += 1 # ②
    87. self.draw_count = 0 # ④
    88. # 每播放死亡动画的一帧,self.die_max_draw_count减1。
    89. # 当self.die_max_draw_count等于0时,表明死亡动画播放完成。
    90. if self.is_die:
    91. self.die_max_draw_count -= 1 # ⑥
    92. # 如果boss死亡 加载win的画面
    93. if self.die_max_draw_count<=0:
    94. screen.blit(view_manager.win[0], (0, 0))
    95. pygame.display.flip()
    96. while True:
    97. for event in pygame.event.get():
    98. if event==pygame.QUIT:
    99. pygame.quit()
    100. sys.exit()
    101. # 绘制子弹
    102. self.draw_bullets(screen, view_manager,player)
    103. # 判断怪物是否被子弹打中的方法
    104. def is_hurt(self, x, y):
    105. return self.start_x < x < self.end_x and self.start_y < y < self.end_y
    106. # 此boos对应的子弹是6
    107. def bullet_type(self):
    108. return 6
    109. # 定义发射子弹的方法
    110. def add_bullet(self):
    111. # 如果没有子弹
    112. if self.bullet_type() <= 0:
    113. return
    114. # 计算子弹的X、Y坐标
    115. draw_x = self.x+30
    116. draw_y = self.y+120
    117. # 创建子弹对象,由于这个boos是从上往下发射子弹所以不需要翻转图片这里pdir参数给以个3让他不执行翻转
    118. # 让飞机只有从左往右飞时发射导弹
    119. if self.SPEED<0:
    120. bullet = Bullet(self.bullet_type(), draw_x, draw_y, 3)
    121. # 将子弹添加到该怪物发射的子弹Group中
    122. self.bullet_list.add(bullet)
    123. # 更新所有子弹的位置:将所有子弹的X坐标减少shift距离(子弹左移)
    124. def update_shift(self, shift):
    125. self.y-=shift
    126. for bullet in self.bullet_list:
    127. if bullet != None:
    128. bullet.y = self.y
    129. # 绘制子弹的方法
    130. def draw_bullets(self, screen, view_manager,player) :
    131. # 遍历该怪物发射的所有子弹
    132. for bullet in self.bullet_list.copy():
    133. # 如果子弹已经越过屏幕
    134. if bullet.boss_bang:
    135. # 删除已经移出屏幕的子弹
    136. self.bullet_list.remove(bullet)
    137. # 绘制所有子弹
    138. for bullet in self.bullet_list.sprites():
    139. if bullet.y<= view_manager.screen_height-250:
    140. # 获取子弹对应的位图
    141. bitmap = bullet.bitmap(view_manager)
    142. # 绘制子弹的位图
    143. screen.blit(bitmap, (bullet.x, bullet.y))
    144. bullet.move(True)
    145. # 子弹移动
    146. if bitmap == None:
    147. continue
    148. elif len(self.bullet_list.sprites())>1:
    149. self.bullet_number+=1
    150. if self.bullet_number%5==0 and bullet.bullet_bang>0:
    151. bullet.bullet_bang-=1
    152. self.check_bullet(player)
    153. bitmap = view_manager.boss_die_images[bullet.bullet_bang]
    154. if bullet.bullet_bang==0:
    155. bullet.boss_bang=True
    156. # 绘制子弹的位图
    157. screen.blit(bitmap, (bullet.x, bullet.y))
    158. # 判断子弹是否与玩家控制的角色碰撞(判断子弹是否打中角色)
    159. def check_bullet(self, player):
    160. # 遍历所有子弹
    161. for bullet in self.bullet_list.copy():
    162. if bullet == None or not bullet.is_effect:
    163. continue
    164. # 如果玩家控制的角色被子弹打到
    165. if player.is_hurt(bullet.x-20, bullet.x+120, bullet.y, bullet.y+80):
    166. # 子弹设为无效
    167. bullet.isEffect = False
    168. player.hp = player.hp - 15
    169. # 删除已经击中玩家控制的角色的子弹
    170. self.bullet_list.remove(bullet)

    2)玩家设置

    1. # coding: utf-8
    2. import pygame
    3. import sys
    4. from random import randint
    5. from pygame.sprite import Sprite
    6. from pygame.sprite import Group
    7. import pygame.font
    8. from bullet import *
    9. import monster_manager as mm
    10. # 定义角色的最高生命值
    11. MAX_HP = 9999999999999999999
    12. # 定义控制角色动作的常量
    13. # 此处只控制该角色包含站立、跑、跳等动作
    14. ACTION_STAND_RIGHT = 1
    15. ACTION_STAND_LEFT = 2
    16. ACTION_RUN_RIGHT = 3
    17. ACTION_RUN_LEFT = 4
    18. ACTION_JUMP_RIGHT = 5
    19. ACTION_JUMP_LEFT = 6
    20. # 定义角色向右移动的常量
    21. DIR_RIGHT = 1
    22. # 定义角色向左移动的常量
    23. DIR_LEFT = 2
    24. # 定义控制角色移动的常量
    25. # 此处控制该角色只包含站立、向右移动、向左移动三种移动方式
    26. MOVE_STAND = 0
    27. MOVE_RIGHT = 1
    28. MOVE_LEFT = 2
    29. MAX_LEFT_SHOOT_TIME = 6
    30. class Player(Sprite):
    31. def __init__(self, view_manager, name, hp):
    32. super().__init__()
    33. self.boos_time_updata_y = False
    34. self.bullet_clear = 0
    35. # Boos时间时地图不在跟随移动角色可以自由移动,规定x轴,y轴坐标
    36. self.boss_time_move_x=0
    37. self.boss_time_move_y=0
    38. # BOSS时间
    39. self.pesses_boss_time=False# BOSS时间
    40. self.name = name # 保存角色名字的成员变量
    41. self.hp = hp # 保存角色生命值的成员变量
    42. self.view_manager = view_manager
    43. # 保存角色所使用枪的类型(以后可考虑让角色能更换不同的枪)
    44. self.gun = 0
    45. # 保存角色当前动作的成员变量(默认向右站立)
    46. self.action = ACTION_STAND_RIGHT
    47. # 代表角色X坐标的属性
    48. self._x = -1
    49. # 代表角色Y坐标的属性
    50. self.y = -1
    51. # 保存角色射出的所有子弹
    52. self.bullet_list = Group()
    53. # 保存角色移动方式的成员变量
    54. self.move = MOVE_STAND
    55. # 控制射击状态的保留计数器
    56. # 每当用户发射一枪时,left_shoot_time会被设为MAX_LEFT_SHOOT_TIME,然后递减
    57. # 只有当left_shoot_time变为0时,用户才能发射下一枪
    58. self.left_shoot_time = 0
    59. # 保存角色是否跳动的属性
    60. self._is_jump = False
    61. # 保存角色是否跳到最高处的成员变量
    62. self.is_jump_max = False
    63. # 控制跳到最高处的停留时间
    64. self.jump_stop_count = 0
    65. # 当前正在绘制角色脚部动画的第几帧
    66. self.index_leg = 0
    67. # 当前正在绘制角色头部动画的第几帧
    68. self.index_head = 0
    69. # 当前绘制头部图片的X坐标
    70. self.current_head_draw_x = 0
    71. # 当前绘制头部图片的Y坐标
    72. self.current_head_draw_y = 0
    73. # 当前正在画的脚部动画帧的图片
    74. self.current_leg_bitmap = None
    75. # 当前正在画的头部动画帧的图片
    76. self.current_head_bitmap = None
    77. # 该变量控制用于控制动画刷新的速度
    78. self.draw_count = 0
    79. # 加载中文字体
    80. self.font = pygame.font.Font('images/msyh.ttf', 20)
    81. # 计算该角色当前方向:action成员变量为奇数代表向右
    82. def get_dir(self):
    83. return DIR_RIGHT if self.action % 2 == 1 else DIR_LEFT
    84. def get_x(self):
    85. return self._x
    86. def set_x(self, x_val):
    87. self._x = x_val % (self.view_manager.map.get_width() +
    88. self.view_manager.X_DEFAULT)
    89. # 如果角色移动到屏幕最左边
    90. if self._x < self.view_manager.X_DEFAULT:
    91. self._x = self.view_manager.X_DEFAULT
    92. x = property(get_x, set_x)
    93. def get_is_jump(self):
    94. return self._is_jump
    95. def set_is_jump(self, jump_val):
    96. self._is_jump = jump_val
    97. self.jump_stop_count = 6
    98. is_jump = property(get_is_jump, set_is_jump)
    99. # 返回该角色在游戏界面上的位移
    100. def shift(self):
    101. if self.x <= 0 or self.y <= 0:
    102. self.init_position()
    103. return self.view_manager.X_DEFAULT - self.x
    104. # 判断角色是否已经死亡
    105. def is_die(self):
    106. return self.hp <= 0
    107. # 初始化角色的初始化位置,角色能跳的最大高度
    108. def init_position(self):
    109. self.x = self.view_manager.screen_width * 15 / 100
    110. self.y = self.view_manager.screen_height * 75 / 100
    111. # 画角色的方法
    112. def draw(self, screen):
    113. if not self.pesses_boss_time:
    114. # 绘制角色向右站立的动画图片
    115. if self.action == ACTION_STAND_RIGHT:
    116. self.draw_anim(screen, self.view_manager.leg_stand_images,
    117. self.view_manager.head_stand_images, DIR_RIGHT)
    118. # 绘制角色向左站立的动画图片
    119. elif self.action == ACTION_STAND_LEFT:
    120. self.draw_anim(screen, self.view_manager.leg_stand_images,
    121. self.view_manager.head_stand_images, DIR_LEFT)
    122. # 绘制角色向右跑动的动画图片
    123. elif self.action == ACTION_RUN_RIGHT:
    124. self.draw_anim(screen, self.view_manager.leg_run_images,
    125. self.view_manager.head_run_images, DIR_RIGHT)
    126. # 绘制角色向左跑动的动画图片
    127. elif self.action == ACTION_RUN_LEFT:
    128. self.draw_anim(screen, self.view_manager.leg_run_images,
    129. self.view_manager.head_run_images, DIR_LEFT)
    130. # 绘制角色向右跳动的动画图片
    131. elif self.action == ACTION_JUMP_RIGHT:
    132. self.draw_anim(screen, self.view_manager.leg_jump_images,
    133. self.view_manager.head_jump_images, DIR_RIGHT)
    134. # 绘制角色向左跳动的动画图片
    135. elif self.action == ACTION_JUMP_LEFT:
    136. self.draw_anim(screen, self.view_manager.leg_jump_images,
    137. self.view_manager.head_jump_images, DIR_LEFT)
    138. else:
    139. # 绘制角色向右站立的动画图片
    140. if self.action == ACTION_STAND_RIGHT:
    141. self.draw_anim(screen, self.view_manager.leg_stand_images,
    142. self.view_manager.look_up_images, DIR_RIGHT)
    143. # 绘制角色向左站立的动画图片
    144. elif self.action == ACTION_STAND_LEFT:
    145. self.draw_anim(screen, self.view_manager.leg_stand_images,
    146. self.view_manager.look_up_images, DIR_LEFT)
    147. # 绘制角色向右跑动的动画图片
    148. elif self.action == ACTION_RUN_RIGHT:
    149. self.draw_anim(screen, self.view_manager.leg_run_images,
    150. self.view_manager.look_up_images, DIR_RIGHT)
    151. # 绘制角色向左跑动的动画图片
    152. elif self.action == ACTION_RUN_LEFT:
    153. self.draw_anim(screen, self.view_manager.leg_run_images,
    154. self.view_manager.look_up_images, DIR_LEFT)
    155. # 绘制角色向右跳动的动画图片
    156. elif self.action == ACTION_JUMP_RIGHT:
    157. self.draw_anim(screen, self.view_manager.leg_jump_images,
    158. self.view_manager.look_up_images, DIR_RIGHT)
    159. # 绘制角色向左跳动的动画图片
    160. elif self.action == ACTION_JUMP_LEFT:
    161. self.draw_anim(screen, self.view_manager.leg_jump_images,
    162. self.view_manager.look_up_images, DIR_LEFT)
    163. # 绘制角色的动画帧
    164. def draw_anim(self, screen, leg_arr, head_arr_from, pdir):
    165. head_arr = head_arr_from
    166. if not self.pesses_boss_time:
    167. # 射击状态停留次数每次减1
    168. if self.left_shoot_time > 0 :
    169. head_arr = self.view_manager.head_shoot_images
    170. self.left_shoot_time -= 1
    171. else:
    172. head_arr = self.view_manager.head_stand_images
    173. self.left_shoot_time -= 1
    174. else:
    175. # 射击状态停留次数每次减1
    176. if self.left_shoot_time > 0:
    177. head_arr = self.view_manager.look_up_shoot_images
    178. self.left_shoot_time -= 1
    179. else:
    180. head_arr = self.view_manager.look_up_images
    181. self.left_shoot_time -= 1
    182. self.index_leg %= len(leg_arr)
    183. self.index_head %= len(head_arr)
    184. # 先画脚
    185. bitmap = leg_arr[self.index_leg]
    186. draw_x = self.view_manager.X_DEFAULT
    187. draw_y = self.y - bitmap.get_height()
    188. if self.pesses_boss_time:
    189. draw_x=self.boss_time_move_x
    190. # draw_y=self.y
    191. # 根据角色方向判断是否需要翻转图片
    192. if pdir == DIR_RIGHT:
    193. # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
    194. bitmap_mirror = pygame.transform.flip(bitmap, True, False)
    195. screen.blit(bitmap_mirror, (draw_x, draw_y))
    196. else:
    197. screen.blit(bitmap, (draw_x, draw_y))
    198. self.current_leg_bitmap = bitmap
    199. # 再画头
    200. bitmap2 = head_arr[self.index_head]
    201. draw_x -= (bitmap2.get_width() - bitmap.get_width() >> 1)
    202. if self.action == ACTION_STAND_LEFT:
    203. draw_x += 6
    204. draw_y = draw_y - bitmap2.get_height() + 10
    205. # 根据角色方向判断是否需要翻转图片
    206. if self.get_dir() == DIR_RIGHT:
    207. # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
    208. bitmap2_mirror = pygame.transform.flip(bitmap2, True, False)
    209. screen.blit(bitmap2_mirror, (draw_x, draw_y))
    210. else:
    211. screen.blit(bitmap2, (draw_x, draw_y))
    212. self.current_head_draw_x = draw_x
    213. self.current_head_draw_y = draw_y
    214. self.current_head_bitmap = bitmap2
    215. # self.draw_count控制该方法每调用4次才会切换到下一帧位图
    216. self.draw_count += 1
    217. if self.draw_count >= 4:
    218. self.draw_count = 0
    219. self.index_leg += 1
    220. self.index_head += 1
    221. # 画子弹
    222. self.draw_bullet(screen)
    223. # 画左上角的角色、名字、血量
    224. self.draw_head(screen)
    225. # 绘制左上角的角色、名字、生命值的方法
    226. def draw_head(self, screen):
    227. if self.view_manager.head == None:
    228. return
    229. # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
    230. head_mirror = pygame.transform.flip(self.view_manager.head, True, False)
    231. # 画头像
    232. screen.blit(head_mirror, (0, 0))
    233. # 将名字渲染成图像
    234. name_image = self.font.render(self.name, True, (230, 23, 23))
    235. # 画名字
    236. screen.blit(name_image, (self.view_manager.head.get_width(), 10))
    237. # 将生命值渲染成图像
    238. hp_image = self.font.render("HP:" + str(self.hp), True, (230, 23, 23))
    239. # 画生命值
    240. screen.blit(hp_image, (self.view_manager.head.get_width(), 30))
    241. # 判断该角色是否被子弹打中的方法
    242. def is_hurt(self, start_x, end_x, start_y, end_y):
    243. if self.current_head_bitmap == None or self.current_leg_bitmap == None:
    244. return False
    245. # 计算角色的图片所覆盖的矩形区域
    246. player_start_x = self.current_head_draw_x
    247. player_end_x = player_start_x + self.current_head_bitmap.get_width()
    248. player_start_y = self.current_head_draw_y
    249. player_end_y = player_start_y + self.current_head_bitmap.get_height() + \
    250. self.current_leg_bitmap.get_height()
    251. # 如果子弹出现的位置与角色图片覆盖的矩形区域有重叠,即可判断角色被子弹打中
    252. return (player_start_x < start_x < player_end_x \
    253. or player_start_x < end_x < player_end_x) \
    254. and (player_start_y < start_y < player_end_y \
    255. or player_start_y < end_y < player_end_y)
    256. # 发射子弹的方法
    257. def add_bullet(self, view_manager):
    258. if not self.pesses_boss_time:
    259. # 计算子弹的初始X坐标
    260. bullet_x = self.view_manager.X_DEFAULT + 50 if self.get_dir() \
    261. == DIR_RIGHT else self.view_manager.X_DEFAULT - 50
    262. else:bullet_x = self.boss_time_move_x
    263. if not self.pesses_boss_time:
    264. # 创建子弹对象
    265. bullet = Bullet(BULLET_TYPE_1, bullet_x, self.y - 60, self.get_dir())
    266. else:
    267. # 创建子弹对象
    268. bullet = Bullet(7, bullet_x+20, self.y-100, self.get_dir())
    269. # 将子弹添加到用户发射的子弹Group中
    270. self.bullet_list.add(bullet)
    271. # 发射子弹时,将self.left_shoot_time设置为射击状态最大值
    272. self.left_shoot_time = MAX_LEFT_SHOOT_TIME
    273. # 播放射击音效
    274. view_manager.sound_effect[0].play()
    275. # 画子弹
    276. def draw_bullet(self, screen):
    277. delete_list = []
    278. if self.pesses_boss_time:
    279. if self.bullet_clear < 2:
    280. self.bullet_clear += 1
    281. # 遍历角色发射的所有子弹
    282. for bullet in self.bullet_list.sprites():
    283. # 将所有越界的子弹收集到delete_list列表中
    284. if bullet.x < 0 or bullet.x > self.view_manager.screen_width:
    285. delete_list.append(bullet)
    286. if self.bullet_clear == 1:
    287. print(self.bullet_clear)
    288. self.bullet_list.remove(bullet)
    289. # 清除所有越界的子弹
    290. self.bullet_list.remove(delete_list)
    291. # 遍历用户发射的所有子弹
    292. for bullet in self.bullet_list.sprites():
    293. # 获取子弹对应的位图
    294. bitmap = bullet.bitmap(self.view_manager)
    295. # 子弹移动
    296. bullet.move(self.pesses_boss_time)
    297. # 画子弹,根据子弹方向判断是否需要翻转图片
    298. if bullet.dir == DIR_LEFT and not self.pesses_boss_time:
    299. # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
    300. bitmap_mirror = pygame.transform.flip(bitmap, True, False)
    301. screen.blit(bitmap_mirror, (bullet.x, bullet.y))
    302. else:
    303. screen.blit(bitmap, (bullet.x, bullet.y))
    304. # 处理角色移动的方法
    305. def move_position(self, screen):
    306. # 如果不是boss时间让怪物移动怪物
    307. if not self.pesses_boss_time:
    308. if self.move == MOVE_RIGHT:
    309. # 更新怪物的位置
    310. mm.update_posistion(screen, self.view_manager, self, 6)
    311. # 更新角色位置
    312. self._x += 6
    313. if not self.is_jump:
    314. # 不跳的时候,需要设置动作
    315. self.action = ACTION_RUN_RIGHT
    316. elif self.move == MOVE_LEFT:
    317. if self.x - 6 < self.view_manager.X_DEFAULT:
    318. # 更新怪物的位置
    319. mm.update_posistion(screen, self.view_manager, self, \
    320. -(self.x - self.view_manager.X_DEFAULT))
    321. else:
    322. # 更新怪物的位置
    323. mm.update_posistion(screen, self.view_manager, self, -6)
    324. # 更新角色位置
    325. self.x -= 6
    326. if not self.is_jump:
    327. # 不跳的时候,需要设置动作
    328. self.action = ACTION_RUN_LEFT
    329. elif self.action != ACTION_JUMP_RIGHT and self.action != ACTION_JUMP_LEFT:
    330. if not self.is_jump:
    331. # 不跳的时候,需要设置动作
    332. self.action = ACTION_STAND_RIGHT
    333. # 否则玩家动
    334. else:
    335. if self.move == MOVE_RIGHT:
    336. # # 更新角色位置
    337. self.boss_time_move_x+=6
    338. if not self.is_jump:
    339. # 不跳的时候,需要设置动作
    340. self.action = ACTION_RUN_RIGHT
    341. elif self.move == MOVE_LEFT:
    342. # 更新角色位置
    343. self.boss_time_move_x -= 6
    344. if not self.is_jump:
    345. # 不跳的时候,需要设置动作
    346. self.action = ACTION_RUN_LEFT
    347. elif self.action != ACTION_JUMP_RIGHT and self.action != ACTION_JUMP_LEFT:
    348. if not self.is_jump:
    349. # 不跳的时候,需要设置动作
    350. self.action = ACTION_STAND_RIGHT
    351. # 处理角色移动与跳的逻辑关系
    352. def logic(self, screen):
    353. if self.boos_time_updata_y:
    354. self.y = 500
    355. self.x = 100
    356. self.boos_time_updata_y = False
    357. if not self.is_jump:
    358. self.move_position(screen)
    359. return
    360. # 如果还没有跳到最高点
    361. if not self.is_jump_max:
    362. self.action = ACTION_JUMP_RIGHT if self.get_dir() == \
    363. DIR_RIGHT else ACTION_JUMP_LEFT
    364. # 更新Y坐标
    365. self.y -= 8
    366. # 设置子弹在Y方向上具有向上的加速度
    367. self.set_bullet_y_accelate(-2)
    368. # 已经达到最高点
    369. if self.y <= self.view_manager.Y_JUMP_MAX:
    370. self.is_jump_max = True
    371. else:
    372. self.jump_stop_count -= 1
    373. # 如果在最高点停留次数已经使用完
    374. if self.jump_stop_count <= 0:
    375. # 更新Y坐标
    376. self.y += 8
    377. # 设置子弹在Y方向上具有向下的加速度
    378. self.set_bullet_y_accelate(2)
    379. # 已经掉落到最低点
    380. if self.y >= self.view_manager.Y_DEFALUT:
    381. # 恢复Y坐标
    382. self.y = self.view_manager.Y_DEFALUT
    383. self.is_jump = False
    384. self.is_jump_max = False
    385. self.action = ACTION_STAND_RIGHT
    386. else:
    387. # 未掉落到最低点,继续使用跳的动作
    388. self.action = ACTION_JUMP_RIGHT if self.get_dir() == \
    389. DIR_RIGHT else ACTION_JUMP_LEFT
    390. # 控制角色移动
    391. self.move_position(screen)
    392. # 更新子弹的位置(子弹位置同样会受到角色的位移的影响)
    393. def update_bullet_shift(self, shift):
    394. for bullet in self.bullet_list:
    395. bullet.x = bullet.x - shift
    396. # 给子弹设置垂直方向上的加速度
    397. # 游戏的设计是:当角色跳动时,子弹会具有垂直方向上的加速度
    398. def set_bullet_y_accelate(self, accelate):
    399. for bullet in self.bullet_list:
    400. if bullet.y_accelate == 0:
    401. bullet.y_accelate = accelate

    3)主程序运行

    1. # coding: utf-8
    2. import pygame
    3. import sys
    4. from view_manager import ViewManager
    5. import game_functions as gf
    6. import monster_manager as mm
    7. import boss_manager as bs
    8. from player import *
    9. def run_game():
    10. # 初始化游戏
    11. pygame.init()
    12. # 初始化混音器模块
    13. pygame.mixer.init()
    14. # 加载背景音乐
    15. pygame.mixer.music.load('music/background.mp3')
    16. # 创建ViewManager对象
    17. view_manager = ViewManager()
    18. # 设置显示屏幕,返回Surface对象
    19. screen = pygame.display.set_mode((view_manager.screen_width,
    20. view_manager.screen_height))
    21. # 设置标题
    22. pygame.display.set_caption('勇者大冒险')
    23. # 创建玩家角色
    24. player = Player(view_manager, 'P1', MAX_HP)
    25. while(True):
    26. pygame.time.delay(15)
    27. # 处理游戏事件
    28. gf.check_events(screen, view_manager, player)
    29. # 更新游戏屏幕
    30. gf.update_screen(screen, view_manager, mm, player,bs)
    31. # 播放背景音乐
    32. if pygame.mixer.music.get_busy() == False:
    33. pygame.mixer.music.play()
    34. run_game()

    四、效果展示

    游戏说明:空格射击子弹、反向键移动即可。更多好玩儿的等大家自己体验的啦~

    1)游戏界面

    ​2)开始游戏

    ​3)跳跃射击

    ​4)BOSS时刻

    PS:如果你以前喜欢过《魂斗罗》、《合金弹头》的话,这款游戏绝对值得拥有。

    那种像素游戏中的突突突可能就是青春中简单的浪漫吧,还记得当初上电脑课最快乐的时刻,

    也莫过于反复的死亡,反复地期待着下一周的课,终于在某一周的课上打通了游戏,那时会手

    舞足蹈,引起老师关注,然后被一顿臭骂,但心底的最深处还是掩藏不住得激动。相信这款游

    戏也能给你带来相同的感动。

    总结

    不得不说刚一手我就爱上了这款游戏,在敌人的枪林弹雨中来回跳跃的感觉属实刺激。之前已

    经写过N篇游戏的文章代码啦!要来挑一挑你喜欢的嘛?

    老规矩的撒!来看文章汇总得免费的源码素材的哈👇

    老规矩,木子的文章汇总可以看到分类好的各种不同类型的文章,滴滴我大部分源码都在滴。

    🎯完整的免费源码领取处:找我吖!文末公众hao可自行领取,滴滴我也可!

    🔨推荐往期文章——

     项目1.0《小蜜蜂历险记》

    【Pygame实战】强烈推荐:教你用百行代码编写一款《小蜜蜂历险记》不信?来看看(玩儿嗨了~)

    项目1.1  扑克牌游戏

    【Pygame实战】打扑克牌嘛?赢了输了?这款打牌游戏,竟让我废寝忘食。

    项目1.2  英文单词猜猜看小游戏

    【Pygame实战】再次祭出舍不得分享的学习小技巧,用游戏玩出英文能力(O基础也能轻松get)

    项目8.3  泡泡机游戏

    【Pygame实战】超有趣的泡泡游戏来袭——愿你童心不泯,永远快乐简单哦~

    🎄文章汇总——

    汇总合集  Python—2022 |已有文章汇总 | 持续更新,直接看这篇就够了

    (更多内容+源码都在✨文章汇总哦!!欢迎阅读喜欢的文章🎉~)

  • 相关阅读:
    性能测试-基础01
    rv1126-rv1109-NFS功能
    手摸手教你 docker+jenkins+gitlab 部署你的前端项目
    一级消防工程师证书价值下降,前景茫然?
    sortablejs拖拽后新增和删除行时顺序错乱
    微服务实战系列之玩转Docker(一)
    图片水印怎么加?图片加水印方法分享
    RobotFramework之如何使用数据驱动(十二)
    Vue数据双向绑定的原理+响应式原理
    中介者模式
  • 原文地址:https://blog.csdn.net/weixin_55822277/article/details/126310479