Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Logika potworów w grze

Ostatnio zmodyfikowano 2024-09-04 22:05
Autor Wiadomość
DejaVu
» 2024-05-23 19:09:34
Co przez to rozumiesz?
P-181122
tBane
Temat założony przez niniejszego użytkownika
» 2024-05-23 20:19:45
Załóżmy, że mamy stany: idle, run, patrol, fight, run away. Mamy już 5 stanów. Złożoność if'ów wzrosła. Czy jest jakaś metoda którą można w prosty sposób uporządkować takie if'y?
P-181123
DejaVu
» 2024-05-23 21:23:16
Możesz zrobić to co ChatGPT zasugerował przy pierwszej odpowiedzi tj. zamiast umieszczać logikę w jednej metodzie pełnej if-ów, to robisz if-y, a logika jest zaimplementowana w metodach, czyli:
C/C++
if( something1 )
   
 method1();
else if( something2 )
   
 method2();
else if( something3 )
   
 method3();
P-181124
tBane
Temat założony przez niniejszego użytkownika
» 2024-05-23 21:25:59
No przecież robię coś takiego. Przypadkiem zrobiłem i działa. Zastanawiam się tylko dlaczego rand()%300 działa a odliczanie cooldown już nie.

C/C++
void update( float dt ) {
   
   
switch( state ) {
   
case states::fight:
       
       
if( playerInAttackRange() ) {
           
if( cooldown <= 0.0f ) {
               
player->takeDamage( 2 );
               
cooldown = attackTime;
               
frame = 0;
           
}
           
           
frame = cooldown / attackTime * 4.0f - 1.0f;
           
sprite->setTexture( * fightTextures[ direction * 4 + frame ] );
       
}
       
else if( playerInViewRange() ) {
           
state = states::run;
           
target = player->position;
       
}
       
else
       
{
           
state = states::run;
       
}
       
break;
       
   
case states::run:
       
if( playerInAttackRange() )
           
 state = states::fight;
       
else if( playerInViewRange() ) {
           
target = player->position;
           
state = states::run;
           
float distance = 15.0f * stepSize * dt;
           
goToTarget( distance );
           
calculateCurrentFrame( dt );
           
sprite->setTexture( * runTextures[ direction * 4 + frame ] );
       
}
       
else if( position == target ) {
           
state = states::idle;
       
}
       
else
       
{
           
float distance = 15.0f * stepSize * dt;
           
goToTarget( distance );
           
calculateCurrentFrame( dt );
           
sprite->setTexture( * runTextures[ direction * 4 + frame ] );
       
}
       
break;
       
   
case states::idle:
       
if( playerInAttackRange() ) {
           
state = states::fight;
       
}
       
else if( playerInViewRange() ) {
           
target = player->position;
           
state = states::run;
       
}
       
else {
           
           
if( rand() % 600 == 0 ) { // HERE HELP ME
               
target.x = pointBase.x + rand() % 300 - 150;
               
target.y = pointBase.y + rand() % 300 - 150;
               
state = states::run;
           
}
           
        }
       
calculateCurrentFrame( dt );
       
sprite->setTexture( * idleTextures[ direction * 4 + frame ] );
       
break;
   
}
   
   
   
mouseOvering();
   
   
if( cooldown >= 0.0f )
       
 cooldown -= dt;
   
   
sprite->setPosition( position );
   
collider->setPosition( position );
   
viewRangeArea->setPosition( position );
   
attackRangeArea->setPosition( position );
   
   
textname->setPosition( position.x, position.y - height - 30 );
   
panelHP->setPosition( position.x, position.y - height - 10 );
   
panelHPcurrent->setPosition( position.x, position.y - height - 10 );
   
}
P-181125
tBane
Temat założony przez niniejszego użytkownika
» 2024-05-23 21:52:16
potrzebuję Waszej pomocy jak przerobić ten rand()%600 == 0 na funkcje czasową ...

