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

2024/5/23

how do i make actor throw knife and stop??

sussywussy sussywussy

2024/5/23

#
I am trying to make my dagger move to the world border, stop for one second, and then return back to the actor. However, the dagger moves way too quick and I can't even see it moving. Also I haven't been able to find a way to make the dagger just stay there without pausing everything else. Please help!!! Here is my code (the boolean is for something else):
public void shoot()
    {
        if (Greenfoot.mouseClicked(null))
        {
            b=false;
            while (getX()<1066 && getY()<800 && getY()>0 && getX()>0)
            {
                moveDelay();
            }
            Greenfoot.delay(1);
            b = true;
            
        }
    }
danpost danpost

2024/5/24

#
sussywussy wrote...
I am trying to make my dagger move to the world border, stop for one second, and then return back to the actor. However, the dagger moves way too quick and I can't even see it moving. Also I haven't been able to find a way to make the dagger just stay there without pausing everything else. Please help!!! Here is my code (the boolean is for something else): << Code Omitted >>
You need to program the act method for each act step. It is not a step by step, life cycle listing. Your while loop completes in one act step. Line 10 is pausing everything. Apparently, the dagger has 4 possible states, IDLE, SHOT, DELAY and RETURN, They cycle in order when a shot is initiated. The time to reach the edge and the time to return to the actor are variable, but the delay time is constant. So and int field will be needed to act as a timer for the DELAY mode. The actor itself will probably not be at the same location when the dagger returns; so, the dagger must be programmed to "chase down" the actor (when in RETURN mode). The click only triggers the shooting of the dagger (sets SHOT mode). Reaching the edge of the world will trigger DELAY mode, after which the exhaustion of the timer will trigger RETURN mode; and, returning to the actor will trigger IDLE mode once again. Once the dagger is shot, no clicks can be registered to shoot the dagger until it returns. So, you might have something like this:
private static final int RETURN = -1, IDLE = 0, SHOT = 1, DELAY = 2;

int mode = IDLE;
int delayTimer = 0;

public void act() {
    if (mode == IDLE && Greenfoot.mouseClicked(null)) mode = SHOT;
    else if (mode == SHOT && findingEdge()) mode = DELAY;
    else if (mode == DELAY && finishingDelay()) mode = RETURN;
    else if (mode == RETURN && findingActor()) mode = IDLE;
}
The code within this act method could be coded this way:
switch (mode) {
    case 0:  if (Greenfoot.mouseClicked(null)) mode = SHOT; break;
    case 1:  if (findingEdge()) mode = DELAY; break;
    case 2:  if (finishingDelay()) mode = RETURN: break;
    case -1:  if (findingActor()) mode = IDLE; break;
}
Or, it could be:
if (mode == IDLE && Greenfoot.mouseClicked(null) ||
    mode == SHOT && findingEdge() ||
    mode == DELAY && finishingDelay() ||
    mode == RETURN && findingActor())
        mode = ((mode+2)%4)-1;
The 3 new methods, findingEdge, finishingDelay and findingActor perform their respective duties and return a true value when completed, otherwise they return a false value.
private boolean findingEdge() {
    move(5);
    return (isAtEdge());
}

private boolean finishingDelay() {
    return (timerDelay+1)%60 == 0;
}

private boolean findingActor() {
    int rotation = getRotation();
    turnTowards(getActorX(), getActorY);
    move(5);
    setRotation(rotation);
    return isTouching(Actor.class);
}
I don't care how you get the x and y of the actor in the turnToward command as there are multiple ways to get those values. The type of Actor class (subclass of Actor) will need specified in the last line.
sussywussy sussywussy

2024/5/24

#
Thank you very much, danpost!!! This was so helpful.
danpost danpost

2024/5/25

#
sussywussy wrote...
Thank you very much, danpost!!! This was so helpful.
Two things: (1) in the switch code, the literals should probably be the modes; ex:
case IDLE:  if (Greenfoot.mouseClicked(null)) mode = SHOT; break;
(2) The line in the finishingDelay method should be:
return (++delayTimer)%60 == 0;
You need to login to post a reply.