0
\$\begingroup\$

I have an actor in a class who then I put him in the main scene, but I want the actor to move randomly, that is, now he moves to the right, then down ... but controlling that he does not leave the screen either. I have tried some ways, but in some he would not move, others would go all the way to the left and loop. I have tried this that more or less does what I had in mind, but it is not correct because the character is shaking and sooner or later ends up leaving the screen. I'm just using this library and there are many things that escape me, any help or advice would be appreciated.

@Override
public void act(float delta) {
    super.act(delta);
    int number= (int)(Math.random()*4+1);

    switch (numero){
        case 1: this.setX(this.getX()-delta*80);break;
        case 2: this.setY(this.getY()-delta*80);break;
        case 3: this.setX(this.getX()+delta*80);break;
        case 4: this.setY(this.getY()+delta*80);break;
    }
    Rectangle.set(this.getX(),this.getY(),this.getWidth(),this.getHeight());
}
\$\endgroup\$
1
  • \$\begingroup\$ Hi, you declared number but the switch statement is about numero (undeclared). Maybe a typo? \$\endgroup\$
    – liggiorgio
    Apr 26 at 13:24
0
\$\begingroup\$

There's a couple of things that stand out in your code. First, in one place you set the variable number to a random value between 1 & 4, but then you're switching based on a variable named numero. I'm guessing this is a typo, but if it's not, it's going to be a problem.

Regarding the shaking, consider how often you are calling act(). If it gets called every time through the game loop (from an update() or something similar), the result is you're picking a new direction too frequently (very likely multiple times per second). The solution to this is to keep track of how long you've been travelling in a particular direction & only pick a new direction when you've gone far enough.

As for leaving the screen, you need to add some sort of bounds checking. As originally posted, there's no code that checks to see if the actor has travelled off screen.

Here's an example of modifications that address these issues. I've included some comments to point out the reason for the various changes

@Override
public void act(float delta) {
    super.act(delta);

    // move in the direction of the current random heading
    switch (randomHeading){
        case 1: this.setX(this.getX()-delta*80);break;
        case 2: this.setY(this.getY()-delta*80);break;
        case 3: this.setX(this.getX()+delta*80);break;
        case 4: this.setY(this.getY()+delta*80);break;
    }

    // if needed, stop at screen boundary & clear the heading
    int maxX = Gdx.graphics.getWidth() - getWidth();
    int maxY = Gdx.graphics.getHeight() - getHeight();
    if(getX() < 0){
        setX(0);
        randomHeading = 0;
    }
    else if(getX() > maxX){
        setX(maxX);
        randomHeading = 0;
    }
    if(getY() < 0){
        setY(0);
        randomHeading = 0;
    }
    else if(getY() > maxY){
        setY(maxY);
        randomHeading = 0;
    }

    // update time spent on current heading & check if a new heading is needed
    // recall that if the actor attempted to move off screen, randomHeading was set to zero
    timeTravelled += delta;
    float maxTravelTime = 10;
    if(timeTravelled > maxTravelTime || randomHeading == 0){
        timeTravelled = 0;
        randomHeading = (int)(Math.random()*4+1);
    }
    
    Rectangle.set(this.getX(),this.getY(),this.getWidth(),this.getHeight());
}

For these changes to work, you'll need to add the following fields to your class:

int randomHeading
float timeTravelled 

You will also probably want to adjust the value assigned to maxTravelTime.
Without the rest of your code I can't check my solution against a compiler, but hopefully this is enough to help you out.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.