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

发布于:2023-01-20 ⋅ 阅读:(11) ⋅ 点赞:(0) ⋅ 评论:(0)

导语

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

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

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

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

戏让我印象尤为深刻。​

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

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

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

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

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

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

正文

一、运行环境

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

境就可以了。

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

二、素材(图片等)

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

当然要有音乐的啦👇

​三、代码展示

1)boss主程序py

# coding: utf-8

import pygame
import sys
from random import randint
from pygame.sprite import Sprite
from pygame.sprite import Group
from bullet import *

# 控制怪物动画的速度

MAN_PAO_SPEED_THRESHOLD = 5

# 定义代表怪物类型的常量(如果程序还需要增加更多怪物,只需在此处添加常量即可)
TYPE_BOSS = 2

class Boss(Sprite):
    boss_produce = True
    def __init__ (self, view_manager):
        super().__init__()
        # 定义子弹爆炸时的帧数
        self.bullet_number=0

        # 定义boss未被加载初始未true
        # boss血量
        self.hp=20
        # 定义怪物X、Y坐标的属性
        self.x = 0
        self.y = 0
        # 定义怪物是否已经死亡的旗标
        self.is_die = False
        # 绘制怪物图片的左上角的X坐标
        self.start_x = 0
        # 绘制怪物图片的左上角的Y坐标
        self.start_y = 0
        # 绘制怪物图片的右下角的X坐标
        self.end_x = 0
        # 绘制怪物图片的右下角的Y坐标
        self.end_y = 0
        # 该变量控制用于控制动画刷新的速度
        self.draw_count = 0
        # 定义当前正在绘制怪物动画的第几帧的变量
        self.draw_index = 0
        # 用于记录死亡动画只绘制一次,不需要重复绘制
        # 每当怪物死亡时,该变量会被初始化为等于死亡动画的总帧数
        # 当怪物的死亡动画帧播放完成时,该变量的值变为0。
        self.die_max_draw_count = sys.maxsize
        # 定义怪物射出的子弹
        self.bullet_list = Group()
        # 定义Boss速度的初始值
        self.SPEED=5
        # -------下面代码初始化BOSS X、Y坐标------

        self.y = 0
        self.x = view_manager.screen_width/2

    # 画怪物的方法
    def draw(self, screen, view_manager,player):
        self.draw_anim(screen, view_manager, view_manager.boss_images
            if not self.is_die else view_manager.boss_die_images,player)
    # 根据怪物的动画帧图片来绘制怪物动画
    def draw_anim(self, screen, view_manager, bitmap_arr,player):
        # 如果怪物已经死,且没有播放过死亡动画
        #(self.die_max_draw_count等于初始值表明未播放过死亡动画)
        if self.is_die and self.die_max_draw_count == sys.maxsize:
            # 将die_max_draw_count设置与死亡动画的总帧数相等
            self.die_max_draw_count = len(bitmap_arr)    # ⑤
        self.draw_index %= len(bitmap_arr)


        # 获取当前绘制的动画帧对应的位图
        bitmap = bitmap_arr[self.draw_index]  # ①
        if bitmap == None:
            return
        # 对绘制怪物动画帧位图的X坐标进行微调

        self.x -=self.SPEED
        # 如果到达屏幕边界则反方向行进
        if self.x <=-376 or self.x >= view_manager.screen_width+120:
            self.SPEED = -self.SPEED

        # 对绘制怪物动画帧位图的Y坐标进行微调
        draw_y = self.y
        # 画怪物动画帧的位图
        if self.SPEED>0:
            bitmap=pygame.transform.flip(bitmap,True,False)
        screen.blit(bitmap, (self.x, draw_y))

        self.start_x = self.x
        self.start_y = draw_y
        self.end_x = self.start_x + bitmap.get_width()
        self.end_y = self.start_y + bitmap.get_height()
        self.draw_count += 1
        # 控制人、飞机的发射子弹的速度
        if self.draw_count >= TYPE_BOSS:  # ③
            # boss只在最后一帧才发射子弹
            if  self.draw_index == len(bitmap_arr)-1 and self.x%40==0:
                self.add_bullet()

            self.draw_index += 1   # ②
            self.draw_count = 0    # ④
        # 每播放死亡动画的一帧,self.die_max_draw_count减1。
        # 当self.die_max_draw_count等于0时,表明死亡动画播放完成。
        if self.is_die:
            self.die_max_draw_count -= 1   # ⑥
        # 如果boss死亡 加载win的画面
        if  self.die_max_draw_count<=0:
            screen.blit(view_manager.win[0], (0, 0))
            pygame.display.flip()
            while True:
                for event in pygame.event.get():
                    if event==pygame.QUIT:
                        pygame.quit()
                        sys.exit()
        # 绘制子弹
        self.draw_bullets(screen, view_manager,player)

    # 判断怪物是否被子弹打中的方法
    def is_hurt(self, x, y): 
        return self.start_x < x < self.end_x and self.start_y < y < self.end_y

    # 此boos对应的子弹是6
    def bullet_type(self):
        return 6


    # 定义发射子弹的方法
    def add_bullet(self):
        # 如果没有子弹
        if self.bullet_type() <= 0:
            return
        # 计算子弹的X、Y坐标
        draw_x = self.x+30
        draw_y = self.y+120

        # 创建子弹对象,由于这个boos是从上往下发射子弹所以不需要翻转图片这里pdir参数给以个3让他不执行翻转
        # 让飞机只有从左往右飞时发射导弹
        if self.SPEED<0:
            bullet = Bullet(self.bullet_type(), draw_x, draw_y, 3)
        # 将子弹添加到该怪物发射的子弹Group中
            self.bullet_list.add(bullet)

    # 更新所有子弹的位置:将所有子弹的X坐标减少shift距离(子弹左移)
    def update_shift(self, shift):
            self.y-=shift
            for bullet in self.bullet_list:
                if bullet != None:
                    bullet.y = self.y

    # 绘制子弹的方法
    def draw_bullets(self, screen, view_manager,player) :
        # 遍历该怪物发射的所有子弹
        for bullet in self.bullet_list.copy():
             # 如果子弹已经越过屏幕
            if bullet.boss_bang:
                # 删除已经移出屏幕的子弹
                self.bullet_list.remove(bullet)
        # 绘制所有子弹
        for bullet in self.bullet_list.sprites():
            if bullet.y<= view_manager.screen_height-250:
                # 获取子弹对应的位图
                bitmap = bullet.bitmap(view_manager)
                # 绘制子弹的位图
                screen.blit(bitmap, (bullet.x, bullet.y))
                bullet.move(True)
                # 子弹移动
                if bitmap == None:
                    continue

            elif len(self.bullet_list.sprites())>1:
                self.bullet_number+=1
                if self.bullet_number%5==0 and bullet.bullet_bang>0:
                    bullet.bullet_bang-=1
                    self.check_bullet(player)
                bitmap = view_manager.boss_die_images[bullet.bullet_bang]
                if  bullet.bullet_bang==0:
                    bullet.boss_bang=True
                # 绘制子弹的位图
                screen.blit(bitmap, (bullet.x, bullet.y))


                # 判断子弹是否与玩家控制的角色碰撞(判断子弹是否打中角色)
    def check_bullet(self, player):
        # 遍历所有子弹
        for bullet in self.bullet_list.copy():
            if bullet == None or not bullet.is_effect:
                continue
            # 如果玩家控制的角色被子弹打到
            if player.is_hurt(bullet.x-20, bullet.x+120, bullet.y, bullet.y+80):
                    # 子弹设为无效
                    bullet.isEffect = False
                    player.hp = player.hp - 15
                    # 删除已经击中玩家控制的角色的子弹
                    self.bullet_list.remove(bullet)

