Я работаю над игрой на основе тайлов. Я уже создал 3 уровня для игры, но теперь я не знаю, как загрузить новые уровни в игре. Игра начинается на уровне 1, и после обработки всех мобов она начинает уровень 2, но после обработки всех мобов на уровне 2 она не загружает уровень 3. Вместо этого она перезапускается на уровне 2. Я думаю, что моя ошибка в обновлении раздел кода, но так как я все еще очень неопытен, это может быть больше, чем просто «одна» ошибка в этом коде. Я был бы рад, если бы кто-нибудь мог помочь мне
вот мой main.py кода:
import pygame as pg
import sys
from os import path
from settings import *
from sprites import *
from tilemap import *
# HUD functions
def draw_player_health(surf, x, y, pct):
if pct < 0:
pct = 0
BAR_LENGTH = 100
BAR_HEIGHT = 20
fill = pct * BAR_LENGTH
outline_rect = pg.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
fill_rect = pg.Rect(x, y, fill, BAR_HEIGHT)
if pct > 0.6:
col = GREEN
elif pct > 0.3:
col = YELLOW
else:
col = RED
pg.draw.rect(surf, col, fill_rect)
pg.draw.rect(surf, BLACK, outline_rect, 2)
class Game:
def __init__(self):
pg.mixer.pre_init(44100, -16, 2, 2048)
pg.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
self.load_data()
self.level = 0
def draw_text(self, text, font_name, size, color, x, y, align="nw"):
font = pg.font.Font(font_name, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
if align == "nw":
text_rect.topleft = (x, y)
if align == "ne":
text_rect.topright = (x, y)
if align == "sw":
text_rect.bottomleft = (x, y)
if align == "se":
text_rect.bottomright = (x, y)
if align == "n":
text_rect.midtop = (x, y)
if align == "s":
text_rect.midbottom = (x, y)
if align == "e":
text_rect.midright = (x, y)
if align == "w":
text_rect.midleft = (x, y)
if align == "center":
text_rect.center = (x, y)
self.screen.blit(text_surface, text_rect)
def load_data(self):
game_folder = path.dirname(__file__)
img_folder = path.join(game_folder, 'img')
self.map_folder = path.join(game_folder, 'maps')
sfx_folder = path.join(game_folder, "sfx")
music_folder = path.join(game_folder, "music")
self.title_font = path.join(img_folder, "ZOMBIE.TTF")
self.hud_font = path.join(img_folder, "Impacted2.0.ttf")
self.dim_screen = pg.Surface(self.screen.get_size()).convert_alpha()
self.dim_screen.fill((0, 0, 0, 180))
self.player_img = pg.image.load(path.join(img_folder, PLAYER_IMG)).convert_alpha()
self.mob_img = pg.image.load(path.join(img_folder, MOB_IMG)).convert_alpha()
self.wall_img = pg.image.load(path.join(img_folder, WALL_IMG)).convert_alpha()
self.wall_img = pg.transform.scale(self.wall_img, (TILESIZE, TILESIZE))
self.bullet_images = {}
self.bullet_images["lg"] = pg.image.load(path.join(img_folder, BULLET_IMG)).convert_alpha()
self.bullet_images["sm"] = pg.transform.scale(self.bullet_images["lg"], (10, 10))
self.splat = pg.image.load(path.join(img_folder, SPLAT)).convert_alpha()
self.splat = pg.transform.scale(self.splat, (64, 64))
self.gun_flashes = []
for img in MUZZLE_FLASHES:
self.gun_flashes.append(pg.image.load(path.join(img_folder, img)).convert_alpha())
self.item_images = {}
for item in ITEM_IMAGES:
self.item_images[item] = pg.image.load(path.join(img_folder, ITEM_IMAGES[item])).convert_alpha()
# lighting effect
self.fog = pg.Surface((WIDTH, HEIGHT))
self.fog.fill(NIGHT_COLOR)
self.light_mask = pg.image.load(path.join(img_folder, LIGHT_MASK)).convert_alpha()
self.light_mask = pg.transform.scale(self.light_mask, LIGHT_RADIUS)
self.light_rect = self.light_mask.get_rect()
# SOUND LOADING
pg.mixer.music.load(path.join(music_folder, BG_MUSIC))
self.effects_sounds = {}
for type in EFFECTS_SOUNDS:
self.effects_sounds[type] = pg.mixer.Sound(path.join(sfx_folder, EFFECTS_SOUNDS[type]))
self.weapon_sounds = {}
for weapon in WEAPON_SOUNDS:
self.weapon_sounds[weapon] = []
for sfx in WEAPON_SOUNDS[weapon]:
s = pg.mixer.Sound(path.join(sfx_folder, sfx))
s.set_volume(0.2)
self.weapon_sounds[weapon].append(s)
self.zombie_moan_sounds = []
for sfx in ZOMBIE_MOAN_SOUNDS:
s = pg.mixer.Sound(path.join(sfx_folder, sfx))
s.set_volume(0.2)
self.zombie_moan_sounds.append(s)
self.player_hit_sounds = []
for sfx in PLAYER_HIT_SOUNDS:
self.player_hit_sounds.append(pg.mixer.Sound(path.join(sfx_folder, sfx)))
self.zombie_hit_sounds = []
for sfx in ZOMBIE_HIT_SOUNDS:
self.zombie_hit_sounds.append(pg.mixer.Sound(path.join(sfx_folder, sfx)))
def new(self):
# initialize all variables and do all the setup for a new game
self.all_sprites = pg.sprite.LayeredUpdates()
self.walls = pg.sprite.Group()
self.bullets = pg.sprite.Group()
self.mobs = pg.sprite.Group()
self.items = pg.sprite.Group()
self.map = Tiled_Map(path.join(self.map_folder, 'level1.tmx'))
self.map_image = self.map.make_map()
self.map_rect = self.map_image.get_rect()
# for row, tiles in enumerate(self.map.data):
# for col, tile in enumerate(tiles):
# if tile == '1':
# Wall(self, col, row)
# if tile == 'M':
# Mob(self, col, row)
# if tile == 'P':
# self.player = Player(self, col, row)
for tile_object in self.map.tmxdata.objects:
obj_center = vec(tile_object.x + tile_object.width / 2, tile_object.y + tile_object.height / 2)
if tile_object.name == "player":
self.player = Player(self, obj_center.x, obj_center.y)
if tile_object.name == "zombie":
Mob(self, obj_center.x, obj_center.y)
if tile_object.name == "wall":
Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height)
if tile_object.name in ["health", "shotgun", "m_gun", "desert_eagle"]:
Item(self, obj_center, tile_object.name)
self.camera = Camera(self.map.width, self.map.height)
self.draw_debug = False
self.paused = False
self.night = False
self.effects_sounds["level_start"].play()
def new_2(self):
# initialize all variables and do all the setup for a new game
self.all_sprites = pg.sprite.LayeredUpdates()
self.walls = pg.sprite.Group()
self.bullets = pg.sprite.Group()
self.mobs = pg.sprite.Group()
self.items = pg.sprite.Group()
self.map = Tiled_Map(path.join(self.map_folder, 'level2.tmx'))
self.map_image = self.map.make_map()
self.map_rect = self.map_image.get_rect()
# for row, tiles in enumerate(self.map.data):
# for col, tile in enumerate(tiles):
# if tile == '1':
# Wall(self, col, row)
# if tile == 'M':
# Mob(self, col, row)
# if tile == 'P':
# self.player = Player(self, col, row)
for tile_object in self.map.tmxdata.objects:
obj_center = vec(tile_object.x + tile_object.width / 2, tile_object.y + tile_object.height / 2)
if tile_object.name == "player":
self.player = Player(self, obj_center.x, obj_center.y)
if tile_object.name == "zombie":
Mob(self, obj_center.x, obj_center.y)
if tile_object.name == "wall":
Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height)
if tile_object.name in ["health", "shotgun", "m_gun", "desert_eagle"]:
Item(self, obj_center, tile_object.name)
self.camera = Camera(self.map.width, self.map.height)
self.draw_debug = False
self.paused = False
self.night = False
self.effects_sounds["level_start"].play()
def new_3(self):
# initialize all variables and do all the setup for a new game
self.all_sprites = pg.sprite.LayeredUpdates()
self.walls = pg.sprite.Group()
self.bullets = pg.sprite.Group()
self.mobs = pg.sprite.Group()
self.items = pg.sprite.Group()
self.map = Tiled_Map(path.join(self.map_folder, 'level3.tmx'))
self.map_image = self.map.make_map()
self.map_rect = self.map_image.get_rect()
# for row, tiles in enumerate(self.map.data):
# for col, tile in enumerate(tiles):
# if tile == '1':
# Wall(self, col, row)
# if tile == 'M':
# Mob(self, col, row)
# if tile == 'P':
# self.player = Player(self, col, row)
for tile_object in self.map.tmxdata.objects:
obj_center = vec(tile_object.x + tile_object.width / 2, tile_object.y + tile_object.height / 2)
if tile_object.name == "player":
self.player = Player(self, obj_center.x, obj_center.y)
if tile_object.name == "zombie":
Mob(self, obj_center.x, obj_center.y)
if tile_object.name == "wall":
Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height)
if tile_object.name in ["health", "shotgun", "m_gun", "desert_eagle"]:
Item(self, obj_center, tile_object.name)
self.camera = Camera(self.map.width, self.map.height)
self.draw_debug = False
self.paused = False
self.night = False
self.effects_sounds["level_start"].play()
def run(self):
# game loop - set self.playing = False to end the game
self.playing = True
pg.mixer.music.play(loops=-1)
while self.playing:
self.dt = self.clock.tick(FPS) / 1000.0 # fix for Python 2.x
self.events()
if not self.paused:
self.update()
self.draw()
def quit(self):
pg.quit()
sys.exit()
def update(self):
# Game over?
if len(self.mobs) == 0:
self.new_2()
if len(self.mobs) == 0:
self.new_3()
# update portion of the game loop
self.all_sprites.update()
self.camera.update(self.player)
# player hits item
hits = pg.sprite.spritecollide(self.player, self.items, False, collide_hit_rect)
for hit in hits:
if hit.type == "health" and self.player.health < PLAYER_HEALTH:
hit.kill()
self.effects_sounds["health_up"].play()
self.player.add_health(HEALTH_PACK_AMOUNT)
if hit.type == "shotgun":
hit.kill()
self.player.weapon = "shotgun"
self.effects_sounds["gun_pickup"].play()
if hit.type == "m_gun":
hit.kill()
self.player.weapon = "m_gun"
self.effects_sounds["gun_pickup"].play()
if hit.type == "desert_eagle":
hit.kill()
self.player.weapon = "desert_eagle"
self.effects_sounds["gun_pickup"].play()
# mobs hit player
hits = pg.sprite.spritecollide(self.player, self.mobs, False, collide_hit_rect)
for hit in hits:
if random() < 0.7:
choice(self.player_hit_sounds).play()
self.player.health -= MOB_DAMAGE
hit.vel = vec(0, 0)
if self.player.health <= 0:
self.playing = False
if hits:
self.player.hit()
self.player.pos += vec(MOB_KNOCKBACK, 0).rotate(-hits[0].rot)
# bullet hit mobs
hits = pg.sprite.groupcollide(self.mobs, self.bullets, False, True)
for mob in hits:
# hit.health -= WEAPONS[self.player.weapon]["damage"] * len(hits[hit])
for bullet in hits[mob]:
mob.health -= bullet.damage
mob.vel = vec(0, 0)
def draw_grid(self):
for x in range(0, WIDTH, TILESIZE):
pg.draw.line(self.screen, LIGHTGREY, (x, 0), (x, HEIGHT))
for y in range(0, HEIGHT, TILESIZE):
pg.draw.line(self.screen, LIGHTGREY, (0, y), (WIDTH, y))
def render_fog(self):
# draw the light mask (gradient) onto the fog image
self.fog.fill(NIGHT_COLOR)
self.light_rect.center = self.camera.apply(self.player).center
self.fog.blit(self.light_mask, self.light_rect)
self.screen.blit(self.fog, (0, 0), special_flags=pg.BLEND_MULT)
def draw(self):
pg.display.set_caption("{:.2f}".format(self.clock.get_fps()))
# self.screen.fill(BGCOLOR)
self.screen.blit(self.map_image, self.camera.apply_rect(self.map_rect))
# self.draw_grid()
for sprite in self.all_sprites:
if isinstance(sprite, Mob):
sprite.draw_health()
self.screen.blit(sprite.image, self.camera.apply(sprite))
if self.draw_debug:
pg.draw.rect(self.screen, CYAN, self.camera.apply_rect(sprite.rect), 1)
if self.draw_debug:
for wall in self.walls:
pg.draw.rect(self.screen, CYAN, self.camera.apply_rect(wall.rect), 1)
# pg.draw.rect(self.screen, WHITE, self.player.hit_rect, 2)
if self.night:
self.render_fog()
# HUD functions
draw_player_health(self.screen, 10, 10, self.player.health / PLAYER_HEALTH)
self.draw_text("Zombies: {}".format(len(self.mobs)), self.hud_font,
30, WHITE, WIDTH - 10, 10, align="ne")
if self.paused:
self.screen.blit(self.dim_screen, (0, 0))
self.draw_text("PAUSED", self.title_font, 105, RED, WIDTH / 2, HEIGHT / 2, align="center")
pg.display.flip()
def events(self):
# catch all events here
for event in pg.event.get():
if event.type == pg.QUIT:
self.quit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
self.quit()
if event.key == pg.K_h:
self.draw_debug = not self.draw_debug
if event.key == pg.K_p:
self.paused = not self.paused
if event.key == pg.K_n:
self.night = not self.night
def show_start_screen(self):
pass
def show_go_screen(self):
self.screen.fill(BLACK)
self.draw_text("GAME OVER", self.title_font, 100,
RED, WIDTH / 2, HEIGHT / 2, align="center")
self.draw_text("Press a key to start", self.title_font, 75, WHITE, WIDTH / 2, HEIGHT * 3 / 4, align="center")
pg.display.flip()
self.wait_for_key()
def wait_for_key(self):
pg.event.wait()
waiting = True
while waiting:
self.clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
waiting = False
self.quit()
if event.type == pg.KEYUP:
waiting = False
# create the game object
g = Game()
g.show_start_screen()
while True:
g.new()
g.run()
g.show_go_screen()