Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import tkinter
- import random
- step = 60
- N_X = 10
- N_Y = 10
- CURRENT_LEVEL = 0 # текущий уровень сложности
- N_ENEMIES = 4 # Число врагов
- N_FIRES = 6 # Число клеток, заполненных огнем
- PLAYER_HEALTH = 10 # Здоровье игрока
- PLAYER_MAX_HEALTH = 10 # максимальный уровнь здоровья игрока
- ENEMY_DAMAGE = 1 # урон от врагов
- FIRE_DAMAGE = 2 # урон от огня
- GUN_SIZE = step / 5 # размер оружия
- fires = [] # список номеров огней на канвасе
- enemies = [] # список (враз, способ движения врага)
- spawners = [] # позоции спавнеров
- GUN_DIRECTION = (step, 0) # направлени оружия
- SPAWN_SIZE = 10 # размер спавнера
- ENEMY_SAPAWN_CHANCE = 0.1 # Шанс появления противника на сповнере
- def try_spawn_enemy(): # попробовать заспавнить врага на спавне
- player_pos = oval_cord_to_pos(canvas.coords(player))
- enemy_pos = random.choice(spawners)
- if is_value_equal(enemy_pos, player_pos):
- return
- enemy = canvas.create_oval(
- (enemy_pos[0], enemy_pos[1]),
- (enemy_pos[0] + step, enemy_pos[1] + step),
- fill='white')
- enemies.append((enemy, random.choice([always_right, random_move, move_to_player])))
- def level_up(): # Поднять уровнь сложности
- global N_X, N_Y, CURRENT_LEVEL, PLAYER_HEALTH, PLAYER_MAX_HEALTH, ENEMY_DAMAGE, FIRE_DAMAGE, N_ENEMIES, N_FIRES
- if CURRENT_LEVEL < 5:
- CURRENT_LEVEL += 1
- N_X += 2
- N_Y += 2
- canvas.config(width=step * N_X, height=step * N_Y)
- PLAYER_HEALTH += 5
- PLAYER_MAX_HEALTH += 5
- ENEMY_DAMAGE += 1
- FIRE_DAMAGE *= 2
- N_ENEMIES += 3
- N_FIRES += 3
- prepare_and_start()
- def level_down(): # уменьшить уровень сложности
- global N_X, N_Y, CURRENT_LEVEL, PLAYER_HEALTH, PLAYER_MAX_HEALTH, ENEMY_DAMAGE, FIRE_DAMAGE, N_ENEMIES, N_FIRES
- if CURRENT_LEVEL > 0:
- CURRENT_LEVEL -= 1
- N_X -= 2
- N_Y -= 2
- canvas.config(width=step * N_X, height=step * N_Y)
- PLAYER_HEALTH -= 5
- PLAYER_MAX_HEALTH -= 5
- ENEMY_DAMAGE -= 1
- FIRE_DAMAGE //= 2
- N_ENEMIES -= 3
- N_FIRES -= 3
- prepare_and_start()
- def get_format_player_health(): # вернуть форматированное здоровье игрока
- global PLAYER_HEALTH, PLAYER_MAX_HEALTH
- left = ''.join(['#' for _ in range(PLAYER_HEALTH)])
- right = ''.join('_' for _ in range((PLAYER_MAX_HEALTH - PLAYER_HEALTH)))
- return f"[ {left}{right} ]"
- def is_value_equal(l1, l2) -> bool: # сравнение списков по значению
- if len(l1) != len(l2):
- return False
- return all(map(lambda a: a[0] == a[1], zip(l1, l2)))
- def oval_cord_to_pos(cord): # координаты центра овала
- return (cord[0] + cord[2]) / 2, (cord[1] + cord[3]) / 2
- def is_empty(pos) -> bool: # проверяет пустая ли позиция
- taked = [canvas.coords(player),
- canvas.coords(exit),
- *map(lambda a: canvas.coords(a), fires),
- *map(lambda a: canvas.coords(a[0]), enemies)]
- taked = filter(lambda a: len(a) > 0, taked)
- taked = map(oval_cord_to_pos, taked)
- return not any(map(lambda a: is_value_equal(a, pos), taked))
- def always_right(pos):
- return step, 0
- def random_move(pos):
- return random.choice([(step, 0), (-step, 0), (0, step), (0, -step)])
- def sign(value): # возрващает знак числа
- return 1 if value > 0 else -1
- def move_to_player(pos): # возвращает направление движения к игроку
- player_pos = oval_cord_to_pos(canvas.coords(player))
- y = step * sign(player_pos[1] - pos[1])
- x = step * sign(player_pos[0] - pos[0])
- if pos[0] == player_pos[0]:
- return 0, y
- if pos[1] == player_pos[1]:
- return x, 0
- return random.choice([(x, 0), (0, y)])
- def prepare_and_start():
- global player, exit, fires, enemies, gun, GUN_SIZE, PLAYER_HEALTH, GUN_DIRECTION, SPAWN_SIZE
- canvas.delete("all")
- PLAYER_HEALTH = PLAYER_MAX_HEALTH
- player_pos = (random.randint(1, N_X - 1) * step,
- random.randint(1, N_Y - 1) * step)
- gun_pos = list(player_pos)
- gun_pos[0] += GUN_DIRECTION[0] / 2 + step / 2
- gun_pos[1] += GUN_DIRECTION[1] / 2 + step / 2
- exit_pos = (random.randint(1, N_X - 1) * step,
- random.randint(1, N_Y - 1) * step)
- player = canvas.create_oval(
- (player_pos[0], player_pos[1]),
- (player_pos[0] + step, player_pos[1] + step),
- fill='green')
- gun = canvas.create_oval(
- (gun_pos[0], gun_pos[1]),
- (gun_pos[0] + GUN_SIZE, gun_pos[1] + GUN_SIZE),
- fill='cyan')
- canvas.move(gun, - GUN_SIZE / 2, - GUN_SIZE / 2)
- exit = canvas.create_oval(
- (exit_pos[0], exit_pos[1]),
- (exit_pos[0] + step, exit_pos[1] + step),
- fill='yellow')
- fires = []
- for i in range(N_FIRES):
- fire_pos = (random.randint(1, N_X - 1) * step,
- random.randint(1, N_Y - 1) * step)
- if not is_empty(fire_pos):
- continue
- fire = canvas.create_oval(
- (fire_pos[0], fire_pos[1]),
- (fire_pos[0] + step, fire_pos[1] + step),
- fill='red')
- fires.append(fire)
- enemies = []
- for i in range(N_ENEMIES):
- enemy_pos = (random.randint(0, N_X - 1) * step,
- random.randint(0, N_Y - 1) * step)
- if is_value_equal(enemy_pos, player_pos):
- continue
- canvas.create_oval(
- (enemy_pos[0] + step / 2 - SPAWN_SIZE, enemy_pos[1] + step / 2 - SPAWN_SIZE),
- (enemy_pos[0] + step / 2 + SPAWN_SIZE, enemy_pos[1] + step / 2 + SPAWN_SIZE),
- fill='black')
- enemy = canvas.create_oval(
- (enemy_pos[0], enemy_pos[1]),
- (enemy_pos[0] + step, enemy_pos[1] + step),
- fill='white')
- enemies.append((enemy, random.choice([always_right, random_move, move_to_player])))
- spawners.append(enemy_pos)
- label.config(text="Найди выход!")
- label_level.config(text=f"Текущий уровень сложности: {CURRENT_LEVEL}")
- master.bind("<KeyPress>", key_pressed)
- def do_nothing(event):
- pass
- def move_wrap(obj, move):
- obj_cord_s = canvas.coords(obj)
- obj_cord = list(oval_cord_to_pos(obj_cord_s))
- obj_cord[0] += move[0]
- obj_cord[1] += move[1]
- x_mod = 0
- y_mod = 0
- if obj_cord[0] < 0:
- x_mod = 1
- if obj_cord[1] < 0:
- y_mod = 1
- if obj_cord[0] > canvas.winfo_width():
- x_mod = -1
- if obj_cord[1] > canvas.winfo_height():
- y_mod = -1
- canvas.coords(obj,
- obj_cord_s[0] + N_X * step * x_mod,
- obj_cord_s[1] + N_Y * step * y_mod,
- obj_cord_s[2] + N_X * step * x_mod,
- obj_cord_s[3] + N_Y * step * y_mod)
- canvas.move(obj, move[0], move[1])
- def check_move():
- global PLAYER_HEALTH, ENEMY_DAMAGE, FIRE_DAMAGE, ENEMY_SAPAWN_CHANCE
- if canvas.coords(player) == canvas.coords(exit):
- label.config(text="Победа!")
- master.bind("<KeyPress>", do_nothing)
- for f in fires:
- if canvas.coords(player) == canvas.coords(f):
- PLAYER_HEALTH -= FIRE_DAMAGE
- for e in enemies:
- if canvas.coords(player) == canvas.coords(e[0]):
- PLAYER_HEALTH -= ENEMY_DAMAGE
- if PLAYER_HEALTH <= 0:
- label.config(text="Ты проиграл!")
- master.bind("<KeyPress>", do_nothing)
- label_health.config(text=get_format_player_health())
- def set_gun_to(direction): # поставить оружие в сообветивии с направлением
- global GUN_DIRECTION
- if is_value_equal(direction, (0, 0)):
- return
- GUN_DIRECTION = direction
- player_pos = oval_cord_to_pos(canvas.coords(player))
- x = player_pos[0] + direction[0] / 2
- y = player_pos[1] + direction[1] / 2
- canvas.coords(gun, x, y, x + GUN_SIZE, y + GUN_SIZE)
- canvas.move(gun, - GUN_SIZE / 2, - GUN_SIZE / 2)
- def shoot(): # стрельба в направлении оружия
- player_pos = oval_cord_to_pos(canvas.coords(player))
- shoot_pos = [player_pos[i] + GUN_DIRECTION[i] for i in range(2)]
- matches = filter(lambda e: is_value_equal(oval_cord_to_pos(canvas.coords(e[0])), shoot_pos), enemies)
- for i in matches:
- enemies.remove(i)
- canvas.delete(i[0])
- def key_pressed(event):
- direction = (0, 0)
- if event.keysym == 'w':
- direction = (0, -step)
- if event.keysym == 'a':
- direction = (-step, 0)
- if event.keysym == 's':
- direction = (0, step)
- if event.keysym == 'd':
- direction = (step, 0)
- move_wrap(player, direction)
- set_gun_to(direction)
- if event.keysym == 'space':
- shoot()
- for enemy in enemies:
- direction = enemy[1](oval_cord_to_pos(canvas.coords(enemy[0]))) # вызвать функцию перемещения у "врага"
- move_wrap(enemy[0], direction) # произвести перемещение
- if random.randint(1, 100) / 100 < ENEMY_SAPAWN_CHANCE and N_ENEMIES > len(enemies):
- try_spawn_enemy()
- # Здесь нужно дописать то, что нужно,
- # чтобы все остальные клавиши работали
- check_move()
- master = tkinter.Tk()
- canvas = tkinter.Canvas(master, bg='blue',
- width=step * N_X, height=step * N_Y)
- restart = tkinter.Button(master, text="Начать заново!",
- command=prepare_and_start)
- label_level_up = tkinter.Button(master, text="Увеличить уровень сложности",
- command=level_up)
- label_level_down = tkinter.Button(master, text="Уменьшить уровень сложности",
- command=level_down)
- label = tkinter.Label(master, text="Найди выход")
- label_level = tkinter.Label(master, text=f"Текущий уровень сложности: {CURRENT_LEVEL}")
- label_health = tkinter.Label(master, text=get_format_player_health())
- prepare_and_start()
- restart.pack()
- label_level_up.pack()
- label_level_down.pack()
- label.pack()
- label_level.pack()
- label_health.pack()
- canvas.pack()
- master.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement