Random movement of wandering monsters in x & y axis in LibGDX

Posted by Vishal Kumar on Game Development See other posts from Game Development or by Vishal Kumar
Published on 2013-10-18T19:29:58Z Indexed on 2013/10/18 22:19 UTC
Read the original article Hit count: 1067

Filed under:
|

I am making a simple top down RPG game in LibGDX. What I want is ... the enemies should wander here and there in x and y directions in certain interval so that it looks natural that they are guarding something. I spend several hours doing this but could not achieve what I want. After a long time of coding, I came with this code. But what I observed is when enemies come to an end of x or start of x or start of y or end of y of the map. It starts flickering for random intervals. Sometimes they remain nice, sometimes, they start flickering for long time.

public class Enemy extends Sprite {

    public float MAX_VELOCITY = 0.05f;

    public static final int MOVING_LEFT = 0;
    public static final int MOVING_RIGHT = 1;
    public static final int MOVING_UP = 2;
    public static final int MOVING_DOWN = 3;

    public static final int HORIZONTAL_GUARD = 0;
    public static final int VERTICAL_GUARD = 1;
    public static final int RANDOM_GUARD = 2;

    private float startTime = System.nanoTime();
    private static float SECONDS_TIME = 0;
    private boolean randomDecider;
    public int enemyType;

    public static final float width = 30 * World.WORLD_UNIT;
    public static final float height = 32 * World.WORLD_UNIT;

    public int state;
    public float stateTime;
    public boolean visible;
    public boolean dead;

    public Enemy(float x, float y, int enemyType) {
        super(x, y);
        state = MOVING_LEFT;
        this.enemyType = enemyType;
        stateTime = 0;
        visible = true;
        dead = false;

        boolean random = Math.random()>=0.5f ? true :false;
        if(enemyType == HORIZONTAL_GUARD){
            if(random)
            velocity.x = -MAX_VELOCITY;
            else
            velocity.x = MAX_VELOCITY;
        }

        if(enemyType == VERTICAL_GUARD){
            if(random)
            velocity.y = -MAX_VELOCITY;
            else
            velocity.y = MAX_VELOCITY;
        }

        if(enemyType == RANDOM_GUARD){
            //if(random)
            //velocity.x = -MAX_VELOCITY;
            //else
            //velocity.y = MAX_VELOCITY;
        }
    }


    public void update(Enemy e, float deltaTime) { 
        super.update(deltaTime);
        e.stateTime+= deltaTime;
        e.position.add(velocity);

        // This is for updating the Animation for Enemy Movement Direction. VERY IMPORTANT FOR REAL EFFECTS
        updateDirections();

        //Here the various movement methods are called depending upon the type of the Enemy
        if(e.enemyType == HORIZONTAL_GUARD)
            guardHorizontally();

        if(e.enemyType == VERTICAL_GUARD)
            guardVertically();

        if(e.enemyType == RANDOM_GUARD)
            guardRandomly();
            //quadrantMovement(e, deltaTime);

    }

    private void guardHorizontally(){
        if(position.x <= 0){
            velocity.x= MAX_VELOCITY;
            velocity.y= 0;
        }
        else if(position.x>= World.mapWidth-width){
            velocity.x= -MAX_VELOCITY;
            velocity.y= 0;
        }
    }

    private void guardVertically(){
        if(position.y<= 0){
            velocity.y= MAX_VELOCITY;
            velocity.x= 0;
            }
            else if(position.y>= World.mapHeight- height){
            velocity.y=  -MAX_VELOCITY;
            velocity.x= 0;
            }   
    }

    private void guardRandomly(){

        if (System.nanoTime() - startTime >= 1000000000) {
            SECONDS_TIME++;
            if(SECONDS_TIME % 5==0)
            randomDecider = Math.random()>=0.5f ? true :false;

            if(SECONDS_TIME>=30)
            SECONDS_TIME =0;
            startTime = System.nanoTime();
        }

        if(SECONDS_TIME <=30){
            if(randomDecider && position.x >= 0)
            velocity.x= -MAX_VELOCITY;
            else{
            if(position.x < World.mapWidth-width)
            velocity.x= MAX_VELOCITY;
            else
            velocity.x= -MAX_VELOCITY;  
            }
            velocity.y =0;
        }
        else{
            if(randomDecider && position.y >0)
            velocity.y= -MAX_VELOCITY;
            else
            velocity.y= MAX_VELOCITY;
            velocity.x =0;
         }   

        /*
        //This is essential so as to keep the enemies inside the boundary of the Map
        if(position.x <= 0){
        velocity.x= MAX_VELOCITY;
        //velocity.y= 0;
        }
        else if(position.x>= World.mapWidth-width){
        velocity.x= -MAX_VELOCITY;
        //velocity.y= 0;
        }
        else
        if(position.y<= 0){
        velocity.y= MAX_VELOCITY;
        //velocity.x= 0;
        }
        else if(position.y>= World.mapHeight- height){
        velocity.y=  -MAX_VELOCITY;
        //velocity.x= 0;
        }   
        */    

    }

    private void updateDirections() {
        if(velocity.x > 0)
            state = MOVING_RIGHT;
        else
            if(velocity.x<0)
            state = MOVING_LEFT;
        else
            if(velocity.y>0)
            state = MOVING_UP;
        else
            if(velocity.y<0)
            state = MOVING_DOWN;        
    }


    public Rectangle getBounds() {
        return new Rectangle(position.x, position.y, width, height);
    }

    private void quadrantMovement(Enemy e, float deltaTime) {
            int temp = e.getEnemyQuadrant(e.position.x, e.position.y);
            boolean random = Math.random()>=0.5f ? true :false;

            switch(temp){

            case 1:

                    velocity.x = MAX_VELOCITY;
                break;

            case 2:

                    velocity.x = MAX_VELOCITY;
                break;

            case 3:

                    velocity.x = -MAX_VELOCITY;

                break;

            case 4:

                    velocity.x = -MAX_VELOCITY;

                break;

            default:
             if(random)
                    velocity.x = MAX_VELOCITY;

             else
                 velocity.y =-MAX_VELOCITY;

            }

            }

    public float getDistanceFromPoint(float p1,float p2){
        Vector2 v1 = new Vector2(p1,p2);
        return position.dst(v1);
    }

    private  int getEnemyQuadrant(float x, float y){
        Rectangle enemyQuad = new Rectangle(x, y, 30, 32);
        if(ScreenQuadrants.getQuad1().contains(enemyQuad))
            return 1;

        if(ScreenQuadrants.getQuad2().contains(enemyQuad))
            return 2;

        if(ScreenQuadrants.getQuad3().contains(enemyQuad))
            return 3;

        if(ScreenQuadrants.getQuad4().contains(enemyQuad))
            return 4;

        return 0;
    }
}

Is there a better way of doing this. I am new to game development. I shall be very grateful to any help or reference.

© Game Development or respective owner

Related posts about libgdx

Related posts about rpg