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

2022/6/9

Need help with a booster

ao_ ao_

2022/6/9

#
I'm trying to code a racing game and need help with the booster-system. I implemented two cars with two separate bars. The bars should gradually decrease while the cars get faster, but I can't seem to have these two operations happen simultaneously. When I press the button to use the booster, the car stops. I'm fairly new to Greenfoot, so I have no idea what the problem might be. Is there a way to solve it? Here's the code from the car/player1 class:
import greenfoot.*;  

public class player1 extends player
{
    int speed;
    public static boolean canUseBooster1 = true;

    public player1(){
        speed = 4;
    }
    
    public void act() 
    {
        checkKeyPress("a","d","w","s", "f");
        checkBooster1();
    }
    
    public void checkKeyPress(String left, String right, String up, String down, String f)
    {
         if (Greenfoot.isKeyDown(right))
        {
            turn(speed);
        }
        if (Greenfoot.isKeyDown(left))
        {
            turn(-speed);
        }
        if (Greenfoot.isKeyDown(up))
        {
            move(speed);
        }
        if (Greenfoot.isKeyDown(down))
        {
            move(-speed);
        }
        if(Greenfoot.isKeyDown(f) && canUseBooster1)
        {
            speed = 10;
        }
        else{
            speed = 4;
        }
        
    }
    
    public void checkBooster1(){
        
        if (1==1){ //set it to 1=1, so I can test it
            canUseBooster1 = true;
        }
        else{
            canUseBooster1 = false;
        }
    }
    
    
   }
Here's the code from booster:
import greenfoot.*; 
public class booster extends Actor
{
    int fuel = 100;
    int fuelBarWidth = 20;
    int fuelBarHeight = 100;
    int pixels = (int)fuelBarHeight/fuel;
    public booster(){
        update();
    }
    
    public void act()
    {
        update();
    }
    public void update(){
        setImage(new GreenfootImage(fuelBarWidth+2, fuelBarHeight+2));
        GreenfootImage myImage = getImage();
        myImage.setColor(Color.WHITE);
        myImage.drawRect(0,0, fuelBarWidth+1, fuelBarHeight+1);
        myImage.setColor(Color.BLUE);
        myImage.fillRect(1,1, fuelBarWidth, fuel*pixels);
    }
    
    public void loseFuel(int x){
        fuel = fuel-x;
        update();
    }
    
}
And here the one from the subclass booster1:
import greenfoot.*;  
public class booster1 extends booster
{
    long timer = 100000;
    
    public void act()
    {
        update();
        checkKeyPress("f");
    }
    
    public void checkKeyPress(String f){
        while(Greenfoot.isKeyDown(f)){
            if(timer > 0){
                timer--;
                if(timer == 0){
                    loseFuel(1);
                    update();
                    timer = 100000;
                }
            }
        }
    }
}
Thanks a lot in advance
danpost danpost

2022/6/9

#
ao_ wrote...
Here's the code from the car/player1 class: << Codes Omitted >>
Your player class needs to be provided. However, in your booster1 class, line 13 should use an if, not a while. Also, lines 4 and 19 set the timer value way too high (no wonder it appears to not change -- as is, it will take some time before any change is seen, if all is working properly). For testing, use a value between 10 and 100. Then, make it 50 to 60 times however many seconds you want between the times when it decreases.
ao_ ao_

2022/6/9

#
My player class is almost empty, I wrote the code in the subclasses (I'll have to fix that). I used "while", so that the progress bar goes down gradually, instead of it going down by e.g. 10 every time the key is pressed. Is there another way to do that? As for the timer, it actually makes the bar go down quite fast, when I used 10/100 it just disappeared right away. The bar for the booster does go down. The thing is, when I press the corresponding key the car stops, which would defeat the whole purpose of a boost.
danpost danpost

2022/6/9

#
ao_ wrote...
My player class is almost empty,
Okay.
I used "while", so that the progress bar goes down gradually, instead of it going down by e.g. 10 every time the key is pressed.
A while loop will run completely within one act step. So, currently, your booster will deplete and restart (at 100000) each act step. This actually results in no overall change. Once you change it to an if statement, the timer value being so large will make it run, but real slow (hours between each change).
As for the timer, it actually makes the bar go down quite fast, when I used 10/100 it just disappeared right away. The bar for the booster does go down. The thing is, when I press the corresponding key the car stops, which would defeat the whole purpose of a boost.
Yes. Ten act steps is all it would take, which is possible to accumulate in one pressing of the key. It may also be possible that those particular key combinations are not detectable (keyboards are quarky that way). Play around using different keys. You do not have to check for the timer being greater than zero (line 14 in booster1 class). It will always be greater than zero because you reset it when it hits zero (line 19) . Also, you do not have to call update at line 18. It is subsequently called in the loseFuel method which is called from line 17. You will run into a dilemma when you try to control canUseBooster1. The bar will only know the state of the 'f' key; it will not know what the value of this field will be.
ao_ ao_

2022/6/9

#
danpost wrote...
You will run into a dilemma when you try to control canUseBooster1. The bar will only know the state of the 'f' key; it will not know what the value of this field will be.
Yeah, I tried doing it like this...
public void checkBooster1(){
        if (myWorld.b1.fuelAmount() > 0){
            canUseBooster1 = true;
        }
        else{
            canUseBooster1 = false;
        }
    }
with a return method in booster1
int fuelAmount(){
        return fuel;
    }
... but I keep getting a null pointer exception error (line 2). Other than that, I fixed the code from booster1 as you instructed and it's perfect. (
public void checkKeyPress(String f){ if(Greenfoot.isKeyDown(f)){ loseFuel(1); } }
)
ao_ ao_

2022/6/9

#
I figured it out. I created 2 separate methods in player1 (canUseB() and cantUseB()) (with public static boolean canUseBooster1;)
    public void canUseB(){
         canUseBooster1 = true;   
    }
    public void cantUseB(){
        canUseBooster1 = false;
    }
   }
In the World class I created a return method for the object p1 (from the class player1):
public player1 getPlayer1(){
        return p1;
    }
And in booster I created a method, that checks if the fuel is less or equal to 0, which I put in the act() method:
public void checkIfCanUse(){
        if(fuel <= 0){
            ((MyWorld) getWorld()).getPlayer1().cantUseB();
        }
        else{
            ((MyWorld) getWorld()).getPlayer1().canUseB();
        }
    }
I hope this will have solved the problem. Thank you for yourhelp!
You need to login to post a reply.