千家信息网

如何使用python中实现炸弹人学院游戏

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章主要介绍了如何使用python中实现炸弹人学院游戏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。正文游戏规则还清楚哈, 我就不
千家信息网最后更新 2025年01月19日如何使用python中实现炸弹人学院游戏

这篇文章主要介绍了如何使用python中实现炸弹人学院游戏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

正文

游戏规则还清楚哈, 我就不多做介绍了不清楚玩法的可以百度下下!

首先准备好相应的素材:【部分如下】

炸弹人主程序:

import sysimport cfgimport randomimport pygamefrom modules import *  '''游戏主程序'''def main(cfg):    # 初始化    pygame.init()    pygame.mixer.init()    pygame.mixer.music.load(cfg.BGMPATH)    pygame.mixer.music.play(-1, 0.0)    screen = pygame.display.set_mode(cfg.SCREENSIZE)    pygame.display.set_caption('炸弹人--源码基地:#959755565#')    # 开始界面    Interface(screen, cfg, mode='game_start')    # 游戏主循环    font = pygame.font.SysFont('Consolas', 15)    for gamemap_path in cfg.GAMEMAPPATHS:        # -地图        map_parser = mapParser(gamemap_path, bg_paths=cfg.BACKGROUNDPATHS, wall_paths=cfg.WALLPATHS, blocksize=cfg.BLOCKSIZE)        # -水果        fruit_sprite_group = pygame.sprite.Group()        used_spaces = []        for i in range(5):            coordinate = map_parser.randomGetSpace(used_spaces)            used_spaces.append(coordinate)            fruit_sprite_group.add(Fruit(random.choice(cfg.FRUITPATHS), coordinate=coordinate, blocksize=cfg.BLOCKSIZE))        # -我方Hero        coordinate = map_parser.randomGetSpace(used_spaces)        used_spaces.append(coordinate)        ourhero = Hero(imagepaths=cfg.HEROZELDAPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='ZELDA')        # -电脑Hero        aihero_sprite_group = pygame.sprite.Group()        coordinate = map_parser.randomGetSpace(used_spaces)        aihero_sprite_group.add(Hero(imagepaths=cfg.HEROBATMANPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='BATMAN'))        used_spaces.append(coordinate)        coordinate = map_parser.randomGetSpace(used_spaces)        aihero_sprite_group.add(Hero(imagepaths=cfg.HERODKPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='DK'))        used_spaces.append(coordinate)        # -炸弹bomb        bomb_sprite_group = pygame.sprite.Group()        # -用于判断游戏胜利或者失败的flag        is_win_flag = False        # -主循环        screen = pygame.display.set_mode(map_parser.screen_size)        clock = pygame.time.Clock()        while True:            dt = clock.tick(cfg.FPS)            for event in pygame.event.get():                if event.type == pygame.QUIT:                    pygame.quit()                    sys.exit(-1)                # --↑↓←→键控制上下左右, 空格键丢炸弹                elif event.type == pygame.KEYDOWN:                    if event.key == pygame.K_UP:                        ourhero.move('up')                    elif event.key == pygame.K_DOWN:                        ourhero.move('down')                    elif event.key == pygame.K_LEFT:                        ourhero.move('left')                    elif event.key == pygame.K_RIGHT:                        ourhero.move('right')                    elif event.key == pygame.K_SPACE:                        if ourhero.bomb_cooling_count <= 0:                            bomb_sprite_group.add(ourhero.generateBomb(imagepath=cfg.BOMBPATH, digitalcolor=cfg.YELLOW, explode_imagepath=cfg.FIREPATH))            screen.fill(cfg.WHITE)            # --电脑Hero随机行动            for hero in aihero_sprite_group:                action, flag = hero.randomAction(dt)                if flag and action == 'dropbomb':                    bomb_sprite_group.add(hero.generateBomb(imagepath=cfg.BOMBPATH, digitalcolor=cfg.YELLOW, explode_imagepath=cfg.FIREPATH))            # --吃到水果加生命值(只要是Hero, 都能加)            ourhero.eatFruit(fruit_sprite_group)            for hero in aihero_sprite_group:                hero.eatFruit(fruit_sprite_group)            # --游戏元素都绑定到屏幕上            map_parser.draw(screen)            for bomb in bomb_sprite_group:                if not bomb.is_being:                    bomb_sprite_group.remove(bomb)                explode_area = bomb.draw(screen, dt, map_parser)                if explode_area:                    # --爆炸火焰范围内的Hero生命值将持续下降                    if ourhero.coordinate in explode_area:                        ourhero.health_value -= bomb.harm_value                    for hero in aihero_sprite_group:                        if hero.coordinate in explode_area:                            hero.health_value -= bomb.harm_value            fruit_sprite_group.draw(screen)            for hero in aihero_sprite_group:                hero.draw(screen, dt)            ourhero.draw(screen, dt)            # --左上角显示生命值            pos_x = showText(screen, font, text=ourhero.hero_name+'(our):'+str(ourhero.health_value), color=cfg.YELLOW, position=[5, 5])            for hero in aihero_sprite_group:                pos_x, pos_y = pos_x+15, 5                pos_x = showText(screen, font, text=hero.hero_name+'(ai):'+str(hero.health_value), color=cfg.YELLOW, position=[pos_x, pos_y])            # --我方玩家生命值小于等于0/电脑方玩家生命值均小于等于0则判断游戏结束            if ourhero.health_value <= 0:                is_win_flag = False                break            for hero in aihero_sprite_group:                if hero.health_value <= 0:                    aihero_sprite_group.remove(hero)            if len(aihero_sprite_group) == 0:                is_win_flag = True                break            pygame.display.update()            clock.tick(cfg.FPS)        if is_win_flag:            Interface(screen, cfg, mode='game_switch')        else:            break    Interface(screen, cfg, mode='game_end')  '''run'''if __name__ == '__main__':    while True:        main(cfg)