2)玩家设置

# coding: utf-8
import pygame
import sys
from random import randint
from pygame.sprite import Sprite
from pygame.sprite import Group
import pygame.font

from bullet import *
import monster_manager as mm

# 定义角色的最高生命值
MAX_HP = 9999999999999999999
# 定义控制角色动作的常量
# 此处只控制该角色包含站立、跑、跳等动作
ACTION_STAND_RIGHT = 1
ACTION_STAND_LEFT = 2
ACTION_RUN_RIGHT = 3
ACTION_RUN_LEFT = 4
ACTION_JUMP_RIGHT = 5
ACTION_JUMP_LEFT = 6
# 定义角色向右移动的常量
DIR_RIGHT = 1
# 定义角色向左移动的常量
DIR_LEFT = 2

# 定义控制角色移动的常量
# 此处控制该角色只包含站立、向右移动、向左移动三种移动方式
MOVE_STAND = 0
MOVE_RIGHT = 1
MOVE_LEFT = 2
MAX_LEFT_SHOOT_TIME = 6

class Player(Sprite):
    def __init__(self, view_manager, name, hp):
        super().__init__()
        self.boos_time_updata_y = False
        self.bullet_clear = 0
        # Boos时间时地图不在跟随移动角色可以自由移动,规定x轴,y轴坐标
        self.boss_time_move_x=0
        self.boss_time_move_y=0
        # BOSS时间
        self.pesses_boss_time=False# BOSS时间

        self.name = name # 保存角色名字的成员变量
        self.hp = hp # 保存角色生命值的成员变量
        self.view_manager = view_manager
        # 保存角色所使用枪的类型(以后可考虑让角色能更换不同的枪)
        self.gun = 0
        # 保存角色当前动作的成员变量(默认向右站立)
        self.action = ACTION_STAND_RIGHT
        # 代表角色X坐标的属性
        self._x = -1
        # 代表角色Y坐标的属性
        self.y = -1
        # 保存角色射出的所有子弹
        self.bullet_list = Group()
        # 保存角色移动方式的成员变量
        self.move = MOVE_STAND
        # 控制射击状态的保留计数器
        # 每当用户发射一枪时,left_shoot_time会被设为MAX_LEFT_SHOOT_TIME,然后递减
        # 只有当left_shoot_time变为0时,用户才能发射下一枪
        self.left_shoot_time = 0
        # 保存角色是否跳动的属性
        self._is_jump = False
        # 保存角色是否跳到最高处的成员变量
        self.is_jump_max = False
        # 控制跳到最高处的停留时间
        self.jump_stop_count = 0
        # 当前正在绘制角色脚部动画的第几帧
        self.index_leg = 0
        # 当前正在绘制角色头部动画的第几帧
        self.index_head = 0
        # 当前绘制头部图片的X坐标
        self.current_head_draw_x = 0
        # 当前绘制头部图片的Y坐标
        self.current_head_draw_y = 0
        # 当前正在画的脚部动画帧的图片
        self.current_leg_bitmap = None
        # 当前正在画的头部动画帧的图片
        self.current_head_bitmap = None
        # 该变量控制用于控制动画刷新的速度
        self.draw_count = 0
        # 加载中文字体
        self.font = pygame.font.Font('images/msyh.ttf', 20)

    # 计算该角色当前方向:action成员变量为奇数代表向右
    def get_dir(self):
        return DIR_RIGHT if self.action % 2 == 1 else DIR_LEFT

    def get_x(self):
        return self._x
    def set_x(self, x_val):
            self._x = x_val % (self.view_manager.map.get_width() +
                self.view_manager.X_DEFAULT)
            # 如果角色移动到屏幕最左边
            if self._x < self.view_manager.X_DEFAULT:
                self._x = self.view_manager.X_DEFAULT
    x = property(get_x, set_x)

    def get_is_jump(self):
        return self._is_jump
    def set_is_jump(self, jump_val):
        self._is_jump = jump_val
        self.jump_stop_count = 6
    is_jump = property(get_is_jump, set_is_jump)

    # 返回该角色在游戏界面上的位移
    def shift(self):
        if self.x <= 0 or self.y <= 0:
            self.init_position()
        return self.view_manager.X_DEFAULT - self.x

    # 判断角色是否已经死亡
    def is_die(self):
        return self.hp <= 0

    # 初始化角色的初始化位置,角色能跳的最大高度
    def init_position(self):
        self.x = self.view_manager.screen_width * 15 / 100
        self.y = self.view_manager.screen_height * 75 / 100

    # 画角色的方法
    def draw(self, screen):
        if not self.pesses_boss_time:
            # 绘制角色向右站立的动画图片
            if self.action == ACTION_STAND_RIGHT:
                self.draw_anim(screen, self.view_manager.leg_stand_images,
                    self.view_manager.head_stand_images, DIR_RIGHT)
            # 绘制角色向左站立的动画图片
            elif self.action == ACTION_STAND_LEFT:
                self.draw_anim(screen, self.view_manager.leg_stand_images,
                    self.view_manager.head_stand_images, DIR_LEFT)
            # 绘制角色向右跑动的动画图片
            elif self.action == ACTION_RUN_RIGHT:
                self.draw_anim(screen, self.view_manager.leg_run_images,
                    self.view_manager.head_run_images, DIR_RIGHT)

            # 绘制角色向左跑动的动画图片
            elif self.action == ACTION_RUN_LEFT:
                self.draw_anim(screen, self.view_manager.leg_run_images,
                    self.view_manager.head_run_images, DIR_LEFT)
            # 绘制角色向右跳动的动画图片
            elif self.action == ACTION_JUMP_RIGHT:
                self.draw_anim(screen, self.view_manager.leg_jump_images,
                    self.view_manager.head_jump_images, DIR_RIGHT)
            # 绘制角色向左跳动的动画图片
            elif self.action == ACTION_JUMP_LEFT:
                self.draw_anim(screen, self.view_manager.leg_jump_images,
                    self.view_manager.head_jump_images, DIR_LEFT)
        else:
            # 绘制角色向右站立的动画图片
            if self.action == ACTION_STAND_RIGHT:
                self.draw_anim(screen, self.view_manager.leg_stand_images,
                               self.view_manager.look_up_images, DIR_RIGHT)
            # 绘制角色向左站立的动画图片
            elif self.action == ACTION_STAND_LEFT:
                self.draw_anim(screen, self.view_manager.leg_stand_images,
                               self.view_manager.look_up_images, DIR_LEFT)
            # 绘制角色向右跑动的动画图片
            elif self.action == ACTION_RUN_RIGHT:
                self.draw_anim(screen, self.view_manager.leg_run_images,
                               self.view_manager.look_up_images, DIR_RIGHT)

            # 绘制角色向左跑动的动画图片
            elif self.action == ACTION_RUN_LEFT:
                self.draw_anim(screen, self.view_manager.leg_run_images,
                               self.view_manager.look_up_images, DIR_LEFT)
            # 绘制角色向右跳动的动画图片
            elif self.action == ACTION_JUMP_RIGHT:
                self.draw_anim(screen, self.view_manager.leg_jump_images,
                               self.view_manager.look_up_images, DIR_RIGHT)
            # 绘制角色向左跳动的动画图片
            elif self.action == ACTION_JUMP_LEFT:
                self.draw_anim(screen, self.view_manager.leg_jump_images,
                               self.view_manager.look_up_images, DIR_LEFT)
    # 绘制角色的动画帧
    def draw_anim(self, screen, leg_arr, head_arr_from, pdir):
        head_arr = head_arr_from
        if not self.pesses_boss_time:
            # 射击状态停留次数每次减1
            if self.left_shoot_time > 0 :
                head_arr = self.view_manager.head_shoot_images
                self.left_shoot_time -= 1
            else:
                head_arr = self.view_manager.head_stand_images
                self.left_shoot_time -= 1
        else:
            # 射击状态停留次数每次减1
            if self.left_shoot_time > 0:
                head_arr = self.view_manager.look_up_shoot_images
                self.left_shoot_time -= 1
            else:
                head_arr = self.view_manager.look_up_images
                self.left_shoot_time -= 1
        self.index_leg %= len(leg_arr)
        self.index_head %= len(head_arr)

        # 先画脚
        bitmap = leg_arr[self.index_leg]
        draw_x = self.view_manager.X_DEFAULT
        draw_y = self.y - bitmap.get_height()
        if self.pesses_boss_time:
            draw_x=self.boss_time_move_x
        # draw_y=self.y
        # 根据角色方向判断是否需要翻转图片
        if pdir == DIR_RIGHT:
            # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
            bitmap_mirror = pygame.transform.flip(bitmap, True, False)
            screen.blit(bitmap_mirror, (draw_x, draw_y))
        else:
            screen.blit(bitmap, (draw_x, draw_y))           
        self.current_leg_bitmap = bitmap
        # 再画头
        bitmap2 = head_arr[self.index_head]
        draw_x -= (bitmap2.get_width() - bitmap.get_width() >> 1)
        if self.action == ACTION_STAND_LEFT:
            draw_x += 6
        draw_y = draw_y - bitmap2.get_height() + 10
        # 根据角色方向判断是否需要翻转图片
        if self.get_dir() == DIR_RIGHT:
            # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
            bitmap2_mirror = pygame.transform.flip(bitmap2, True, False)
            screen.blit(bitmap2_mirror, (draw_x, draw_y))
        else:
            screen.blit(bitmap2, (draw_x, draw_y))  
        self.current_head_draw_x = draw_x
        self.current_head_draw_y = draw_y
        self.current_head_bitmap = bitmap2
        # self.draw_count控制该方法每调用4次才会切换到下一帧位图
        self.draw_count += 1
        if self.draw_count >= 4:
            self.draw_count = 0
            self.index_leg += 1
            self.index_head += 1
        # 画子弹
        self.draw_bullet(screen)
        # 画左上角的角色、名字、血量
        self.draw_head(screen)

    # 绘制左上角的角色、名字、生命值的方法
    def draw_head(self, screen):
        if self.view_manager.head == None:
            return
        # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
        head_mirror = pygame.transform.flip(self.view_manager.head, True, False)
        # 画头像
        screen.blit(head_mirror, (0, 0))
        # 将名字渲染成图像
        name_image = self.font.render(self.name, True, (230, 23, 23))
        # 画名字
        screen.blit(name_image, (self.view_manager.head.get_width(), 10))
        # 将生命值渲染成图像
        hp_image = self.font.render("HP:" + str(self.hp), True, (230, 23, 23))
        # 画生命值
        screen.blit(hp_image, (self.view_manager.head.get_width(), 30))

    # 判断该角色是否被子弹打中的方法
    def is_hurt(self, start_x, end_x, start_y, end_y):
        if self.current_head_bitmap == None or self.current_leg_bitmap == None:
            return False
        # 计算角色的图片所覆盖的矩形区域
        player_start_x = self.current_head_draw_x
        player_end_x = player_start_x + self.current_head_bitmap.get_width()
        player_start_y = self.current_head_draw_y
        player_end_y = player_start_y + self.current_head_bitmap.get_height() + \
            self.current_leg_bitmap.get_height()
        # 如果子弹出现的位置与角色图片覆盖的矩形区域有重叠,即可判断角色被子弹打中
        return (player_start_x < start_x < player_end_x \
            or player_start_x < end_x < player_end_x) \
            and (player_start_y < start_y < player_end_y \
            or player_start_y < end_y < player_end_y)

    # 发射子弹的方法
    def add_bullet(self, view_manager):

        if not self.pesses_boss_time:
        # 计算子弹的初始X坐标
            bullet_x = self.view_manager.X_DEFAULT + 50 if self.get_dir() \
            == DIR_RIGHT else self.view_manager.X_DEFAULT - 50
        else:bullet_x = self.boss_time_move_x
        if not self.pesses_boss_time:
            # 创建子弹对象
            bullet = Bullet(BULLET_TYPE_1, bullet_x, self.y - 60, self.get_dir())

        else:
            # 创建子弹对象
            bullet = Bullet(7, bullet_x+20, self.y-100, self.get_dir())


        # 将子弹添加到用户发射的子弹Group中
        self.bullet_list.add(bullet)
        # 发射子弹时,将self.left_shoot_time设置为射击状态最大值
        self.left_shoot_time = MAX_LEFT_SHOOT_TIME
        # 播放射击音效
        view_manager.sound_effect[0].play()

    # 画子弹
    def draw_bullet(self, screen):

        delete_list = []
        if self.pesses_boss_time:
            if self.bullet_clear < 2:
                self.bullet_clear += 1
        # 遍历角色发射的所有子弹
        for bullet in self.bullet_list.sprites():
            # 将所有越界的子弹收集到delete_list列表中
            if bullet.x < 0 or bullet.x > self.view_manager.screen_width:
                delete_list.append(bullet)
            if self.bullet_clear == 1:
                print(self.bullet_clear)
                self.bullet_list.remove(bullet)

        # 清除所有越界的子弹
        self.bullet_list.remove(delete_list)
        # 遍历用户发射的所有子弹
        for bullet in self.bullet_list.sprites():
            # 获取子弹对应的位图
            bitmap = bullet.bitmap(self.view_manager)
            # 子弹移动
            bullet.move(self.pesses_boss_time)
            # 画子弹,根据子弹方向判断是否需要翻转图片
            if bullet.dir == DIR_LEFT and not self.pesses_boss_time:
                # 对图片执行镜像(第二个参数控制水平镜像,第三个参数控制垂直镜像)
                bitmap_mirror = pygame.transform.flip(bitmap, True, False)
                screen.blit(bitmap_mirror, (bullet.x, bullet.y))
            else:
                screen.blit(bitmap, (bullet.x, bullet.y))

    # 处理角色移动的方法
    def move_position(self, screen):
        # 如果不是boss时间让怪物移动怪物
        if  not self.pesses_boss_time:
            if self.move == MOVE_RIGHT:
                # 更新怪物的位置
                mm.update_posistion(screen, self.view_manager, self, 6)
                # 更新角色位置
                self._x += 6
                if not self.is_jump:
                    # 不跳的时候,需要设置动作
                    self.action = ACTION_RUN_RIGHT
            elif self.move == MOVE_LEFT:
                if self.x - 6 < self.view_manager.X_DEFAULT:
                    # 更新怪物的位置
                    mm.update_posistion(screen, self.view_manager, self, \
                        -(self.x - self.view_manager.X_DEFAULT))
                else:
                    # 更新怪物的位置
                    mm.update_posistion(screen, self.view_manager, self, -6)
                # 更新角色位置
                self.x -= 6
                if not self.is_jump:
                    # 不跳的时候,需要设置动作
                    self.action = ACTION_RUN_LEFT
            elif self.action != ACTION_JUMP_RIGHT and self.action != ACTION_JUMP_LEFT:
                if not self.is_jump:
                    # 不跳的时候,需要设置动作
                    self.action = ACTION_STAND_RIGHT
        # 否则玩家动
        else:

            if self.move == MOVE_RIGHT:
                # # 更新角色位置
                self.boss_time_move_x+=6
                if not self.is_jump:
                    # 不跳的时候,需要设置动作
                    self.action = ACTION_RUN_RIGHT
            elif self.move == MOVE_LEFT:
                # 更新角色位置
                self.boss_time_move_x -= 6
                if not self.is_jump:
                    # 不跳的时候,需要设置动作
                    self.action = ACTION_RUN_LEFT
            elif self.action != ACTION_JUMP_RIGHT and self.action != ACTION_JUMP_LEFT:
                if not self.is_jump:
                    # 不跳的时候,需要设置动作
                    self.action = ACTION_STAND_RIGHT
    # 处理角色移动与跳的逻辑关系
    def logic(self, screen):
        if self.boos_time_updata_y:
            self.y = 500
            self.x = 100
            self.boos_time_updata_y = False
        if not self.is_jump:
            self.move_position(screen)
            return
        # 如果还没有跳到最高点
        if not self.is_jump_max:
            self.action = ACTION_JUMP_RIGHT if self.get_dir() == \
                DIR_RIGHT else ACTION_JUMP_LEFT
            # 更新Y坐标
            self.y -= 8
            # 设置子弹在Y方向上具有向上的加速度
            self.set_bullet_y_accelate(-2)
            # 已经达到最高点
            if self.y <= self.view_manager.Y_JUMP_MAX:
                self.is_jump_max = True
        else:
            self.jump_stop_count -= 1
            # 如果在最高点停留次数已经使用完
            if self.jump_stop_count <= 0:
                # 更新Y坐标
                self.y += 8
                # 设置子弹在Y方向上具有向下的加速度
                self.set_bullet_y_accelate(2)
                # 已经掉落到最低点
                if self.y >= self.view_manager.Y_DEFALUT:
                    # 恢复Y坐标
                    self.y = self.view_manager.Y_DEFALUT
                    self.is_jump = False
                    self.is_jump_max = False
                    self.action = ACTION_STAND_RIGHT
                else:
                    # 未掉落到最低点,继续使用跳的动作
                    self.action = ACTION_JUMP_RIGHT if self.get_dir() == \
                    DIR_RIGHT else ACTION_JUMP_LEFT
        # 控制角色移动
        self.move_position(screen)

    # 更新子弹的位置(子弹位置同样会受到角色的位移的影响)
    def update_bullet_shift(self, shift):
        for bullet in self.bullet_list:
            bullet.x = bullet.x - shift
            
    # 给子弹设置垂直方向上的加速度
    # 游戏的设计是:当角色跳动时,子弹会具有垂直方向上的加速度
    def set_bullet_y_accelate(self, accelate):
        for bullet in self.bullet_list:
            if bullet.y_accelate == 0:
                bullet.y_accelate = accelate

3)主程序运行

# coding: utf-8

import pygame
import sys
from view_manager import ViewManager
import game_functions as gf
import monster_manager as mm
import boss_manager as bs
from player import *

def run_game():
    # 初始化游戏
    pygame.init()
    # 初始化混音器模块
    pygame.mixer.init()
    # 加载背景音乐
    pygame.mixer.music.load('music/background.mp3')
    # 创建ViewManager对象
    view_manager = ViewManager()
    # 设置显示屏幕,返回Surface对象
    screen = pygame.display.set_mode((view_manager.screen_width, 
        view_manager.screen_height))
    # 设置标题
    pygame.display.set_caption('勇者大冒险')
    # 创建玩家角色
    player = Player(view_manager, 'P1', MAX_HP)
    while(True):
        pygame.time.delay(15)
        # 处理游戏事件
        gf.check_events(screen, view_manager, player)
        # 更新游戏屏幕
        gf.update_screen(screen, view_manager, mm, player,bs)
        # 播放背景音乐
        if pygame.mixer.music.get_busy() == False:
            pygame.mixer.music.play()
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 |已有文章汇总 | 持续更新,直接看这篇就够了

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


网站公告

欢迎关注微信公众号

今日签到

点亮在社区的每一天
签到