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

2020/3/18

Key released?

whattheheck whattheheck

2020/3/18

#
How would I be able to detect when a key is released? I have code for when a key is held, using isKeyDown, but I'm looking for a method to detect when the key is released
Yehuda Yehuda

2020/3/19

#
You can do it yourself. Create a Boolean that gets set to isKeyDown. If the Boolean and the method are not equal to each other, that means the state of the key has changed. If isKeyDown returns false, and your Boolean is true, the key was just released, since after every change you set your Boolean to the method.
whattheheck whattheheck

2020/3/19

#
I have figured out a way to do it using the getKey method, but I seem to be having an issue with what my program should be doing. I'm trying to program a moving car that when the "drive" key is released, the car still moves but slows down. I would figure that a while loop would be useful, and if the key is released, decelerate and move until speed is 0, but the car just moves forwards in one big motion. My code is below: Actor.Car.ControlledCar:
public class ControlledCar extends Car
{   
    /**
     * Act - do whatever the ControlledCar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        String key = Greenfoot.getKey();
        setImage("car01.png");
        if(Greenfoot.isKeyDown("up")) {
            accelerate(.25);
            wrap();
            int speed = (int) this.speed;
            move(speed);
        }
        if (key != null) {
            if("up".equals(key)) {
                while (this.speed > 0) {
                    accelerate(-.25);
                    wrap();
                    int speed = (int) this.speed;
                    move(speed);
                }
            }
            if("down".equals(key)) {
                while (this.speed > 0) {
                    accelerate(-.1);
                    wrap();
                    int speed = (int) this.speed;
                    move(-speed);
                }
            }
        }    
        if(Greenfoot.isKeyDown("right")) {
            turn(5);
        }
        if(Greenfoot.isKeyDown("down")) {
            accelerate(.5);
            wrap();
            int speed = (int) this.speed;
            move(-speed);
        }
        if(Greenfoot.isKeyDown("left")) {
            turn(-5);
        }
    }  
    ControlledCar(String licenceIn, double speedIn, double maxSpeedIn) {
        super("null", 0, 10);
    }
}
Actor.Car:
public class Car extends Actor
{
    //setter vars
    String licencePlate;
    double speed;
    double maxSpeed;
    
    //setter methods
    
    void setLicence(String licencePlate) { //setter method for licence plate
        this.licencePlate = licencePlate; //licence plate changes to input
    }
    
    void setSpeed(double speed) { //setter method for speed
        this.speed = speed; //speed changes to input
    }
    
    void setMaxSpeed(double maxSpeed) { //setter method for max speed
        this.maxSpeed = maxSpeed; //maxspeed changes to input
    }
    
    //getter methods
    
    String getLicence() { //getter method for licence plate
        return this.licencePlate; //return this instances licence plate
    }
    
    double getSpeed() { //getter method for speed
        return this.speed; //return this instances speed
    }
    
    double getMaxSpeed() { //getter method for max speed
        return this.maxSpeed; //return this instances maxspeed
    }
    
    
    //extra methods
    
    //'floor' it method
    void floorIt() {
        this.speed = this.maxSpeed; //set speed to maxspeed
    }
    //accelerate method
    void accelerate(double velocity) {
        this.speed += velocity; //change speed based on change in velocity
        if (this.speed >= this.maxSpeed) { //test if new speed is greater
            this.speed = this.maxSpeed; //if it is, speed = maxspeed
        }
        if (this.speed < 0.0) { //test if speed is less than 0
            this.speed = 0.0; //if it is, speed = 0
        }
    }
    
    
    public void act() 
    {
        
    }
    //creation of Car constructor
    public Car(String licenceIn, double speedIn, double maxSpeedIn) { //take input of licence plate, speed, and max speed
       licencePlate = licenceIn; //licencePlate var will always be the licenceIn
       
       if (speedIn >= 0) { //check if speedIn is greater than 0
           speed = speedIn; //if greater, speed = speedIn
       } else {
           speed = 0.0; //otherwise speed = 0
       }
       
       if (maxSpeedIn >= 0) { //check if maxspeed is greater than 0
           maxSpeed = maxSpeedIn; //if greater, maxspeed = maxspeedin
       } else {
           maxSpeed = 0.0; //otherwise, maxspeed = 0
       }
    }
    
    //wrap method to change location of object to other side of world
    void wrap() {
        if(getX() == getWorld().getWidth()-1) { //check if at edge of world width
            setLocation(1, getY()); //set location to other edge
        }
        if(getY() == getWorld().getHeight()-1) { //check if at edge of world height
            setLocation(getX(), 1); //set location to other edge
        }
        if(getX() == 0) { //check if at start of widths edge
            setLocation(getWorld().getWidth()-1, getY()); //set location to other edge
        }
        if(getY() == 0) { //check if at start of heights edge
            setLocation(getX(), getWorld().getHeight()-1); //set location to other edge
        }
    }
}
whattheheck whattheheck

2020/3/19

#
I have found that adding an else if statement to the ifKeyDown up block works for forward movement, but I would like both forward and backward movement to share this gradual slow down, is there a way to modify the code for both forwards and backwards movement?
if(Greenfoot.isKeyDown("up")) {
            if (this.speed < this.maxSpeed) {
                accelerate(.1);
            }
            wrap();
            move(speed);
        } else if (!Greenfoot.isKeyDown("up") && !Greenfoot.isKeyDown("down")) {
                if (this.speed > 0) {
                    accelerate(-.2);
                }
                wrap();
                move(speed);
        }
danpost danpost

2020/3/19

#
Though not tested, the following hopefully will produce the results you want:
int d = 0;
if (Greenfoot.isKeyDown("up")) d++;
if (Greenfoot.isKeyDown("down")) d--;
double ds = -0.1; // assume no key (slowing down)
if (d != 0) ds = 0.2*d; // accelerating/decelerating
if (speed+ds < 0) ds = -speed; // stopping;
accelerate(ds);
wrap();
move(speed);
whattheheck whattheheck

2020/3/19

#
That method seems to launch the car forward when trying to move backwards
danpost danpost

2020/3/19

#
whattheheck wrote...
That method seems to launch the car forward when trying to move backwards
I guess I was confused. Your accelerate method precludes the car from moving backward (see lines 49 and 50 above). Also, I do not see a move method in the class. If you are using the move method in the Actor class, then all your attempts to use double values is for naught as all fractional precision is lost.
whattheheck whattheheck

2020/3/19

#
I forgot about the limit I put on the acceleration, I have removed that if statement. This is my current code under ControlledCar's act, it doesn't seem to move backwards at all even with the if statement gone. I know about the issue with using doubles as well, I will fix it after I have the rolling movement complete
public void act() 
    {
        int speed = (int) this.speed;
        setImage("car01.png");
        int d = 0;
        if (Greenfoot.isKeyDown("up")) d++;
        if (Greenfoot.isKeyDown("down")) d--;
        double ds = -0.1; // assume no key (slowing down)
        if (d != 0) ds = 0.2*d; // accelerating/decelerating
        if (speed+ds < 0) ds = -speed; // stopping;
        accelerate(ds);
        wrap();
        move(speed);
        if(Greenfoot.isKeyDown("right")) {
            turn(5);
        }
        if(Greenfoot.isKeyDown("left")) {
            turn(-5);
        }
    }  
danpost danpost

2020/3/19

#
whattheheck wrote...
I forgot about the limit I put on the acceleration, I have removed that if statement. This is my current code under ControlledCar's act, it doesn't seem to move backwards at all even with the if statement gone.
Of course not. I wrote the code knowing it was not going to be going backwards. Now that you have removed that restriction, and backwards movement is preferred, my codes will need to be adjusted.
I know about the issue with using doubles as well, I will fix it after I have the rolling movement complete
Maybe this will do:
import greenfoot.*;

public class Car extends Actor
{
    double x, y, speed;
    
    protected void addedToWorld(World w)
    {
        x = getX();
        y = getY();
    }
    public void act()
    {
        moving();
        turning();
    }
    
    private void turning()
    {
        int dr = 0;
        if (Greenfoot.isKeyDown("left")) dr--;
        if (Greenfoot.isKeyDown("right")) dr++;
        turn(dr*3);
    }
    
    private void moving()
    {
        int d = 0;
        if (Greenfoot.isKeyDown("up")) d++;
        if (Greenfoot.isKeyDown("down")) d--;
        double ds = -0.1;
        if (d != 0) ds = 0.2*d;
        if (speed+ds < 0) ds = -speed;
        accelerate(ds);
        move();        
    }
    
    private void accelerate(double amt)
    {
        speed += amt;
        if (speed > 5) speed = 5.0;
    }
    
    private void wrap()
    {
        int w = getWorld().getWidth();
        int h = getWorld().getHeight();
        x = (x+w)%w;
        y = (y+h)%h;
    }
    
    private void move()
    {
        double angle = Math.PI*getRotation()/180;
        double dx = Math.cos(angle)*speed;
        double dy = Math.sin(angle)*speed;
        x += dx;
        y += dy;
        wrap();
        setLocation((int)x, (int)y);
    }
}
danpost danpost

2020/3/19

#
Adjustments for moving backwards forthcoming.
danpost danpost

2020/3/19

#
Replace the following two methods in my Car class above:
private void moving()
{
    int d = 0;
    if (Greenfoot.isKeyDown("up")) d++;
    if (Greenfoot.isKeyDown("down")) d--;
    double ds = -0.05*Math.signum(speed);
    if (d != 0) ds = 0.2*d;
    accelerate(ds);
    move();        
}

private void accelerate(double amt)
{
    speed += amt;
    if (Math.abs(speed) > 5) speed = 5.0*Math.signum(speed);
}
You need to login to post a reply.