开始的界面如下:

定义地图类:

class mapParser():        def __init__(self, mapfilepath, bg_paths, wall_paths, blocksize, **kwargs):                self.instances_list = self.__parse(mapfilepath)                self.bg_paths = bg_paths                self.wall_paths = wall_paths                self.blocksize = blocksize                self.height = len(self.instances_list)                self.width = len(self.instances_list[0])                self.screen_size = (blocksize * self.width, blocksize * self.height)        '''地图画到屏幕上'''        def draw(self, screen):                for j in range(self.height):                        for i in range(self.width):                                instance = self.instances_list[j][i]                                if instance == 'w':                                        elem = Wall(self.wall_paths[0], [i, j], self.blocksize)                                elif instance == 'x':                                        elem = Wall(self.wall_paths[1], [i, j], self.blocksize)                                elif instance == 'z':                                        elem = Wall(self.wall_paths[2], [i, j], self.blocksize)                                elif instance == '0':                                        elem = Background(self.bg_paths[0], [i, j], self.blocksize)                                elif instance == '1':                                        elem = Background(self.bg_paths[1], [i, j], self.blocksize)                                elif instance == '2':                                        elem = Background(self.bg_paths[2], [i, j], self.blocksize)                                else:                                        raise ValueError('instance parse error in mapParser.draw...')                                elem.draw(screen)        '''随机获取一个空地'''        def randomGetSpace(self, used_spaces=None):                while True:                        i = random.randint(0, self.width-1)                        j = random.randint(0, self.height-1)                        coordinate = [i, j]                        if used_spaces and coordinate in used_spaces:                                continue                        instance = self.instances_list[j][i]                        if instance in ['0', '1', '2']:                                break                return coordinate        '''根据坐标获取元素类型'''        def getElemByCoordinate(self, coordinate):                return self.instances_list[coordinate[1]][coordinate[0]]        '''解析.map文件'''        def __parse(self, mapfilepath):                instances_list = []                with open(mapfilepath) as f:                        for line in f.readlines():                                instances_line_list = []                                for c in line:                                        if c in ['w', 'x', 'z', '0', '1', '2']:                                                instances_line_list.append(c)                                instances_list.append(instances_line_list)                return instances_list

定义必要的一些精灵类:角色,水果等等。

