• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM nested loop issue [SOLVED]

woods

Member
being very new to coding i find it difficult to wrap my head around where in this nest of lf statements can i put this bit.. i know i have the right parts.. just not sure where to put them...

Code:
// isFlying code



if (isFlying = true)
{
    {
    flyCounter = flyCounter + 1
    if flyCounter = 60
        {
            var fnumber=irandom(3)  //pick random direction: 0=south, 1=north, 2= west, 3=east,      
            {
                if (fnumber == 0)
                {
                motion_set(0,2.5); image_speed=0.2; sprite_index=spr_chicken_flying_right;  // fly right
                }
                if (fnumber == 1)
                {
                motion_set(270,2.5); image_speed=0.2; sprite_index=spr_chicken_flying_down; // fly down
                }
                if (fnumber == 2)
                {
                motion_set(180,2.5); image_speed=0.2; sprite_index=spr_chicken_flying_left;  // fly left
                }
                if (fnumber == 3)
                {
                motion_set(90,2.5); image_speed=0.2; sprite_index=spr_chicken_flying_up;  // fly up
                }          
            }
        flyCounter = 0;    //reset move counter
        move_snap(32,32);                
        }            
     }          
}
im trying to wrap my head around teh whole for/while/with/do/ loop thing
i know this is a basic fundamental tool and everyone should have a firm grip on it... bbut like i said.. im trying to learn how it works ;o)

for(i=0; i<3; i+=1)

=====
flyCounter is a custom alarm set to pick a number to change direction

i have a couple more things to plug in here..
isWalking = true
isCarry = false
isFlying = false
im pretty sure they go in after the movement code, but i want the timer to run 2 or 3 times before changing the state.. im just at a loss as to where they all go...

i know the first thing everybody is going to say is statemachine...... but honestly if im having problems with a basic if statement... im not ready to add more to my plate until i get a better handle on what i got in front of me.
 

woods

Member
the code as it sits, the chicken will fly around picking random directions and without collision.. which is what i want..

i didnt see a need to put in the "else" after each direction // i believe the == makes it skip the instruction if the fnumber is NOT for this instruction.. (if the number is 0...oh its not.. nvm , next ;o)
unless im missing something here.

as the flyCounter hits 60 it checks each if statement and resets to 0, thus making the loop repeat itself..


what i am wanting to do is have that loop only repeat 2 or 3 times, // the chicken flies around a bit then starts walking


the chain i have going so far is basically..
1. walk near a chicken hit spacebar
2. chicken changes movement from isWalking to isCarry and is stuck to player object
3. player hits space again to throw the chicken.. chicken starts flying around (this is where i am at currently)
4. [havnt got here yet] after the chicken runs thru the code pasted above a few times, it switches from isFlying to isWalking again
(step 4 happens without player input-having a hard time with this)

so i think i need a loop to start after if (isFlying=true) and before flyCounter+1 so the timer still tics to make it pick directions
and finish the loop[ somewhere after flyCounter=0 and move_snap(32,32)

ive been bashing my head on this for a while now..... and im probably making it aLOT harder than it should be ;o)
 
Yep, state machine it is - it will become a logical nightmare to manage more than 2 booleans, at least that's what I've found. It can get very messy code-wise, debugging, and mentally.

However, to answer your current question, what you need is another counter, similar to flyCounter.

Let's call it stateChangeCounter.

Every time flyCounter reaches 60, add 1 to stateChangeCounter. Once stateChangeCounter reaches 2 or 3, you know that you instance has changed direction that many times, and you can do the state change (modify the booleans). Then, reset stateChangeCounter to 0.

Code:
if (isFlying)
{
    flyCounter++;
    if ( flyCounter == 60 )
    {
        flyCounter = 0;
        // [direction code from above]

       stateChangeCounter++;
       if ( stateChangeCounter >= 3 )
       {
           stateChangeCounter = 0;
           // Switch to Walking
           walkCounter = 0;
           isFlying = false;
           isWalking = true;
       }
    }
}

if ( isWalking )
{
    walkCounter++;
    if ( walkCounter == 60 )
    {
        // [ walking code]
        stateChangeCounter ++;
       if ( stateChangeCounter >= 3 )
       {
           stateChangeCounter = 0;
           flyCounter = 0;
           isFlying = true;
           isWalking = false;
       }
    }
}
Once you've got the hang of this, I highly recommend learning state machines for this kind of thing.
 

woods

Member
i was on the right track..... i know just enough to know i dont know what im doing with it ;o)

heres the whole bit if your curious...

obj_chicken create
Code:
/// initialize variables
image_speed = 0.2

walkCounter=0
flyCounter = 0
isWalking = true
isCarry = false
isFlying = false
obj_chicken step
Code:
/// movement
// isWalking code
walkCounter = walkCounter + 1

