您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 湘潭分类信息网,免费分类信息发布

Python如何实现射击闯关游戏

2024/5/28 19:22:58发布31次查看
项目功能地图编辑器:可以实现玩家自己定义每一关卡的样式和难易程度
运行界面:实现了玩家的移动,跳跃,发射子弹,投掷手雷,以及敌人的al(移动,发射子弹,扔手雷),同时游戏中有一系列的道具(生命值药箱,子弹补给,手雷补给)以及各种动画和音乐音效,还有各种花草岩石装饰品,以及悬崖和水涡危险地方,更多未知,自己体验就能感受到!
总代码累计1100行左右!
地图编辑器import pygameimport sysimport csvimport buttonpygame.init()# 定义一个时钟clock = pygame.time.clock()fps = 60# 游戏窗口screen_width = 800screen_height = 560lower_margin = 100side_magtin = 300screen = pygame.display.set_mode((screen_width + side_magtin, screen_height + lower_margin))pygame.display.set_caption("级别编辑器")# 定义游戏变量rows = 16max_cols = 150tile_size = screen_height // rowstile_types = 21level = 1current_tile = 0scroll_left = falsescroll_right = falsescroll = 0scroll_speed = 1# 加载背景图片pine1_img = pygame.image.load("img/background/pine1.png").convert_alpha()pine2_img = pygame.image.load("img/background/pine2.png").convert_alpha()mountain_img = pygame.image.load("img/background/mountain.png").convert_alpha()sky_img = pygame.image.load("img/background/sky_cloud.png").convert_alpha()# 瓷砖瓦片列表img_list = []for x in range(tile_types): img = pygame.image.load(f"img/tile/{x}.png") img = pygame.transform.scale(img, (tile_size, tile_size)) img_list.append(img)# 创建保存按钮save_img = pygame.image.load("img/save_btn.png").convert_alpha()load_img = pygame.image.load("img/load_btn.png").convert_alpha()# 定义颜色green = (144, 201, 120)white = (255, 255, 255)red = (200, 25, 25)#定义字体font = pygame.font.sysfont("futura", 30)# 创建空的瓷砖列表(二维)world_data = []for row in range(rows): r = [-1] * max_cols world_data.append(r)# 创建一个组for tile in range(0, max_cols): world_data[rows - 1][tile] = 0# 在屏幕上显示下一级定义文本显示函数def draw_text(text, font, text_color, x, y): img = font.render(text, true, text_color) screen.blit(img, (x, y))# 创建背景函数def draw_bg(): screen.fill(green) width = sky_img.get_width() for x in range(4): screen.blit(sky_img, ((x * width) - scroll * 0.5, 0)) screen.blit(mountain_img, ((x * width) - scroll * 0.6, screen_height - mountain_img.get_height() - 300)) screen.blit(pine1_img, ((x * width) - scroll * 0.7, screen_height - pine1_img.get_height() - 150)) screen.blit(pine2_img, ((x * width) - scroll * 0.8, screen_height - pine2_img.get_height()))# 绘制格子def draw_grid(): # 垂直的线 for c in range(max_cols + 1): pygame.draw.line(screen, white, (c * tile_size - scroll, 0), (c * tile_size - scroll, screen_height)) # 水平的线 for c in range(rows + 1): pygame.draw.line(screen, white, (0, c * tile_size), (screen_width, c * tile_size))# 在地图中绘制瓷砖def draw_world(): for y, row in enumerate(world_data): for x, tile in enumerate(row): if tile >= 0: screen.blit(img_list[tile], (x * tile_size - scroll, y * tile_size))# 创建按钮# 创建保存和加载数据按钮save_button = button.button(screen_width // 2, screen_height + lower_margin - 50, save_img, 1)load_button = button.button(screen_width // 2 + 200, screen_height + lower_margin - 50, load_img, 1)# 制作一个按钮瓷片列表button_list = []button_col = 0button_row = 0for i in range(len(img_list)): tile_button = button.button(screen_width + (75 * button_col) + 50, 75 * button_row + 50, img_list[i], 1) button_list.append(tile_button) button_col += 1 if button_col == 3: button_row += 1 button_col = 0run = truewhile run: clock.tick(fps) draw_bg() draw_grid() draw_world() draw_text(f"level: {level}", font, white, 10, screen_height + lower_margin - 90) draw_text("press up or down to change level", font, white, 10, screen_height + lower_margin - 60) # 保存和加载地图数据 if save_button.draw(screen): # 保存级别数据 with open(f"level{level}_data.csv", "w", newline="") as csvfile: writer = csv.writer(csvfile, delimiter = ",") for row in world_data: writer.writerow(row) # with open(f"level{level}_data.csv", "wb") as pickle_out: # pickle.dump(world_data, pickle_out) if load_button.draw(screen): # 加载地图级别数据 # 重置滚动scroll为起始位置0 scroll = 0 with open(f"level{level}_data.csv", "r", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for y, row in enumerate(reader): for x, tile in enumerate(row): world_data[y][x] = int(tile) # 画面板和瓷砖 pygame.draw.rect(screen, green, (screen_width, 0, side_magtin, screen_height)) # 选择一种瓷砖,获取右侧瓷砖列表的具体 button_count = 0 for button_count, i in enumerate(button_list): if i.draw(screen): current_tile = button_count # 高亮显示选中的瓷砖 pygame.draw.rect(screen, red, button_list[current_tile].rect, 3) # 滚动地图 if scroll_left == true and scroll > 0: scroll -= 5 * scroll_speed if scroll_right == true and scroll < (max_cols * tile_size) - screen_width: # 检测最右边的边缘 scroll += 5 * scroll_speed # 在窗口中增加新的瓷砖 # 获取鼠标的位置 pos = pygame.mouse.get_pos() x = (pos[0] + scroll) // tile_size y = pos[1] // tile_size # 检测点击的区域,把右侧获取的瓷片放在地图中 if pos[0] < screen_width and pos[1] < screen_height: # 更新瓷砖的值 if pygame.mouse.get_pressed()[0] == 1: if world_data[y][x] != current_tile: world_data[y][x] = current_tile # 删除选中的 if pygame.mouse.get_pressed()[2] == 1: world_data[y][x] = -1 for event in pygame.event.get(): if event.type == pygame.quit: run = false pygame.quit() sys.exit() # 键盘按键 if event.type == pygame.keydown: if event.key == pygame.k_up: level += 1 if event.key == pygame.k_down and level > 0: level -= 1 if event.key == pygame.k_left: scroll_left = true if event.key == pygame.k_right: scroll_right = true if event.key == pygame.k_lshift: scroll_speed = 5 if event.type == pygame.keyup: if event.key == pygame.k_left: scroll_left = false if event.key == pygame.k_right: scroll_right = false if event.key == pygame.k_lshift: scroll_speed = 1 pygame.display.update()
游戏主运行程序import pygamefrom pygame import mixerimport sysimport osimport randomimport csvimport buttonimport mathmixer.init()pygame.init()# 画布元素screen_width = 800screen_height = int(screen_width * 0.8)screen = pygame.display.set_mode((screen_width, screen_height))pygame.display.set_caption("射击游戏")# 设置帧clock = pygame.time.clock()fps = 60# 定义游戏变量gravity = 0.75scroll_thresh = 200rows = 16cols = 150tile_size = screen_height // rowstile_types = 21max_levels = 3screen_scroll = 0bg_scroll = 0level = 1# 定义游戏状态start_game = false# 定义是否淡入进入游戏画面start_intro = false# 定义玩家状态变量moving_left = falsemoving_right = falseshoot = falsegrenade = falsegrenade_thrown = false#加载音乐和声音pygame.mixer.music.load("audio/music2.mp3")pygame.mixer.music.set_volume(0.3)pygame.mixer.music.play(-1, 0.0, 3000)jump_fx = pygame.mixer.sound("audio/jump.wav")jump_fx.set_volume(0.5)shot_fx = pygame.mixer.sound("audio/shot.wav")shot_fx.set_volume(0.9)grenade_fx = pygame.mixer.sound("audio/grenade.wav")grenade_fx.set_volume(0.9)# 加载背景图片pine1_img = pygame.image.load("img/background/pine1.png").convert_alpha()pine2_img = pygame.image.load("img/background/pine2.png").convert_alpha()mountain_img = pygame.image.load("img/background/mountain.png").convert_alpha()sky_img = pygame.image.load("img/background/sky_cloud.png").convert_alpha()# 加载按钮图像start_img = pygame.image.load("img/start_btn.png").convert_alpha()exit_img = pygame.image.load("img/exit_btn.png").convert_alpha()restart_img = pygame.image.load("img/restart_btn.png").convert_alpha()# 加载21种瓷砖图像放在瓷砖图像列表中img_list = []for x in range(tile_types): img = pygame.image.load(f"img/tile/{x}.png") img = pygame.transform.scale(img, (tile_size, tile_size)) img_list.append(img)# 加载子弹bullet_img = pygame.image.load("img/icons/bullet.png").convert_alpha()grenade_img = pygame.image.load("img/icons/grenade.png").convert_alpha()# 加载物品health_box_img = pygame.image.load("img/icons/health_box.png").convert_alpha()ammo_box_img = pygame.image.load("img/icons/ammo_box.png").convert_alpha()grenade_box_img = pygame.image.load("img/icons/grenade_box.png").convert_alpha()item_boxes = { "health": health_box_img, "ammo": ammo_box_img, "grenade": grenade_box_img}# 定义颜色bg = (144, 201, 120)red = (255, 0, 0)white = (255, 255, 255)green = (0, 255, 0)black = (0, 0, 0)pink = (235, 65, 54)# 定义字体font = pygame.font.sysfont("futura", 30)# 定义一个显示文本函数,用来显示玩家的相关属性def draw_text(text, font, text_color, x, y): img = font.render(text, true, text_color) screen.blit(img, (x, y))# 刷新背景函数,for循环重复背景,刷新背景中不同的照片的x坐标,以此达到背景动态效果def draw_bg(): screen.fill(bg) width = sky_img.get_width() for x in range(5): screen.blit(sky_img, ((x * width) - bg_scroll * 0.5, 0)) screen.blit(mountain_img, ((x * width) - bg_scroll * 0.6, screen_height - mountain_img.get_height() - 300)) screen.blit(pine1_img, ((x * width) - bg_scroll * 0.7, screen_height - pine1_img.get_height() - 150)) screen.blit(pine2_img, ((x * width) - bg_scroll * 0.8, screen_height - pine2_img.get_height()))# 重置游戏函数定义,碰撞”通关“瓷片时,清空本关的所有显示元素def reset_level(): enemy_group.empty() bullet_group.empty() grenade_group.empty() explosion_group.empty() item_box_group.empty() decoration_group.empty() water_group.empty() exit_group.empty() # 创建空的瓷砖列表。二维列表行列 data = [] for row in range(rows): r = [-1] * cols data.append(r) return data# 创建士兵类(敌人和玩家)class soldier(pygame.sprite.sprite): def __init__(self, char_type, x, y, scale, speed, ammo, grenades): super().__init__() self.alive = true # 定义或者还是死亡变量 self.char_type = char_type # 获取文件类型样式 self.speed = speed # 速度 self.ammo = ammo # 子弹 self.start_ammo = ammo self.shoot_cooldown = 0 # 冷却 self.grenades = grenades # 手雷 self.health = 100 # 生命值 self.max_health = self.health self.direction = 1 # 默认方向右 self.vel_y = 0 # 垂直 self.jump = false # 跳跃 self.in_air = true # 是否在空中 self.flip = false # 默认左为false self.animation_list = [] # 动画列表 self.frame_index = 0 # 索引 self.action = 0 # 选择动作变量 self.update_time = pygame.time.get_ticks() # 以毫秒为单位获取时间 # 创建ai特定变量 self.move_counter = 0 # 移动计数,对应下文敌人来回徘徊 self.vision = pygame.rect(0, 0, 150, 20) # 搜索玩家在玩家视线之内 self.idling = false # 闲置状态,对应下文ai开枪和扔手雷的状态 self.idling_counter = 0 # 闲置计数 self.grenade_time = pygame.time.get_ticks() # 对应下文手雷爆炸时间 # 加载玩家是所有的图片类型 animation_types = ["idle", "run", "jump", "death"] for animation in animation_types: # 重置临时列表 temp_list = [] # 统计每种动画帧数量 num_of_frames = len(os.listdir(f"img/{char_type}/{animation}")) for i in range(num_of_frames): img = pygame.image.load(f"img/{char_type}/{animation}/{i}.png").convert_alpha() img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale))) temp_list.append(img) self.animation_list.append(temp_list) self.image = self.animation_list[self.action][self.frame_index] self.rect = self.image.get_rect() self.rect.center = (x, y)# rect=(x,y,w,h) self.width = self.image.get_width() self.height = self.image.get_height() def update(self): self.update_animation() self.check_alive() # 更新冷却时间 if self.shoot_cooldown > 0: self.shoot_cooldown -= 1 def move(self, moving_left, moving_right): # 重置移动变量 screen_scroll = 0 dx = 0 dy = 0 # 根据移动变量判断向左还是向右移动 if moving_left: dx = -self.speed self.flip = true self.direction = -1 if moving_right: dx = self.speed self.flip = false self.direction = 1 # 跳跃 if self.jump == true and self.in_air == false: self.vel_y = -11 self.jump = false self.in_air = true # 使用重力,让其在y方向跳跃高度进行限制 self.vel_y += gravity if self.vel_y > 10: self.vel_y dy += self.vel_y # 检测与地面的碰撞 for tile in world.obstacle_list: # 检测玩家与每个地面瓷砖x方向上的碰撞 if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height): dx = 0 # 检测如果是ai机器人碰到墙就返回 if self.char_type == "enemy": self.direction *= -1 self.move_counter = 0 # 检车玩家与瓷砖y方向上的碰撞 if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height): # 检测与地面底部的碰撞 if self.vel_y < 0: self.vel_y = 0 dy = tile[1].bottom - self.rect.top # 检测与地面顶部的碰撞 elif self.vel_y >= 0: self.vel_y = 0 self.in_air = false dy = tile[1].top - self.rect.bottom # 检测与水面的碰撞 if pygame.sprite.spritecollide(self, water_group, false): self.health = 0 # 检车与出口标志碰撞 level_complete = false if pygame.sprite.spritecollide(self, exit_group, false): level_complete = true # 检测从地图上坠落下来 if self.rect.bottom > screen_height: self.health = 0 # 检测是否走到窗口的边缘,如果走到窗口边缘就不让再走了 if self.char_type == "player": if self.rect.left + dx < 0 or self.rect.right + dx > screen_width: dx = 0 # 更新矩形的位置 self.rect.x += dx self.rect.y += dy # 在玩家位置的基础上更新滚动平台 rect.right 对应矩形的左,以此类推 if self.char_type == "player": if (self.rect.right > screen_width - scroll_thresh and bg_scroll < world.level_length * tile_size - screen_width)\ or (self .rect.left < scroll_thresh and bg_scroll > abs(dx)): self.rect.x -= dx screen_scroll = -dx return screen_scroll, level_complete def shoot(self): if self.shoot_cooldown == 0 and self.ammo > 0: self.shoot_cooldown = 20 bullet = bullet(self.rect.centerx + (0.75 * self.rect.size[0] * self.direction), self.rect.centery, self.direction) bullet_group.add(bullet) #减少弹药 self.ammo -= 1 shot_fx.play() def ai(self): if self.alive and player.alive: if self.idling == false and random.randint(1, 100) == 1: self.update_action(0) # 选择闲置动作 self.idling = true # ai检测到我方士兵在附近 if self.vision.colliderect(player.rect): # 停止奔跑并面向玩家的时候 self.update_action(0) # 并射击 self.shoot() else: # 不定时扔手雷 now_time = pygame.time.get_ticks() if math.sqrt(math.pow(abs(self.rect.centerx - player.rect.centerx), 2) + math.pow( abs(self.rect.centery - player.rect.centery), 2)) < tile_size * 5: if self.grenades > 0: if now_time - self.grenade_time > random.randint(2000, 3000): # 停止奔跑并面向玩家的时候 self.update_action(0) self.grenade_time = pygame.time.get_ticks() grenade = grenade(self.rect.centerx, self.rect.centery, self.direction) grenade_group.add(grenade) self.grenades -= 1 if self.idling == false: if self.direction == 1: ai_moving_right = true self.idling_counter = 50 else: ai_moving_right = false ai_moving_left = not ai_moving_right self.move(ai_moving_left, ai_moving_right) self.update_action(1) # 选择运动动作 self.move_counter += 1 # 更新ai视觉范围作为移动范围 self.vision.center = (self.rect.centerx + 75 * self.direction, self.rect.centery) # pygame.draw.rect(screen, red, self.vision) if self.move_counter > tile_size: self.direction *= -1 self.move_counter *= -1 else: self.idling_counter -= 1 if self.idling_counter <= 0: self.idling = false # 滚动 self.rect.x += screen_scroll def update_animation(self): # 更新动画 animation_cooldown= 100 # 更新当前的帧 self.image = self.animation_list[self.action][self.frame_index] # 检测现在的时间更新时间 if pygame.time.get_ticks() - self.update_time > animation_cooldown: self.update_time = pygame.time.get_ticks() self.frame_index += 1 # 检测如果列表索引超出了动画帧数 if self.frame_index >= len(self.animation_list[self.action]): if self.action == 3: self.frame_index = len(self.animation_list[self.action]) - 1 else: self.frame_index = 0 def update_action(self, new_action): # 判断不同的行动播放不同的动画 if new_action != self.action: self.action = new_action # 更新动画设置 self.frame_index = 0 self.update_time = pygame.time.get_ticks() def check_alive(self): if self.health <= 0: self.health = 0 self.speed = 0 self.alive = false self.update_action(3) def draw(self): screen.blit(pygame.transform.flip(self.image, self.flip, false), self.rect)# 收集物品类class itembox(pygame.sprite.sprite): def __init__(self, item_type, x, y): super().__init__() self.item_type = item_type self.image = item_boxes.get(self.item_type) self.rect = self.image.get_rect() self.rect.midtop = (x + tile_size // 2, y + (tile_size - self.image.get_height())) def update(self): # 滚动 self.rect.x += screen_scroll # 检车士兵与物品的碰撞 if pygame.sprite.collide_rect(self, player): # 检测获取箱子的种类 if self.item_type == "health": player.health += 25 if player.health > player.max_health: player.health = player.max_health elif self.item_type == "ammo": player.ammo += 15 elif self.item_type == "grenade": player.grenades += 3 # 删除物品 self.kill()# 创建血条类class healthbar(): def __init__(self, x, y, health, max_health): self.x = x self.y = y self.health = health self.max_health = max_health def draw(self, health): # 更新最新血条 self.health = health # 计算血条的比率 ratio = self.health / self.max_health pygame.draw.rect(screen, black, (self.x - 2, self.y - 2, 154, 24)) pygame.draw.rect(screen, red, (self.x, self.y, 150, 20)) pygame.draw.rect(screen, green, (self.x, self.y, 150 * ratio, 20))class bullet(pygame.sprite.sprite): def __init__(self, x, y, direction): super().__init__() self.speed = 10 self.image = bullet_img self.rect = self.image.get_rect() self.rect.center = (x, y) self.direction = direction def update(self): # 移动子弹 self.rect.x += (self.direction * self.speed) + screen_scroll # 子弹射出也要一起移动 # 检测子弹与地面瓷砖的碰撞 for tile in world.obstacle_list: if tile[1].colliderect(self.rect): self.kill() # 检测子弹的碰撞 if pygame.sprite.spritecollide(player, bullet_group, false): if player.alive: player.health -= 5 self.kill() for enemy in enemy_group: if pygame.sprite.spritecollide(enemy, bullet_group, false): if enemy.alive: enemy.health -= 25 self.kill()# 创建手雷class grenade(pygame.sprite.sprite): def __init__(self, x, y, direction): super().__init__() self.timer = 90 self.vel_y = -11 self.speed = 7 self.image = grenade_img self.rect = self.image.get_rect() self.rect.center = (x, y) self.direction = direction self.width = self.image.get_width() self.height = self.image.get_height() def update(self): self.vel_y += gravity dx = self.direction * self.speed dy = self.vel_y # 检测手雷与每个瓷砖的碰撞 for tile in world.obstacle_list: # 检测与瓷砖墙壁的碰撞 if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height): self.direction *= -1 dx = self.direction * self.speed # 检测与y方向上的碰撞 if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height): self.speed = 0 # 检测与地面底部的碰撞向下反弹 if self.vel_y < 0: self.vel_y = 0 dy = tile[1].bottom - self.rect.top # 检测与地面顶部的碰撞 elif self.vel_y >= 0: self.vel_y = 0 self.in_air = false dy = tile[1].top - self.rect.bottom # 更新受累的位置 self.rect.x += dx + screen_scroll # 手雷扔出也需要加上滚动的量 self.rect.y += dy # 手雷爆炸冷却时间 self.timer -= 1 if self.timer <= 0: self.kill() grenade_fx.play() explosion = explosion(self.rect.x, self.rect.y, 0.8) explosion_group.add(explosion) # 爆炸后对任何人在一定的范围内都有伤害 if abs(self.rect.centerx - player.rect.centerx) < tile_size * 2 and \ abs(self.rect.centery - player.rect.centery) < tile_size * 2: player.health -= 10 for enemy in enemy_group: # if abs(self.rect.centerx - enemy.rect.centerx) < tile_size and \ # abs(self.rect.centery - enemy.rect.centery) < tile_size: # enemy.health -= 100 if abs(self.rect.centerx - enemy.rect.centerx) < tile_size * 2 and \ abs(self.rect.centery - enemy.rect.centery) < tile_size * 2: enemy.health -= 50# 创建地图的类class world(): def __init__(self): self.obstacle_list = [] # 障碍列表 def process_data(self, data1): self.level_length = len(data1[0]) # 迭代加载数据的每个值 for y, row in enumerate(data1): for x, tile in enumerate(row): if tile >= 0: img = img_list[tile] img_rect = img.get_rect() img_rect.x = x * tile_size img_rect.y = y * tile_size tile_data = (img, img_rect) if tile >= 0 and tile <= 8: # 地面泥块 self.obstacle_list.append(tile_data) elif tile >= 9 and tile <= 10: # 水 water = water(img, x * tile_size, y * tile_size) water_group.add(water) elif tile >= 11 and tile <= 14: # 装饰类型的 decoration = decoration(img, x * tile_size, y * tile_size) decoration_group.add(decoration) elif tile == 15: # 创建玩家自己 player = soldier("player", x * tile_size, y * tile_size, 1.65, 5, 30, 10) health_bar = healthbar(10, 10, player.health, player.health) elif tile == 16: # 创建敌人 enemy = soldier("enemy", x * tile_size, y * tile_size, 1.65, 2, 20, 5) enemy_group.add(enemy) elif tile == 17: # 收集弹药 item_box = itembox("ammo", x * tile_size, y * tile_size) item_box_group.add(item_box) elif tile == 18: # 收集手雷 item_box = itembox("grenade", x * tile_size, y * tile_size) item_box_group.add(item_box) elif tile == 19: # 收集医药 item_box = itembox("health", x * tile_size, y * tile_size) item_box_group.add(item_box) elif tile == 20: # 出口 exit = exit(img, x * tile_size, y * tile_size) exit_group.add(exit) return player, health_bar def draw(self): for tile in self.obstacle_list: tile[1][0] += screen_scroll screen.blit(tile[0], tile[1])# 装饰品类class decoration(pygame.sprite.sprite): def __init__(self, img, x, y): super().__init__() self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + tile_size // 2, y + (tile_size - self.image.get_height())) def update(self): self.rect.x += screen_scroll# 创建水类class water(pygame.sprite.sprite): def __init__(self, img, x, y): super().__init__() self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + tile_size // 2, y + (tile_size - self.image.get_height())) def update(self): self.rect.x += screen_scroll# 创建出口class exit(pygame.sprite.sprite): def __init__(self, img, x, y): super().__init__() self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + tile_size // 2, y + (tile_size - self.image.get_height())) def update(self): self.rect.x += screen_scroll# 创建爆炸类class explosion(pygame.sprite.sprite): def __init__(self, x, y, scale): super().__init__() self.images = [] for num in range(1, 6): img = pygame.image.load(f"img/explosion/exp{num}.png").convert_alpha() img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale))) self.images.append(img) self.frame_index = 0 self.image = self.images[self.frame_index] self.rect = self.image.get_rect() self.rect.center = (x, y) self.counter = 0 def update(self): # 爆炸加滚动 self.rect.x += screen_scroll explosion_speed = 4 # 更新爆炸动画 self.counter += 1 if self.counter >= explosion_speed: self.counter = 0 self.frame_index += 1 # 检测爆炸完成后删除爆炸 if self.frame_index >= len(self.images): self.kill() else: self.image = self.images[self.frame_index]class screenfade(): def __init__(self, direction, color, speed): self.direction = direction self.color = color self.speed = speed self.fade_counter = 0 def fade(self): fade_complete = false # 定义判断是否完成覆盖 self.fade_counter += self.speed if self.direction == 1: #所有类型的淡入淡出 pygame.draw.rect(screen, self.color, (0 - self.fade_counter, 0, screen_width // 2, screen_height)) # 向左拉开序幕 pygame.draw.rect(screen, self.color, (screen_width // 2 + self.fade_counter, 0, screen_width, screen_height)) # 向右拉开序幕 pygame.draw.rect(screen, self.color, (0, 0 - self.fade_counter, screen_width, screen_height // 2)) pygame.draw.rect(screen, self.color, (0, screen_height // 2 + self.fade_counter, screen_width, screen_height)) if self.direction == 2: # 垂直向下淡入 pygame.draw.rect(screen, self.color, (0, 0, screen_width, 0 + self.fade_counter)) if self.fade_counter >= screen_width: fade_complete = true return fade_complete# 创建淡入淡出intro_fade = screenfade(1, black, 4)death_fade = screenfade(2, pink, 4)#创建开始、退出、重置菜单按钮start_button = button.button(screen_width // 2 - 130, screen_height // 2 - 150, start_img, 1)exit_button = button.button(screen_width // 2 - 110, screen_height // 2 + 50, exit_img, 1)restart_button = button.button(screen_width // 2 - 70, screen_height // 2 - 50, restart_img, 1)#创建群组enemy_group = pygame.sprite.group()bullet_group = pygame.sprite.group()grenade_group = pygame.sprite.group()explosion_group = pygame.sprite.group()item_box_group = pygame.sprite.group()decoration_group = pygame.sprite.group()water_group = pygame.sprite.group()exit_group = pygame.sprite.group()# 创建空的瓷砖列表world_data = []for row in range(rows): r = [-1] * cols world_data.append(r)# 加载级别数据创建地图with open(f"level{level}_data.csv", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for y, row in enumerate(reader): for x, tile in enumerate(row): world_data[y][x] = int(tile)world = world()player, health_bar = world.process_data(world_data)run = truewhile run: clock.tick(fps) if start_game == false: # 显示主菜单 # 画菜单 screen.fill(bg) # 增加按钮 if start_button.draw(screen): start_game = true start_intro = true if exit_button.draw(screen): run = false else: draw_bg() # 显示地图 world.draw() # 显示血条 health_bar.draw(player.health) # 显示弹药量 draw_text("ammo: ", font, white, 10, 35) for x in range(player.ammo): screen.blit(bullet_img, (90 + (x * 10), 40)) # 显示手雷量 draw_text("grenades: ", font, white, 10, 60) for x in range(player.grenades): screen.blit(grenade_img, (135 + (x * 15), 60)) # 显示血条量 # draw_text(f"ammo: {player.ammo}", font, white, 10, 35) player.update() player.draw() for enemy in enemy_group: enemy.ai() enemy.update() enemy.draw() # 更新和画组 bullet_group.update() grenade_group.update() explosion_group.update() item_box_group.update() decoration_group.update() water_group.update() exit_group.update() bullet_group.draw(screen) grenade_group.draw(screen) explosion_group.draw(screen) item_box_group.draw(screen) decoration_group.draw(screen) water_group.draw(screen) exit_group.draw(screen) # 显示淡入 if start_intro: if intro_fade.fade(): start_intro = false intro_fade.fade_counter = 0 # 更新玩家的动作 if player.alive: # 发射子弹 if shoot: player.shoot() # 扔手雷 elif grenade and grenade_thrown == false and player.grenades > 0: grenade = grenade(player.rect.centerx + (0.5 * player.rect.size[0] * player.direction), player.rect.top, player.direction) grenade_group.add(grenade) player.grenades -= 1 grenade_thrown = true if player.in_air: player.update_action(2) elif moving_left or moving_right: player.update_action(1) else: player.update_action(0) screen_scroll, level_complete = player.move(moving_left, moving_right) bg_scroll -= screen_scroll # 检测玩家是否通过该级别,把二位列表的具体位置(某一行的某一列)赋值 if level_complete: start_intro = true level += 1 bg_scroll = 0 world_data = reset_level() if level <= max_levels: # 加载级别数据创建地图 with open(f"level{level}_data.csv", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for y, row in enumerate(reader): for x, tile in enumerate(row): world_data[y][x] = int(tile) world = world() player, health_bar = world.process_data(world_data) else: screen_scroll = 0 if death_fade.fade(): # 完成覆盖后才出现按钮中间时间过渡 if restart_button.draw(screen): death_fade.fade_counter = 0 # 计数清零 start_intro = true bg_scroll = 0 world_data = reset_level() # 加载级别数据创建地图 with open(f"level{level}_data.csv", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for y, row in enumerate(reader): for x, tile in enumerate(row): world_data[y][x] = int(tile) world = world() player, health_bar = world.process_data(world_data) for event in pygame.event.get(): # 退出游戏 if event.type == pygame.quit: run = false pygame.quit() sys.exit() # 键盘按键 if event.type == pygame.keydown: if event.key == pygame.k_a: moving_left = true if event.key == pygame.k_d: moving_right = true if event.key == pygame.k_space: shoot = true if event.key == pygame.k_q: grenade = true if event.key == pygame.k_w and player.alive: player.jump = true jump_fx.play() if event.key == pygame.k_escape: run = false # 按键释放 if event.type == pygame.keyup: if event.key == pygame.k_a: moving_left = false if event.key == pygame.k_d: moving_right = false if event.key == pygame.k_space: shoot = false if event.key == pygame.k_q: grenade = false grenade_thrown = false pygame.display.update()
以上就是python如何实现射击闯关游戏的详细内容。
湘潭分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录