首页 > 编程语言 >Python 实现炸弹人游戏

Python 实现炸弹人游戏

时间:2024-12-17 17:56:29浏览次数:5  
标签:enemy bomb 游戏 Python pos player 炸弹 pygame

一、引言

       炸弹人游戏是一款经典的游戏,在本文中,我们将深入探讨如何使用 Python 的 Pygame 库来实现一个炸弹人游戏,并对其进行多方面的优化,包括添加敌人 AI、得分系统、生命值以及游戏结束逻辑,从而为玩家带来更完整丰富的游戏体验。

二、游戏初始化与设置

(一)Pygame 初始化与窗口设置

首先,我们导入必要的库pygamerandomsys,并对pygame进行初始化操作。

import pygame
import random
import sys

# 初始化pygame
pygame.init()

# 设置游戏窗口大小
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
BOMB_TIMER = 10  # 炸弹爆炸时间

# 设置颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)

# 设置字体
FONT = pygame.font.SysFont('Arial', 24)

# 游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Bomber Man')

这里我们设定了游戏窗口的大小为800x600像素,炸弹的爆炸时间为10个单位时间,同时定义了游戏中会用到的各种颜色以及字体样式,并创建了游戏窗口并设置了窗口标题为Bomber Man

(二)玩家、敌人与炸弹的初始设置

接下来,我们对游戏中的主要元素 —— 玩家、敌人和炸弹进行初始设置。

收起

python

# 玩家设置
player_size = 30
player_pos = [SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2]
player_speed = 5
player_bombs = 3
player_lives = 3

# 敌人设置
enemy_size = 30
enemy_pos = [random.randint(0, SCREEN_WIDTH - enemy_size), random.randint(0, SCREEN_HEIGHT - enemy_size)]
enemy_speed = 3
enemy_list = [{'pos': enemy_pos, 'speed': enemy_speed}]

# 炸弹设置
bomb_size = 20
bomb_list = []
bomb_timer = 0

对于玩家,我们设定了其初始大小为30像素,初始位置在窗口中心,移动速度为5像素 / 单位时间,初始拥有3颗炸弹且生命值为3。对于敌人,其初始大小也为30像素,初始位置随机生成在窗口内,移动速度为3像素 / 单位时间,并将其信息存储在enemy_list列表中。炸弹则设置了初始大小,创建了一个空的炸弹列表bomb_list用于存储炸弹信息,同时初始化炸弹定时器为0

(三)地图设置

最后,我们进行地图的设置。

# 地图设置
map_width = 20
map_height = 15
map_grid = [['1' for _ in range(map_width)] for _ in range(map_height)]

这里创建了一个20x15的地图网格map_grid,其中'1'表示不可通过的墙体,后续可根据炸弹爆炸等情况对地图进行修改。

三、游戏元素绘制函数

(一)绘制地图网格函数

def draw_grid():
    for y in range(map_height):
        for x in range(map_width):
            rect = pygame.Rect(x * 40, y * 40, 40, 40)
            pygame.draw.rect(screen, BLACK if map_grid[y][x] == '1' else WHITE, rect, 0 if map_grid[y][x] == '0' else 1)

该函数用于绘制游戏地图的网格。通过遍历地图网格中的每个格子,根据格子的值('1'为黑色墙体,'0'为白色可通行区域)绘制对应的矩形,并且根据格子类型决定是否绘制边框。

(二)绘制玩家函数

def draw_player():
    pygame.draw.rect(screen, RED, (player_pos[0], player_pos[1], player_size, player_size))

此函数简单地在玩家当前位置绘制一个红色的矩形来表示玩家。

(三)绘制敌人函数

def draw_enemy():
    for enemy in enemy_list:
        pygame.draw.rect(screen, BLUE, (enemy['pos'][0], enemy['pos'][1], enemy_size, enemy_size))

该函数遍历敌人列表enemy_list,在每个敌人的位置绘制一个蓝色的矩形来表示敌人。

四、游戏元素移动与操作函数

(一)玩家移动函数

def move_player(keys):
    if keys[pygame.K_LEFT] and player_pos[0] > 0:
        player_pos[0] -= player_speed
    if keys[pygame.K_RIGHT] and player_pos[0] < SCREEN_WIDTH - player_size:
        player_pos[0] += player_speed
    if keys[pygame.K_UP] and player_pos[1] > 0:
        player_pos[1] -= player_speed
    if keys[pygame.K_DOWN] and player_pos[1] < SCREEN_HEIGHT - player_size:
        player_pos[1] += player_speed

通过获取键盘按键状态keys,当玩家按下左、右、上、下方向键时,并且玩家位置在窗口边界内,就相应地改变玩家的位置坐标,实现玩家的移动操作。

(二)敌人移动函数

def move_enemy():
    for enemy in enemy_list:
        if random.random() < 0.1:  # 随机移动
            if random.random() < 0.5:
                enemy['pos'][0] += enemy['speed']
            else:
                enemy['pos'][0] -= enemy['speed']
            if random.random() < 0.5:
                enemy['pos'][1] += enemy['speed']
            else:
                enemy['pos'][1] -= enemy['speed']
        # 保持敌人在窗口内
        enemy['pos'][0] = max(0, min(enemy['pos'][0], SCREEN_WIDTH - enemy_size))
        enemy['pos'][1] = max(0, min(enemy['pos'][1], SCREEN_HEIGHT - enemy_size))

敌人的移动采用了简单的随机移动策略。在每次循环中,有10%的概率敌人会进行移动,移动方向在上下左右四个方向中随机选择,并且移动速度为enemy_speed。同时,确保敌人的位置始终在游戏窗口内。

(三)放置炸弹函数

def place_bomb():
    global bomb_timer
    if bomb_timer == 0 and player_bombs > 0:
        bomb_list.append({'pos': [player_pos[0] // 40, player_pos[1] // 40], 'timer': BOMB_TIMER})
        bomb_timer = BOMB_TIMER
        player_bombs -= 1

当炸弹定时器为0且玩家还有炸弹时,在玩家当前位置对应的地图格子坐标处创建一个炸弹信息并添加到bomb_list中,同时更新炸弹定时器和减少玩家的炸弹数量。

(四)炸弹爆炸函数

def explode_bombs():
    for bomb in bomb_list[:]:
        x, y = bomb['pos']
        if bomb['timer'] == 0:
            bomb_list.remove(bomb)
            if map_grid[y][x] == '1':
                map_grid[y][x] = '0'
                for dx in [-1, 0, 1]:
                    for dy in [-1, 0, 1]:
                        if dx!= 0 or dy!= 0:
                            nx, ny = x + dx, y + dy
                            if 0 <= nx < map_width and 0 <= ny < map_height and map_grid[ny][nx] == '1':
                                map_grid[ny][nx] = '0'
        else:
            bomb['timer'] -= 1

该函数遍历炸弹列表bomb_list,当炸弹定时器归零时,炸弹爆炸。如果爆炸位置是墙体('1'),则将其变为可通行区域('0'),并且对爆炸周围的格子(九宫格范围内除中心格)进行遍历,如果是墙体也将其变为可通行区域。如果炸弹定时器未归零,则将其减1

(五)碰撞检测函数

收起

python

def check_collision():
    global player_lives
    for enemy in enemy_list[:]:
        if (enemy['pos'][0] >= player_pos[0] and enemy['pos'][0] <= player_pos[0] + player_size) and \
           (enemy['pos'][1] >= player_pos[1] and enemy['pos'][1] <= player_pos[1] + player_size):
            player_lives -= 1
            enemy_list.remove(enemy)
            if player_lives <= 0:
                return True
    return False

此函数用于检测玩家与敌人之间的碰撞。遍历敌人列表,如果某个敌人与玩家的位置有重叠,则减少玩家生命值,移除该敌人。如果玩家生命值小于等于0,则游戏结束,返回True,否则返回False

五、游戏主循环

def game_loop():
    running = True
    clock = pygame.time.Clock()
    score = 0
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        keys = pygame.key.get_pressed()
        move_player(keys)
        if keys[pygame.K_SPACE] and player_bombs > 0:
            place_bomb()

        move_enemy()
        explode_bombs()

        screen.fill(BLACK)
        draw_grid()
        draw_player()
        draw_enemy()
        for bomb in bomb_list:
            pygame.draw.rect(screen, (255, 255, 0), (bomb['pos'][0] * 40, bomb['pos'][1] * 40, 40, 40))

        if check_collision():
            running = False

        score_text = FONT.render(f'Score: {score}', True, GREEN)
        lives_text = FONT.render(f'Lives: {player_lives}', True, GREEN)
        screen.blit(score_text, (10, 10))
        screen.blit(lives_text, (SCREEN_WIDTH - 150, 10))

        pygame.display.flip()
        clock.tick(30)

    pygame.quit()
    sys.exit()

        游戏主循环game_loop中,首先处理游戏退出事件。然后获取键盘按键状态并进行玩家移动和炸弹放置操作。接着移动敌人、处理炸弹爆炸逻辑。之后绘制游戏背景、地图、玩家、敌人和炸弹等元素。再进行碰撞检测,如果游戏结束则跳出循环。最后绘制得分和生命值信息,并更新屏幕显示,控制游戏帧率为30帧 / 秒。

六、游戏入口

if __name__ == "__main__":
    game_loop()

if __name__ == "__main__"语句块中调用game_loop函数,启动游戏。

七、优化内容总结

  1. 敌人 AI:通过简单的随机移动策略,使敌人具有一定的自主性,增加了游戏的挑战性。
  2. 得分系统:虽然代码中未详细展示得分增加逻辑(可在放置炸弹时增加得分等),但已预留了得分变量score,为后续完善得分系统提供了基础。
  3. 生命值:玩家拥有生命值,当与敌人碰撞时生命值减少,当生命值为0时游戏结束,使游戏更加合理和具有紧张感。
  4. 游戏结束逻辑:明确了游戏结束的条件,即玩家生命值耗尽,使游戏有完整的开始和结束流程。

八、后续扩展方向

       这个优化后的代码已经提供了一个较为完整的炸弹人游戏框架。你可以根据需要进一步扩展和优化这个游戏,例如添加更多的敌人类型,不同类型敌人具有不同的移动策略和攻击方式;改进地图生成逻辑,生成更加复杂和有趣的地图;增加更多的游戏元素,如道具、陷阱等,以丰富游戏玩法和提高游戏的趣味性与可玩性。

       通过以上对炸弹人游戏代码的详细解析,希望能帮助读者更好地理解游戏开发过程中的逻辑构建和功能实现,从而在游戏开发的学习和实践中取得更大的进步。

标签:enemy,bomb,游戏,Python,pos,player,炸弹,pygame
From: https://blog.csdn.net/2403_89537385/article/details/144541153

相关文章

  • Python字符串及正则表达式(十):字符串常用操作、字符串编码转换
    前言:在编程的世界里,字符串无处不在。它们是构建用户界面、存储数据、进行通信的基础元素。无论是财务系统的总账报表、电子游戏的比赛结果,还是火车站的列车时刻表,这些信息最终都需要以文本的形式呈现给用户。这些文本的背后,是程序经过精确计算、逻辑判断和数据整理的结果,它们将复......
  • Python中构建全局字典的详细指南
    在Python编程中,全局变量是指在整个程序运行期间都可以访问的变量。全局字典作为一种特殊的全局变量,可以存储各种类型的数据,包括字符串、数字、列表、元组等,这使得它在数据管理和跨模块通信方面非常有用。本文将详细介绍如何在Python中构建和使用全局字典,包括理论概述和代码示例。......
  • 零基础学习人工智能—Python—Pytorch学习(十三)
    前言最近学习了一新概念,叫科学发现和科技发明,科学发现是高于科技发明的,而这个说法我觉得还是挺有道理的,我们总说中国的科技不如欧美,但我们实际感觉上,不论建筑,硬件还是软件,理论,我们都已经高于欧美了,那为什么还说我们不如欧美呢?科学发现是高于科技发明就很好的解释了这个问题,即,我......
  • 记录使用python遇到的问题
    pycharm和python版本问题pycharm官网从官网上查看不同版本的pycharm支持什么版本的python。版本不兼容,后续会出现一些莫名其妙的问题。比如说:我安装的是python3.11.3版本,但是提示的有误,以及一些报错。而且在创建虚拟环境的时候也一直有问题。如何卸载pycharm使用Uni......
  • Python字典加入元素
    Python字典是一种非常有用的数据结构,它可以存储键值对,并且键是唯一的。在实际应用中,我们常常需要向字典中添加元素以满足特定需求。本文将从多个方面详细阐述Python字典加入元素的方法和技巧。一、直接赋值最简单的向字典中加入元素的方式就是通过直接赋值来实现。例如,我们有一......
  • python所有内置函数的简介和用法示例
    以下是python所有内置函数的简介和用法示例:序号函数名简介用法示例1__build_class__用于构建类的内部函数,通常不直接使用-(高级用法,不常直接调用)2__import__动态导入模块module=__import__('math')然后可以使用module.sqrt(9)3abs返回数字的绝对值p......
  • 使用Python脚本之家商品列表实现的解析
    本文将详细介绍如何使用Python脚本之家商品列表来实现各种功能。通过对不同方面的阐述,帮助读者更好地理解和应用这个功能。一、创建商品列表1、首先,我们需要导入所需的库,如下所示:代码语言:javascript复制importrequestsfrombs4importBeautifulSoup2、接下来,我们可以使用......
  • 8.python字典
    文章目录Python字典(Dictionary)深度总结1.字典的基本概念2.访问字典中的值3.修改字典4.遍历字典5.字典的内置函数和方法6.字典的高级用法6.1字典推导式(DictionaryComprehensions)6.2字典的浅拷贝与深拷贝6.3字典的合并6.4字典的默认值6.5字典的排序7.......
  • 【华为OD-E卷-寻找链表的中间结点 100分(python、java、c++、js、c)】
    【华为OD-E卷-寻找链表的中间结点100分(python、java、c++、js、c)】题目给定一个单链表L,请编写程序输出L中间结点保存的数据。如果有两个中间结点,则输出第二个中间结点保存的数据。例如:给定L为1→7→5,则输出应该为7;给定L为1→2→3→4,则输出应该为3;输入描述......
  • 【华为OD-E卷-字符串重新排序 字符串重新排列 100分(python、java、c++、js、c)】
    【华为OD-E卷-字符串重新排序字符串重新排列100分(python、java、c++、js、c)】题目给定一个字符串s,s包括以空格分隔的若干个单词,请对s进行如下处理后输出:1、单词内部调整:对每个单词字母重新按字典序排序2、单词间顺序调整:1)统计每个单词出现的次数,并按次数降序排列2)次......