'''墙类'''class Wall(pygame.sprite.Sprite):        def __init__(self, imagepath, coordinate, blocksize, **kwargs):                pygame.sprite.Sprite.__init__(self)                self.image = pygame.image.load(imagepath)                self.image = pygame.transform.scale(self.image, (blocksize, blocksize))                self.rect = self.image.get_rect()                self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize                self.coordinate = coordinate                self.blocksize = blocksize        '''画到屏幕上'''        def draw(self, screen):                screen.blit(self.image, self.rect)                return True  '''背景类'''class Background(pygame.sprite.Sprite):        def __init__(self, imagepath, coordinate, blocksize, **kwargs):                pygame.sprite.Sprite.__init__(self)                self.image = pygame.image.load(imagepath)                self.image = pygame.transform.scale(self.image, (blocksize, blocksize))                self.rect = self.image.get_rect()                self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize                self.coordinate = coordinate                self.blocksize = blocksize        '''画到屏幕上'''        def draw(self, screen):                screen.blit(self.image, self.rect)                return True  '''水果类'''class Fruit(pygame.sprite.Sprite):        def __init__(self, imagepath, coordinate, blocksize, **kwargs):                pygame.sprite.Sprite.__init__(self)                self.kind = imagepath.split('/')[-1].split('.')[0]                if self.kind == 'banana':                        self.value = 5                elif self.kind == 'cherry':                        self.value = 10                else:                        raise ValueError('Unknow fruit %s...' % self.kind)                self.image = pygame.image.load(imagepath)                self.image = pygame.transform.scale(self.image, (blocksize, blocksize))                self.rect = self.image.get_rect()                self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize                self.coordinate = coordinate                self.blocksize = blocksize        '''画到屏幕上'''        def draw(self, screen):                screen.blit(self.image, self.rect)                return True  '''炸弹类'''class Bomb(pygame.sprite.Sprite):        def __init__(self, imagepath, coordinate, blocksize, digitalcolor, explode_imagepath, **kwargs):                pygame.sprite.Sprite.__init__(self)                self.image = pygame.image.load(imagepath)                self.image = pygame.transform.scale(self.image, (blocksize, blocksize))                self.explode_imagepath = explode_imagepath                self.rect = self.image.get_rect()                # 像素位置                self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize                # 坐标(元素块为单位长度)                self.coordinate = coordinate                self.blocksize = blocksize                # 爆炸倒计时                self.explode_millisecond = 6000 * 1 - 1                self.explode_second = int(self.explode_millisecond / 1000)                self.start_explode = False                # 爆炸持续时间                self.exploding_count = 1000 * 1                # 炸弹伤害能力                self.harm_value = 1                # 该炸弹是否还存在                self.is_being = True                self.font = pygame.font.SysFont('Consolas', 20)                self.digitalcolor = digitalcolor        '''画到屏幕上'''        def draw(self, screen, dt, map_parser):                if not self.start_explode:                        # 爆炸倒计时                        self.explode_millisecond -= dt                        self.explode_second = int(self.explode_millisecond / 1000)                        if self.explode_millisecond < 0:                                self.start_explode = True                        screen.blit(self.image, self.rect)                        text = self.font.render(str(self.explode_second), True, self.digitalcolor)                        rect = text.get_rect(center=(self.rect.centerx-5, self.rect.centery+5))                        screen.blit(text, rect)                        return False                else:                        # 爆炸持续倒计时                        self.exploding_count -= dt                        if self.exploding_count > 0:                                return self.__explode(screen, map_parser)                        else:                                self.is_being = False                                return False        '''爆炸效果'''        def __explode(self, screen, map_parser):                explode_area = self.__calcExplodeArea(map_parser.instances_list)                for each in explode_area:                        image = pygame.image.load(self.explode_imagepath)                        image = pygame.transform.scale(image, (self.blocksize, self.blocksize))                        rect = image.get_rect()                        rect.left, rect.top = each[0] * self.blocksize, each[1] * self.blocksize                        screen.blit(image, rect)                return explode_area        '''计算爆炸区域'''        def __calcExplodeArea(self, instances_list):                explode_area = []                # 区域计算规则为墙可以阻止爆炸扩散, 且爆炸范围仅在游戏地图范围内                for ymin in range(self.coordinate[1], self.coordinate[1]-5, -1):                        if ymin < 0 or instances_list[ymin][self.coordinate[0]] in ['w', 'x', 'z']:                                break                        explode_area.append([self.coordinate[0], ymin])                for ymax in range(self.coordinate[1]+1, self.coordinate[1]+5):                        if ymax >= len(instances_list) or instances_list[ymax][self.coordinate[0]] in ['w', 'x', 'z']:                                break                        explode_area.append([self.coordinate[0], ymax])                for xmin in range(self.coordinate[0], self.coordinate[0]-5, -1):                        if xmin < 0 or instances_list[self.coordinate[1]][xmin] in ['w', 'x', 'z']:                                break                        explode_area.append([xmin, self.coordinate[1]])                for xmax in range(self.coordinate[0]+1, self.coordinate[0]+5):                        if xmax >= len(instances_list[0]) or instances_list[self.coordinate[1]][xmax] in ['w', 'x', 'z']:                                break                        explode_area.append([xmax, self.coordinate[1]])                return explode_area  '''角色类'''class Hero(pygame.sprite.Sprite):        def __init__(self, imagepaths, coordinate, blocksize, map_parser, **kwargs):                pygame.sprite.Sprite.__init__(self)                self.imagepaths = imagepaths                self.image = pygame.image.load(imagepaths[-1])                self.image = pygame.transform.scale(self.image, (blocksize, blocksize))                self.rect = self.image.get_rect()                self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize                self.coordinate = coordinate                self.blocksize = blocksize                self.map_parser = map_parser                self.hero_name = kwargs.get('hero_name')                # 生命值                self.health_value = 50                # 炸弹冷却时间                self.bomb_cooling_time = 5000                self.bomb_cooling_count = 0                # 随机移动冷却时间(仅AI电脑用)                self.randommove_cooling_time = 100                self.randommove_cooling_count = 0        '''角色移动'''        def move(self, direction):                self.__updateImage(direction)                if direction == 'left':                        if self.coordinate[0]-1 < 0 or self.map_parser.getElemByCoordinate([self.coordinate[0]-1, self.coordinate[1]]) in ['w', 'x', 'z']:                                return False                        self.coordinate[0] = self.coordinate[0] - 1                elif direction == 'right':                        if self.coordinate[0]+1 >= self.map_parser.width or self.map_parser.getElemByCoordinate([self.coordinate[0]+1, self.coordinate[1]]) in ['w', 'x', 'z']:                                return False                        self.coordinate[0] = self.coordinate[0] + 1                elif direction == 'up':                        if self.coordinate[1]-1 < 0 or self.map_parser.getElemByCoordinate([self.coordinate[0], self.coordinate[1]-1]) in ['w', 'x', 'z']:                                return False                        self.coordinate[1] = self.coordinate[1] - 1                elif direction == 'down':                        if self.coordinate[1]+1 >= self.map_parser.height or self.map_parser.getElemByCoordinate([self.coordinate[0], self.coordinate[1]+1]) in ['w', 'x', 'z']:                                return False                        self.coordinate[1] = self.coordinate[1] + 1                else:                        raise ValueError('Unknow direction %s...' % direction)                self.rect.left, self.rect.top = self.coordinate[0] * self.blocksize, self.coordinate[1] * self.blocksize                return True        '''随机行动(AI电脑用)'''        def randomAction(self, dt):                # 冷却倒计时                if self.randommove_cooling_count > 0:                        self.randommove_cooling_count -= dt                action = random.choice(['left', 'left', 'right', 'right', 'up', 'up', 'down', 'down', 'dropbomb'])                flag = False                if action in ['left', 'right', 'up', 'down']:                        if self.randommove_cooling_count <= 0:                                flag = True                                self.move(action)                                self.randommove_cooling_count = self.randommove_cooling_time                elif action in ['dropbomb']:                        if self.bomb_cooling_count <= 0:                                flag = True                                self.bomb_cooling_count = self.bomb_cooling_time                return action, flag        '''生成炸弹'''        def generateBomb(self, imagepath, digitalcolor, explode_imagepath):                return Bomb(imagepath=imagepath, coordinate=copy.deepcopy(self.coordinate), blocksize=self.blocksize, digitalcolor=digitalcolor, explode_imagepath=explode_imagepath)        '''画到屏幕上'''        def draw(self, screen, dt):                # 冷却倒计时                if self.bomb_cooling_count > 0:                        self.bomb_cooling_count -= dt                screen.blit(self.image, self.rect)                return True        '''吃水果'''        def eatFruit(self, fruit_sprite_group):                eaten_fruit = pygame.sprite.spritecollide(self, fruit_sprite_group, True, None)                for fruit in eaten_fruit:                        self.health_value += fruit.value        '''更新角色朝向'''        def __updateImage(self, direction):                directions = ['left', 'right', 'up', 'down']                idx = directions.index(direction)                self.image = pygame.image.load(self.imagepaths[idx])                self.image = pygame.transform.scale(self.image, (self.blocksize, self.blocksize))

效果如下:

感谢你能够认真阅读完这篇文章,希望小编分享的"如何使用python中实现炸弹人学院游戏"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0