как можно сделать чтобы npc "видел" и не "видел" игрока?

def can_see_hero(self):
    for p in platforms:
        #вычисление расположения х игрока и npc
        if hero.rect.x+hero.a <= self.rect.x:
            if hero.rect.x >= p.rect.x+p.w:
                if hero.rect.y <= self.rect.y:
#вычисления расположения у игрока и платформы
                    if hero.rect.y <= p.rect.y:
                        self.see=True
                    if hero.rect.y >= p.rect.y:
                        self.see=False

                if hero.rect.y > self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=False
                    if hero.rect.y >= p.rect.y:
                        self.see=True
            if hero.rect.x+hero.a<=p.rect.x:
                if hero.rect.y <= self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=True
                    if hero.rect.y >= p.rect.y:
                        self.see=False

                if hero.rect.y > self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=False
                    if hero.rect.y >= p.rect.y:
                        self.see=True
        if hero.rect.x >= self.rect.x:
            if hero.rect.x >= p.rect.x+p.w:
                if hero.rect.y <= self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=True
                    if hero.rect.y >= p.rect.y:
                        self.see=False

                if hero.rect.y > self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=False
                    if hero.rect.y >= p.rect.y:
                        self.see=True
            if hero.rect.x+hero.a<=p.rect.x:
                if hero.rect.y <= self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=True
                    if hero.rect.y >= p.rect.y:
                        self.see=False

                if hero.rect.y > self.rect.y:
                    if hero.rect.y <= p.rect.y:
                        self.see=False
                    if hero.rect.y >= p.rect.y:
                        self.see=True

Можете мне указать на логические ошибки?

  • hero-игрок
  • p-платформа
  • self-npc

Ответы (2 шт):

Автор решения: Андрей Таков

очень сложно, а пайтон говорит постой код лучше. есть отличная формула из тригонометрии на определение принадлежит ли точка кругу. Вот пример функции которая определяет вошел ли персонаж в тригерную зону, если да, то турель начинает стрелять.

def check_in(self):
    r = 200
    if (player.rect.centerx - self.rect.centerx) ** 2 + (player.rect.centery - self.rect.centery) ** 2 <= r * r:
        self.shoot()
→ Ссылка
Автор решения: Alexander Chernin

Давайте нарисуем и рассмотрим картинку (проекция вида сверху - top-down).

npc-view

Здесь:

  • красные кружочки - это npc
  • зеленый - игрок
  • закрашенный прямоугольник - стена/преграда (ПР)
  • треугольники - область видимости/зрения npc (ТВ)
  • черные линии от npc до игрока - линии видимости (ЛВ)
  • маленькие красные точки - пересечение ЛВ и преграды

Тогда алгоритм выделения адреналина у npc будет такой:

  1. Пока есть, берем очередного npc

  2. Проверяем, попадает ли игрок в ТВ данного npc

  3. Если да, то

    3.1 Последовательно получаем и проверяем все ПР(через проверку характерных точек ПР), лежащие внутри ТВ данного npc. Проверка пересечения ЛВ с преградой, осуществляется наличием точек пересечения ЛВ и сторон ПР (или других характерных линий - диагоналей, срединных линий и тому подобное)

    3.2 Если точки пересечения ЛВ и ПР имеются, то npc игрока не видит и it keeps calm. Переходим к п.1

    3.3 Иначе выделяется адреналин и начинается action

  4. Если нет, переходим к п.1

→ Ссылка