if isWalking = true and walkCounter = 60
{
var number=irandom(8)  //pick random direction 0=right, 1=down, 2=left, 3=up, 4thru7 = no idle

//move and change sprite
if (number>3)
    {
    speed=0; image_speed=0.1; sprite_index=spr_chicken_right; //idle
    }
   
if (number==0)
{
    if(!place_meeting(x+32,y,obj_block))
    {
    motion_set(0,0.6); image_speed=0.2; sprite_index=spr_chicken_right;  //right if not blocked
    }
    else
    {
    speed=0; image_speed=0.1; //idle if blocked
    }
}

if (number==1)
{
    if (!place_meeting(x,y+32,obj_block))
    {
    motion_set(270,0.6); image_speed=0.2; sprite_index=spr_chicken_down; //down if not blocked
    }
    else
    {
    speed=0; image_speed=0.1; //idle if blocked
    }
}
       
if (number==2)
{
    if (!place_meeting(x-32,y,obj_block))
    {
    motion_set(180,0.6); image_speed=0.2; sprite_index=spr_chicken_left; //left if not blocked
    }
    else
    {
    speed=0; image_speed=0.1; //idle if blocked
    }
}
     
if (number==3)
{
    if (!place_meeting(x,y-32,obj_block))
    {
    motion_set(90,0.6); image_speed=0.2; sprite_index=spr_chicken_up;  //up if not blocked
    }
    else
    {
    speed=0; image_speed=0.1; //idle if blocked
    }  
}
               
move_snap(32,32);  // snap to the grid cell
walkCounter = 0
}


// isCarry code
if isCarry = true   // when player grabs chicken
{
    x=obj_player.x      // follow player
    y=obj_player.y   // follow player
    depth = obj_player.depth-1
    dir = (obj_player.dir)
   
    if (dir = 0)
        {
        image_speed=0; sprite_index=spr_chicken_right
        }
    if (dir = 1)
        {
        image_speed=0; sprite_index=spr_chicken_down
        }
    if (dir = 2)
        {
        image_speed=0; sprite_index=spr_chicken_left
        }
    if (dir = 3)
        {
        image_speed=0; sprite_index=spr_chicken_up
        }         
}



// isFlying code



if (isFlying = true)
{     
    flyCounter = flyCounter + 1
    if flyCounter = 60
    {
            var fnumber=irandom(3)  //pick random direction: 0=south, 1=north, 2= west, 3=east,       
            {
                if (fnumber == 0)
                {
                motion_set(0,2); image_speed=0.2; sprite_index=spr_chicken_flying_right;  // fly right
                }
                if (fnumber == 1)
                {
                motion_set(270,2); image_speed=0.2; sprite_index=spr_chicken_flying_down; // fly down
                }
                if (fnumber == 2)
                {
                motion_set(180,2); image_speed=0.2; sprite_index=spr_chicken_flying_left;  // fly left
                }
                if (fnumber == 3)
                {
                motion_set(90,2); image_speed=0.2; sprite_index=spr_chicken_flying_up;  // fly up
                }           
            }
        flyCounter = 0;    //reset move counter
        move_snap(32,32);                 
    }                       
}
obj_player create
Code:
/// initialize variables

global.carried = noone;

canCarry = true //stops player from picking up all the chickens
dir = 0
obj_player step_ grab and throw

Code:
/// graab and throw chicken
if (distance_to_object(instance_nearest(x,y,obj_chicken)) <=32)
{
if canCarry = true
{
    if (keyboard_check_pressed(vk_space))
    {
        with (instance_nearest(x,y,obj_chicken))
        {
            isWalking = false   
            isCarry = true
            isFlying = false
        }
        canCarry = false
    }
}


else
{
    if (keyboard_check_pressed(vk_space))
    {
        with (instance_nearest(x,y,obj_chicken))
        {
           isWalking = false
           isCarry = false
           isFlying = true
        }
        canCarry = true
    }
   
}
}
if you can make sense of all this...... tell me there is an easier way to make it happen ;o)
 

TheouAegis

Member
i didnt see a need to put in the "else" after each direction // i believe the == makes it skip the instruction if the fnumber is NOT for this instruction.. (if the number is 0...oh its not.. nvm , next ;o)
unless im missing something here.

Need? No need. But it speeds up code a lot. If the variable is zero, then why bother checking three more times? If the variable is one, why bother checking it two more times?
 

woods

Member
Need? No need. But it speeds up code a lot. If the variable is zero, then why bother checking three more times? If the variable is one, why bother checking it two more times?
that makes aLOT of sense.. thank you for that tidbit
*grabs another stickynote and slaps it on the monitor


;o)
 
Top