master/character.c
// determine the direction in which a monster or projectile should move
determine the direction in which a monster or projectile should move
determine the direction in which a monster or projectile should move
void move(struct Character* character)
{
    switch (character->movement)
    {
        case FOLLOW_PROTAGONIST:
            if (protagonist->x < character->x
                && obstacle(character->x - 1, FLOOR_Y)) 
            {
                moveleft(character);
            }
            else if (protagonist->x > character->x
                && obstacle(character->x + character->width, FLOOR_Y)) 
            {
                moveright(character);
            }
            else
            {
                draw(character);
            }
            break;
        case BACK_AND_FORTH:
            if (character->direction == DIRECTION_LEFT)
            {
                if (!obstacle(character->x - 1, FLOOR_Y) || !moveleft(character))
                    character->direction = DIRECTION_RIGHT;
            }
            else
            {
                if (!obstacle(character->x + character->width, FLOOR_Y) || !moveright(character))
                    character->direction = DIRECTION_LEFT;
            }
            break;
        case PROJECTILE:
        case FIREBALL:
        case ARROW:
            if (character->direction == DIRECTION_LEFT)
            {
                if (!moveleft(character))
                    hide(character);
            }
            else
            {
                if (!moveright(character))
                    hide(character);
            }
            break;
        case HIDDEN:
            break;
        case JUMP:
            if(character->jumpstate == ON_THE_GROUND)
            {    
                character->jumpstate = 1;
            }
            break;
        case JUMPMOVE:
            if(character->jumpstate == ON_THE_GROUND)
            {
                character->jumpstate = 1;
            }
            if (protagonist->x < character->x)
                moveleft(character);
            else if (protagonist->x > character->x)
                moveright(character);
            else
                draw(character);
            break;
        case BOMB:
            break;
        case BOSS_DRAGON_AIR:
            if (character->y < CEILING_Y + 16
                && (character->x < 20 || character->x > DISPLAY_WIDTH - character->width - 20)
                && really_random_below(3) == 0) 
            {
                character->movement = BOSS_DRAGON_ATTACK;
                if (character->x > DISPLAY_WIDTH / 2)
                    character->direction = DIRECTION_LEFT;
                else
                    character->direction = DIRECTION_RIGHT;
                character->jumpstate = character->jumpheight = FLOOR_Y - character->y;
                character->x_pace = 30;
                character->y_pace = 10;
                break;
            }
        case FLYING_AROUND:
            if (character->direction == DIRECTION_LEFT)
            {
                if (!moveleft(character) || !really_random_below(20))
                    character->direction = really_random_below(2);
            }
            else
            {
                if (!moveright(character) || !really_random_below(20))
                    character->direction = really_random_below(2);
            }
            break;
        case ENERGYTANK:
            break;
        case XPARASITE:
            break;
        case SECROB:
            if (character->x >= DISPLAY_WIDTH - character->width - 8)
            {
                character->direction = DIRECTION_LEFT;
            }
            else if (character->x == 8)
            {
                character->direction = DIRECTION_RIGHT;
            }
            if  (character->direction == DIRECTION_LEFT)
            {
                moveleft(character);
            }
            else
            {
                moveright(character);
            }
            if (character->jumpstate == ON_THE_GROUND && really_random_below(10) == 0)
            {
                character->jumpheight = 30 + really_random_below(10);
                character->x_pace = 10;
                character->jumpstate = 1;
            }
            break;
        case BOSS_DRAGON_GROUND:
            if(character->health > character->initial_health/2)
            {
                if(protagonist->x <= DISPLAY_WIDTH / 2)
                {
                    moveleft(character);
                }
                else
                {
                    moveright(character);
                }
            }
            else
            {
                while(character->y > CEILING_Y + 16)
                {
                    moveup(character);
                }
                character->movement = BOSS_DRAGON_AIR;
            }
            break;
        case BOSS_DRAGON_ATTACK:
            if (character->direction == DIRECTION_LEFT)
            {
                if (character->x <= DISPLAY_WIDTH / 2
                    && character->jumpstate == character->jumpheight)
                {
                    character->movement = BOSS_DRAGON_AIR;
                    character->x_pace = 100;
                    character->y_pace = 40;
                }
                else
                {
                    moveleft(character);
                    if (character->x < 30)
                        character->jumpstate = 1;
                }
            }
            else
            {
                if (character->x > DISPLAY_WIDTH / 2
                    && character->jumpstate == character->jumpheight)
                {
                    character->movement = BOSS_DRAGON_AIR;
                    character->x_pace = 100;
                    character->y_pace = 40;
                }
                else
                {
                    moveright(character);
                    if (character->x > DISPLAY_WIDTH - character->width - 30)
                        character->jumpstate = 1;
                }
            }
            break;
        case ARROW_UP:
            break;
        case ZAZABI:
            if (character->jumpstate == ON_THE_GROUND)
            {
                if (really_random_below(10) == 0)
                {
                    character->direction = 1 - character->direction;
                    character->jumpstate = 1;
                    character->y_pace = 20;
                    character->jumpheight = 30 + really_random_below(20);
                    if (character->health < 10)
                    {
                        character->x_pace = 10 + really_random_below(15);
                    }
                    else
                    {
                        character->x_pace = 20 + really_random_below(15);
                    }
                }
            }
            else
            {
                if (character->y_pace == 40) 
                {
                    break;
                }
                else if (character->x + character->width / 2 == protagonist->x + protagonist->width / 2) 
                {
                    character->y_pace = 40;
                    character->jumpstate = character->jumpheight;
                }
                else
                {
                    if (character->direction == DIRECTION_LEFT)
                        moveleft(character);
                    else
                        moveright(character);
                }
            }
            break;
    }
}
void move ( struct Character * character ) { switch ( character -> movement ) { case FOLLOW_PROTAGONIST : if ( protagonist -> x < character -> x && obstacle ( character -> x - 1 , FLOOR_Y ) ) { moveleft ( character ) ; } else if ( protagonist -> x > character -> x && obstacle ( character -> x + character -> width , FLOOR_Y ) ) { moveright ( character ) ; } else { draw ( character ) ; } break ; case BACK_AND_FORTH : if ( character -> direction == DIRECTION_LEFT ) { if ( ! obstacle ( character -> x - 1 , FLOOR_Y ) || ! moveleft ( character ) ) character -> direction = DIRECTION_RIGHT ; } else { if ( ! obstacle ( character -> x + character -> width , FLOOR_Y ) || ! moveright ( character ) ) character -> direction = DIRECTION_LEFT ; } break ; case PROJECTILE : case FIREBALL : case ARROW : if ( character -> direction == DIRECTION_LEFT ) { if ( ! moveleft ( character ) ) hide ( character ) ; } else { if ( ! moveright ( character ) ) hide ( character ) ; } break ; case HIDDEN : break ; case JUMP : if ( character -> jumpstate == ON_THE_GROUND ) { character -> jumpstate = 1 ; } break ; case JUMPMOVE : if ( character -> jumpstate == ON_THE_GROUND ) { character -> jumpstate = 1 ; } if ( protagonist -> x < character -> x ) moveleft ( character ) ; else if ( protagonist -> x > character -> x ) moveright ( character ) ; else draw ( character ) ; break ; case BOMB : break ; case BOSS_DRAGON_AIR : if ( character -> y < CEILING_Y + 16 && ( character -> x < 20 || character -> x > DISPLAY_WIDTH - character -> width - 20 ) && really_random_below ( 3 ) == 0 ) { character -> movement = BOSS_DRAGON_ATTACK ; if ( character -> x > DISPLAY_WIDTH / 2 ) character -> direction = DIRECTION_LEFT ; else character -> direction = DIRECTION_RIGHT ; character -> jumpstate = character -> jumpheight = FLOOR_Y - character -> y ; character -> x_pace = 30 ; character -> y_pace = 10 ; break ; } case FLYING_AROUND : if ( character -> direction == DIRECTION_LEFT ) { if ( ! moveleft ( character ) || ! really_random_below ( 20 ) ) character -> direction = really_random_below ( 2 ) ; } else { if ( ! moveright ( character ) || ! really_random_below ( 20 ) ) character -> direction = really_random_below ( 2 ) ; } break ; case ENERGYTANK : break ; case XPARASITE : break ; case SECROB : if ( character -> x >= DISPLAY_WIDTH - character -> width - 8 ) { character -> direction = DIRECTION_LEFT ; } else if ( character -> x == 8 ) { character -> direction = DIRECTION_RIGHT ; } if ( character -> direction == DIRECTION_LEFT ) { moveleft ( character ) ; } else { moveright ( character ) ; } if ( character -> jumpstate == ON_THE_GROUND && really_random_below ( 10 ) == 0 ) { character -> jumpheight = 30 + really_random_below ( 10 ) ; character -> x_pace = 10 ; character -> jumpstate = 1 ; } break ; case BOSS_DRAGON_GROUND : if ( character -> health > character -> initial_health / 2 ) { if ( protagonist -> x <= DISPLAY_WIDTH / 2 ) { moveleft ( character ) ; } else { moveright ( character ) ; } } else { while ( character -> y > CEILING_Y + 16 ) { moveup ( character ) ; } character -> movement = BOSS_DRAGON_AIR ; } break ; case BOSS_DRAGON_ATTACK : if ( character -> direction == DIRECTION_LEFT ) { if ( character -> x <= DISPLAY_WIDTH / 2 && character -> jumpstate == character -> jumpheight ) { character -> movement = BOSS_DRAGON_AIR ; character -> x_pace = 100 ; character -> y_pace = 40 ; } else { moveleft ( character ) ; if ( character -> x < 30 ) character -> jumpstate = 1 ; } } else { if ( character -> x > DISPLAY_WIDTH / 2 && character -> jumpstate == character -> jumpheight ) { character -> movement = BOSS_DRAGON_AIR ; character -> x_pace = 100 ; character -> y_pace = 40 ; } else { moveright ( character ) ; if ( character -> x > DISPLAY_WIDTH - character -> width - 30 ) character -> jumpstate = 1 ; } } break ; case ARROW_UP : break ; case ZAZABI : if ( character -> jumpstate == ON_THE_GROUND ) { if ( really_random_below ( 10 ) == 0 ) { character -> direction = 1 - character -> direction ; character -> jumpstate = 1 ; character -> y_pace = 20 ; character -> jumpheight = 30 + really_random_below ( 20 ) ; if ( character -> health < 10 ) { character -> x_pace = 10 + really_random_below ( 15 ) ; } else { character -> x_pace = 20 + really_random_below ( 15 ) ; } } } else { if ( character -> y_pace == 40 ) { break ; } else if ( character -> x + character -> width / 2 == protagonist -> x + protagonist -> width / 2 ) { character -> y_pace = 40 ; character -> jumpstate = character -> jumpheight ; } else { if ( character -> direction == DIRECTION_LEFT ) moveleft ( character ) ; else moveright ( character ) ; } } break ; } }
determine the direction in which a monster or projectile should move
determine the direction in which a monster or projectile should move
// if it wouldn't fall into water // if it wouldn't fall into water // 1/3 probability to attack // move down towards the middle of the screen, // then move up again while continuing in the previous horizontal direction // begin flying down // else fly around // if we're on the left and have reached the highest point // if we're on the right and have reached the highest point // begin jumping in the opposite direction // Zazabi is moving down in a straight line // if Zazabi is right above the protagonist // fall down slowly