скорость движения не обновляется в автомате - PullRequest
0 голосов
/ 31 декабря 2018

ЭТО ВСЕ В ШАГЕ СОБЫТИЙ.

В настоящее время я пытаюсь создать свой первый конечный автомат для какого-нибудь вражеского ИИ.Будучи очень новым для gml и gamemaker studio 2, мой код очень прост, так как я не знаю, как реализовать встроенные функции.

В 1 из моих состояний, в состоянии спешки, враг должен преследоватьигрок.Я делаю это, создавая некоторые условия: если игрок находится слева от врага, враг бежит налево.Если игрок направо, враг бежит направо.Теоретически это то, что я кодировал, но когда я вхожу в игру, иногда это срабатывает, но затем судороги и идут другим путем.

Если мой персонаж находится в круге, он бежит не к игроку, а вместо этого.Это не изменится, если я переверну условия.

case  behaviour.rush:
{
    //radius in square
        if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
         { 
             //direction to face player
             if (behaviourState == behaviour.rush && playerObject.x           >.     warriorx) hsp = -4;
              else if (behaviourState == behaviour.rush &&     
  playerObject.x <= warriorx) hsp = 4;
            x = x + hsp;
         }

    if (!point_in_circle(playerObject.x,playerObject.y,x,y,200))
    {
        behaviourState = behaviour.idle;    
    }
}

Мой полный код:

image_speed = 1;
vsp = vsp+grv;
Print(behaviourState);
if (hsp > 0) image_xscale = 3; else if (hsp < 0) image_xscale = -3; 

//animation
if (behaviourState == behaviour.idle) sprite_index =     tikiAxeWarriorIdle;
if (hsp == 2 || hsp == -2)sprite_index = tikiAxeWarriorWalk;

if (hsp == 4 || hsp == -4) sprite_index = tikiAxeWarriorRush;

if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
{ 
   Print("in circle");
}
Print(hsp);

switch(behaviourState)
{
    case behaviour.idle:
    {
        //stand still
         if (alarm[1] <= 0) alarm[1] = room_speed * 4;

         if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
         { 
             behaviourState = behaviour.rush;
         }
    }

    case behaviour.wander:
    {
        if (alarm[0] <= 0) alarm[0] = room_speed * 3;

        //move
        if (!place_meeting(x + hsp,y,wallObject)) 
        {
            x = x + hsp;
        }

        if (place_meeting(x + hsp,y,wallObject))//checking frame before.
        {   
            hsp = -hsp;
        }

        //check for behaviour.rush.
        if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
        { 
            behaviourState = behaviour.rush;
        }
    }

    case  behaviour.rush:
    {
        //radius in square
        if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
        { 
            //direction to face player
            if (behaviourState == behaviour.rush && playerObject.x > warriorx) hsp = -4;
            else if (behaviourState == behaviour.rush && playerObject.x <= warriorx) hsp = 4;
            x = x + hsp;
        }

        if (!point_in_circle(playerObject.x,playerObject.y,x,y,200))
        {
            behaviourState = behaviour.idle;    
        }
    }
    case behaviour.attack:
    {
        //attack.   
        //if player is hit, he dies.
    }
}

Ожидаемый результат - враг «бросится» к моей позиции игрока и когда закончитсяступил, лицом к другому.Если мой игрок покидает круг, он должен вернуться в состояние ожидания.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

С заявлениями о переключателях я считаю, что вам нужно добавить "break;"между каждым Case.

Документация YoYo здесь содержит хорошую информацию о выражениях switch.Теперь это может не позволить вашему коду работать точно так, как вы надеетесь, но это даст вам на одну ошибку меньше к вашей цели.

Соответствующая часть состояния ссылки:
"... выполнение продолжается после первого оператора case с правильным значением, пока не встретится оператор break .... разрыв не будеттребуется, и если нет оператора break, выполнение просто продолжается с кодом следующего оператора case ".

Таким образом, по существу, без оператора break код будет начинаться с блока case, соответствующего текущему значению, а затем проходить по коду всех нижеуказанных падежей, пока не достигнет "break;".

Вот как будет выглядеть ваш код с "break";добавлено в правильные места.

image_speed = 1;
vsp = vsp+grv;
Print(behaviourState);
if (hsp > 0) image_xscale = 3; else if (hsp < 0) image_xscale = -3; 

//animation
if (behaviourState == behaviour.idle) sprite_index =     tikiAxeWarriorIdle;
if (hsp == 2 || hsp == -2)sprite_index = tikiAxeWarriorWalk;

if (hsp == 4 || hsp == -4) sprite_index = tikiAxeWarriorRush;

if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
{ 
   Print("in circle");
}
Print(hsp);

switch(behaviourState)
{
    case behaviour.idle:
    {
        //stand still
         if (alarm[1] <= 0) alarm[1] = room_speed * 4;

         if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
         { 
             behaviourState = behaviour.rush;
         }
    }
    break;
    case behaviour.wander:
    {
        if (alarm[0] <= 0) alarm[0] = room_speed * 3;

        //move
        if (!place_meeting(x + hsp,y,wallObject)) 
        {
            x = x + hsp;
        }

        if (place_meeting(x + hsp,y,wallObject))//checking frame before.
        {   
            hsp = -hsp;
        }

        //check for behaviour.rush.
        if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
        { 
            behaviourState = behaviour.rush;
        }
    }
    break;
    case  behaviour.rush:
    {
        //radius in square
        if (point_in_circle(playerObject.x,playerObject.y,x,y,200))
        { 
            //direction to face player
            if (behaviourState == behaviour.rush && playerObject.x > warriorx) hsp = -4;
            else if (behaviourState == behaviour.rush && playerObject.x <= warriorx) hsp = 4;
            x = x + hsp;
        }

        if (!point_in_circle(playerObject.x,playerObject.y,x,y,200))
        {
            behaviourState = behaviour.idle;    
        }
    }
    break;
    case behaviour.attack:
    {
        //attack.   
        //if player is hit, he dies.
    }
    break;
}

Надеюсь, это поможет!

Кроме того, быстрый совет!Одна вещь, которую я заметил в вашем коде, это то, что вы повторяете пару выражений несколько раз.Для удобства чтения я рекомендую присвоить их переменной, если это возможно.Например:

var in_circle = point_in_circle(playerObject.x,playerObject.y,x,y,200);

if in_circle {

}
if !in_circle {

}
0 голосов
/ 03 января 2019

hsp = -hsp звучит очень чувствительно к спазму.и поскольку он влияет на hsp в целом, он также влияет на часть place_meeting(x + hsp,y,wallObject).Я не знаю решение сразу, но я думаю, что вы должны взглянуть на этот раздел.

Я также предпочитаю разделить ваш текущий hsp на две переменные: направление и скорость, где направление - это значение 1 или -1, а скорость равна hsp, новозвращает положительное значение.А затем объедините их, используя speed * direction.
Таким образом, вы можете рассчитать скорость без учета направления, и наоборот.Что также может решить конфликт, который у вас сейчас есть.

...