[Solved] Chained statements like .moveXY() and behavior override each other?

This is extremely confusing. So far my commands executed in the sequence they appear in the code…
Is there any way they can first walk and then turn defensive?

1 Like

I’ve not tried your code with his idea yet, but when I ran your code, all 3 archers did, in a sort of round about way, reach the fences. Like I said, I’ll keep playing with it…might take me a few days, so if you are on a tight schedule (deadline), you might want to pursue the teleporting and then tinker later, so you can understand what’s going on.

2 Likes

I will really appreciate that!
I’ll go with a teleport for now, though it will feel so much better to be able to predict what my code will actually do. And understand why it does what it does )

1 Like

@Deadpool198, @Chaboi_3000 to keep me honest here.

My interpretation is that the ‘moveXY’ statement works differently in the game dev (GD) environment, as compared to the campaign environment.

In campaign, we know that all subsequent code execution stops until the hero reaches the final x,y coords. In the GD, moveXY appears to behave more like the ‘move’ command, which is effectively:

  • take a step
  • execute the next code statement, etc, etc, etc
  • start at the beginning, taking the next step

I now remember another topic from quite a while back that discussed this very behavior…

2 Likes

Thank you! I will know now there is a game dev environment and campaign environment.

If this is what happens, does that mean that an archer takes his first step towards point 1, second step towards point 2, third step towards point 3 and then it all gets overridden by setting a behavior?

1 Like

That sounds plausible…kind of like, first line initiates the move, the second (if it even has time to fully execute) resets the destination, the third sets the final destination; the behavior change, being last has the final say.

2 Likes

I guess I’ll be better off going with a teleport then :slight_smile:

1 Like

I’ve renamed the topic to describe the issue better.

It would really be nice to have more information on how code executes in the game dev environment. I did my best to implement what I learned in Game Dev 2, but the existence of campaign and dev environments kind of subverted my expectations.

So far I have been able to teleport my archers to the desired location. It is not pretty, but it works. Yes, I did it just for the sake of it :partying_face:

Here is the short version. Teleport activates on munchkin defeat
var hero=game.spawnPlayerXY("samurai", 10, 10);
var archer1=game.spawnXY("archer", 10, 60);
var archer2=game.spawnXY("archer", 11, 57);
var archer3=game.spawnXY("archer", 8, 55);
game.spawnXY("munchkin", 26, 26);
game.spawnXY("ogre-f", 69, 53);

var tele01;
var tele02;
var tele03;
var tele11;
var tele12;
var tele13;
var teleLoad=3;
var teleTurn=0;
var transferComplete=false;
var teleOff=false;

function onDefeat(event){
    var unit=event.target;
    if (unit.type=="munchkin"){
        teleport();
    }
}

function onSpawn(){
    var unit=event.target;
    if (unit.type=="archer"){
        //unit.attackRange=60;
    }
}
game.setActionFor("munchkin", "defeat", onDefeat);

function teleport(){
    var vectorX=32;
    var vectorY=-17;
    openPortal();
    teleTurn=game.time+teleLoad;
    while(true){
        if (teleTurn < game.time && !transferComplete) {
            beam();
            transferComplete=true;
        }
    }
}

function openPortal(){
    tele11=game.spawnXY("mushroom", archer1.pos.x+vectorX, archer1.pos.y+vectorY);
    tele12=game.spawnXY("mushroom", archer2.pos.x+vectorX, archer2.pos.y+vectorY);
    tele13=game.spawnXY("mushroom", archer3.pos.x+vectorX, archer3.pos.y+vectorY);
}

function beam(){
    tele01=archer1.pos;
    archer1.pos=tele11.pos;
    tele11.pos=tele01;
    
    tele02=archer2.pos;
    archer2.pos=tele12.pos;
    tele12.pos=tele02;
    
    tele03=archer3.pos;
    archer3.pos=tele13.pos;
    tele13.pos=tele03;
    
    teleTurn=game.time+teleLoad;
    
    while(true){
        if (teleTurn < game.time && !teleOff) {
            closePortal();
            teleOff=true;
        }
    }
    
}

function closePortal(){
    tele11.destroy();
    tele12.destroy();
    tele13.destroy();
    archer1.attackRange=60;
    archer2.attackRange=60;
    archer3.attackRange=60;
    archer1.behavior="Defends";
    archer2.behavior="Defends";
    archer3.behavior="Defends";    
}

If archer.attackRange is set onSpawn, after teleporting the archers walk in place and never shoot at the enemy.
If archer.attackRange is set after teleporting, they shoot just fine.
And I have absolutely no idea why they walk to their previous location if behavior is set one line before teleport() is called.

It feels the issue is somehow beyond the scope of the course. It will just take some trial and error to complete the level.

I’m not good at game development, I have finished mechanically only several levels of it (my son got quickly bored with them and the awards are miserable). So my advice is based on ordinary levels @aYo11 wants to implement something I’ve used for my hero and soldiers in all maps - I have almost absolutely thrown away a hero. moveXY () - see HELP Kelvintaph Crusader for my posted video solution and the animated gif.I suppose the goal is to have this kind of movement - modified @AnSeDra’s code:( I use something similar wrapped in a function)

var archer=game.spawnXY("archer", 9, 57),
    k = 0;
while ( true ){
    if (k === 0){
        if ( archer.pos.x != 25 && archer.pos.y != 58) archer.moveXY(25,58);
        else k = 1;
    }
    else if ( k == 1){
        if ( archer.pos.x != 26 && archer.pos.y != 36) archer.moveXY(26,36);
        else  k = 2;
    }
    else if ( k == 2){
        if ( archer.pos.x != 44 && archer.pos.y != 36) archer.moveXY(44,36);
        else k = 0;
    }
}

4 Likes

This one is actually brilliant!

Thank you so much! I slightly modified the code you suggested as I wanted the archer to first take a walk just once and then stand down and turn defensive. So if I want to add any other actions, I’ll need to make sure the previous actions are actually complete.

var archer=game.spawnXY("archer", 9, 57);
game.spawnXY("ogre-f", 60, 44);
var k = 0;
while ( true ){
    if (k === 0){
        if ( archer.pos.x != 25 && archer.pos.y != 58) { archer.moveXY(25,58); }
        else { k = 1; }
    }
    else if ( k == 1){
        if ( archer.pos.x != 26 && archer.pos.y != 36) { archer.moveXY(26,36); } 
        else { k = 2; }
    }
    else if ( k == 2){
        if ( archer.pos.x != 44 && archer.pos.y != 36) { archer.moveXY(44,36); } 
        else { k = 3;  }
    }
    else if (k==3 && archer.behavior != "Defends") {
        archer.behavior="Defends"; 
        k=4;
        }
}

I will have to do with a while(true)loop, because using while(k<4) crashes my browser.

My post is marked as solution, but the way I had changed the @AnSeDra code is wrong. It will fail if we have points A(x0,y0), B(x1,y1), C(x2, y2) where x0=x1 and y1=y2 and similar. AnseDra solution is OK, he only needs to replace
while (k < 3) with while(true)
and
archer.pos.y = xx to archer.pos.y == xx
I’ll redeem my sins by showing how to move the hero and the minions by his method :slight_smile:


and the code:

var k = 0,
    x = hero.pos.x,
    y = hero.pos.y;
var peasant = hero.findByType("peasant")[0],
    l = 0,
    xp = peasant.pos.x,
    yp = peasant.pos.y;
while (true){
    if (k === 0){
        hero.move(Vector(x-20,y));
        if ( hero.pos.x == x-20 && hero.pos.y == y)  k=1;
    }
    else if ( k == 1){
        hero.move(Vector(x-20,y-20));
        if ( hero.pos.x == x-20 && hero.pos.y == y-20)  k=2;
    }
    else if ( k == 2){
        hero.move(Vector(x , y-20));
        if ( hero.pos.x == x && hero.pos.y == y-20) k=3;
    }
    else if ( k == 3){
        hero.move(Vector(x, y));
        if ( hero.pos.x == x && hero.pos.y == y) k=0;
    }    
/////////////////////////////////////////////////////////////////////////    
    if (l === 0){
        hero.command(peasant, "move",Vector(xp-20,yp));
        if ( peasant.pos.x == xp-20 && peasant.pos.y == yp)  l=1;
    }
    else if ( l == 1){
        hero.command(peasant, "move",Vector(xp-20,yp-20));
        if ( peasant.pos.x == xp-20 && peasant.pos.y == yp-20)  l=2;
    }
    else if ( l == 2){
        hero.command(peasant, "move",Vector(xp , yp-20));
        if ( peasant.pos.x == xp && peasant.pos.y == yp-20) l=3;
    }
    else if ( l == 3){
        hero.command(peasant, "move",Vector(xp, yp));
        if ( peasant.pos.x == xp && peasant.pos.y == yp) l=0;
    }    
}

3 Likes

Thank you for sharing! It’s beyond the scope of GameDev2, but hopefully I’ll get to vectors some day soon :slight_smile:

I have tested the code marked as the solution with A(25, 58), B(25, 36) and C(44, 36) and it still worked for me.
Here x0 = x1 and y1=y2. I figure true AND false evaluates to false, but the archer keeps walking in circles somehow…

The code marked as “Solution” is not foolproof and I succeeded to crash it, I don’t remember the exact case.
About vectors see Listen well, brothers and sisters, for I can teach you the power of the VECTOR (Nope, not the guy from Despicable Me…) and the whole topic.
I wish these fantastic guys were still at codecombat…

3 Likes

You are right! The code initially marked as the solution (theoretically) should not work, still it does. I will then remove [Solution] tag so it would not confuse the others.

Thank you for the vector link! There is so much dust on my school math now :slight_smile:

1 Like