C/C++
case states::idle:
if( playerInAttackRange() ) {
   
state = states::fight;
}
else if( playerInViewRange() ) {
   
target = player->position;
   
state = states::run;
}
else {
   
   
if( rand() % 600 == 0 ) { // HERE HELP ME
        // losowanie targetu
       
target.x = pointBase.x + rand() % 300 - 150;
       
target.y = pointBase.y + rand() % 300 - 150;
       
state = states::run;
   
}
   
}
P-181126
DejaVu
» 2024-05-23 22:26:49
No właśnie nie robisz. Puchnie Ci kod w jednej metodzie, w której decydujesz o zachowaniu. If-y powinny być w jednej metodzie, a zachowanie każdej z akcji w osobnej metodzie, aby kod był łatwiej utrzymywalny.
P-181127
tBane
Temat założony przez niniejszego użytkownika
» 2024-05-23 22:39:00
Przecież to nie ma sensu ... Ale zrobiłem...

C/C++
void funcFight() {
   
if( playerInAttackRange() ) {
       
if( cooldown <= 0.0f ) {
           
player->takeDamage( 2 );
           
cooldown = attackTime;
           
frame = 0;
       
}
       
       
frame = cooldown / attackTime * 4.0f - 1.0f;
       
sprite->setTexture( * fightTextures[ direction * 4 + frame ] );
   
}
   
else if( playerInViewRange() ) {
       
state = states::run;
       
target = player->position;
   
}
   
else
   
{
       
state = states::run;
   
}
}

void funcRun( float dt ) {
   
if( playerInAttackRange() )
       
 state = states::fight;
   
else if( playerInViewRange() ) {
       
target = player->position;
       
state = states::run;
       
float distance = 15.0f * stepSize * dt;
       
goToTarget( distance );
       
calculateCurrentFrame( dt );
       
sprite->setTexture( * runTextures[ direction * 4 + frame ] );
   
}
   
else if( position == target ) {
       
state = states::idle;
   
}
   
else
   
{
       
float distance = 15.0f * stepSize * dt;
       
goToTarget( distance );
       
calculateCurrentFrame( dt );
       
sprite->setTexture( * runTextures[ direction * 4 + frame ] );
   
}
}

void funcIdle( float dt ) {
   
if( playerInAttackRange() ) {
       
state = states::fight;
   
}
   
else if( playerInViewRange() ) {
       
target = player->position;
       
state = states::run;
   
}
   
else {
       
       
if( rand() % 600 == 0 ) { // HERE HELP ME
           
target.x = pointBase.x + rand() % 300 - 150;
           
target.y = pointBase.y + rand() % 300 - 150;
           
state = states::run;
       
}
       
    }
   
calculateCurrentFrame( dt );
   
sprite->setTexture( * idleTextures[ direction * 4 + frame ] );
}

void update( float dt ) {
   
   
switch( state ) {
   
case states::fight:
       
funcFight();
       
break;
       
   
case states::run:
       
funcRun( dt );
       
break;
       
   
case states::idle:
       
funcIdle( dt );
       
break;
   
}
   
   
   
mouseOvering();
   
   
if( cooldown >= 0.0f )
       
 cooldown -= dt;
   
   
sprite->setPosition( position );
   
collider->setPosition( position );
   
viewRangeArea->setPosition( position );
   
attackRangeArea->setPosition( position );
   
   
textname->setPosition( position.x, position.y - height - 30 );
   
panelHP->setPosition( position.x, position.y - height - 10 );
   
panelHPcurrent->setPosition( position.x, position.y - height - 10 );
   
}
P-181128
DejaVu
» 2024-05-24 00:27:29
No właśnie ma sens, bo upraszczasz kod. Logikę jednej akcji masz w jednej metodzie, a nie jedną wielką metodę zawierającą logikę wszystkich akcji. Przecież takie pytanie postawiłeś.

W takim razie, czy istnieje jakaś metoda rozkładająca taką logikę na czynniki pierwsze?

Załóżmy, że mamy stany: idle, run, patrol, fight, run away. Mamy już 5 stanów. Złożoność if'ów wzrosła. Czy jest jakaś metoda którą można w prosty sposób uporządkować takie if'y?
P-181129
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona