This site requires JavaScript, please enable it in your browser!
Greenfoot back
Wolfy5039
Wolfy5039 wrote ...

2024/10/25

How to make smoother movement in characters?

Wolfy5039 Wolfy5039

2024/10/25

#
private void swoop(){
        canMoveLaterally = false; 
       if (swoopingDown) {
            setLocation(getX(), getY() + 2 );
            speed += 10;
            if (getY() >= maxY) {
                swoopingDown = false;  // Change direction to move up
            }
        }
        // move back up and then only do move method until timer
        else {
           if (getY() > minY) {
                    setLocation(getX(), getY() );
                    speed += 3;
            } else {
                swoopingDown = true; // Reset to swoop down again
                    canMoveLaterally = true;
                speed = 5;
            }
    }
    }
Wolfy5039 Wolfy5039

2024/10/25

#
I am having a lot of trouble making the swooping movement faster and smoother. the character just teleports to its next position and its frustrating. How do i do this?
danpost danpost

2024/10/25

#
Wolfy5039 wrote...
I am having a lot of trouble making the swooping movement faster and smoother. the character just teleports to its next position
You are messing around with this speed variable that does not seem to be doing anything. Also,, the else part says to NOT move (which goes without coding). That is, line 13 can be removed without changing what the code does. Increasing speed by 10 each act step (line 5) seems excessive, but without speed being used in the actual movement, I do not see how that could be causing any problems like you are experiencing. There are several suitable classes you can import into your project to improve the smoothness of the movement. These are classes that the class of your actor can extend from. Greenfoot provides its SmoothMover class (imported via the menubar in your greenfoot application) -- Edit >> Import class... >> SmoothMover. I also have written a class for smooth movement (which also includes smoother rotations). The class is called QActor (for quality actor) and can be found in my Asteroids w/improved QActor SuperClass scenario.
Wolfy5039 Wolfy5039

2024/10/26

#
To be honest, even when fixing this, the whole thhing doesnt work as it is supposed to. What I am trying to do is make a bird be able to swoop down after a timer has run out, then go back up to a specific spot and then continue to move across the screen again but it is not working as it is supposed to. the bird swoops to much. Also, I tried using the SmoothMover thing and I dont really quite understand it. Should I extend my bird class to it? Because If that is what I have to do then some of my methods seem to stop working.
Wolfy5039 Wolfy5039

2024/10/26

#
I thought maybe increasing the speed would help but now it also continuously loops and does not stop
danpost danpost

2024/10/26

#
Wolfy5039 wrote...
I thought maybe increasing the speed would help but now it also continuously loops and does not stop
Please provide the entire class code. Btw, the QActor class is not to be modified. Any modifications can be done in your class.
Wolfy5039 Wolfy5039

2024/10/28

#
Ive decided to come up with a different solution so I was able to get the movement down okay. Now the issue is that I want the bird to hit a line barrier and then get removed and then respawn. Or atleast just stop doing the swoop method if it hits the barrier until the timer reaches 0 again? Anything that resets the bird so that it will not forever swoop. here is the code i created that would let the bird respawn, but it does not do that. Instead it infinetly spawns birds.
private void swoophandle(){
            Swooptimer --;  //decreases time on timer by 1 every frame
            if (Swooptimer == 0){ //when timer reaches 0
                 swoop(); //method that makes bird swoop
                Swooptimer = Greenfoot.getRandomNumber(10) +5; //resets timer
           }
        }
public void check(){
     if (isTouching(Barrier.class)) {
         
         getWorld().removeObject(this); // Remove the bird from the world
        respawntimer = 120; 
            
            
            
                    }
                
    }
    public void remove() {
        check(); // Check for collision with the barrier
        if (respawntimer > 0) {
            respawntimer--; // Count down the timer if it's above 0
        } else {
            spawnBird();
        }
    }

    private void spawnBird() {
        int x = Greenfoot.getRandomNumber(getWorld().getWidth()); // Random x-coordinate
        int y = 100; // Fixed y-coordinate
        ((CrabWorld) getWorld()).addObject(new Bird(), x, y); // Spawn a new bird at the specified coordinates
        respawntimer = 0; // Reset timer after spawning
    }
    private void removespawn(){
        check();
        remove();
    }
private void swoop() {
    canMoveLaterally = false; 
    if (swoopingDown) {
        setLocation(getX(), getY() + 2); // Control the swooping down speed
        if (getY() >= maxY) {
            swoopingDown = false; // Change direction to move up
        }
    } else {
        if (getY() > minY) {
            setLocation(getX(), getY() - 2); // Control the swooping up speed
        } else {
            swoopingDown = true; // Reset to swoop down again
            canMoveLaterally = true; // Allow lateral movement again
        }
    }
}
danpost danpost

2024/10/28

#
Wolfy5039 wrote...
here is the code i created that would let the bird respawn, but it does not do that. Instead it infinetly spawns birds. << Code Omitted >>
Your remove method is allowing spawning every act that the respawntimer field has a value of zero.. You only want it to res-pawn when the counter reaches zero (or at the moment it becomes zero -- not while its zero). Simple fix:
public void remove() {
    check(); // Check for collision with the barrier
    if (respawntimer > 0 && --respawntimer  == 0) {
        spawnBird();
    }
}
danpost danpost

2024/11/1

#
danpost wrote...
Simple fix: << Code Omitted >>
Sorry ... not quite so simple. The timer for respawning cannot be in the class of the instance for the actor removed from the world. It's act method will not be called to count the timer down. Since you will only ever have one instance of that actor at any one time, you can have the world run a respawn timer: (in CrabWorld)
int spawnTimer;

public void act() {
    if (spawnTimer > 0 && --spawnTimer == 0) {
        int x = Greenfoot.getRandomNumber(getWidth()); 
        int y = 100;
        addObject(new Bird(), x, y);
    }
}

public void removeObject(Actor actor) {
    if (actor != null && (actor instanceof Bird)) {
        spawnTimer = 120;
    }    
    super.removeObject(actor);
}
  
You need to login to post a reply.