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

2024/4/20

Why are my hearts offset from the left?

daviddd daviddd

2024/4/20

#
Hey, i am trying to make a game, on the main menu screen you select your difficulty, e.g easy, you will have 5 lives and they will show up as hearts in the top left corner of the game, but when i pick medium or hard they will be moved a bit to the right, does anyone know why is that?
import greenfoot.*;

public class HealthBar extends Actor {
    private int health;

    public HealthBar(int initialHealth) {
        this.health = initialHealth;
        update();
    }

    public void update() {
        GreenfootImage image = new GreenfootImage(50 * health, 50);
        image.clear();
        for (int i = 0; i < health; i++) {
            GreenfootImage heart = new GreenfootImage("heart.png");
            heart.scale(40, 40);
            image.drawImage(heart, i * 45, 5);
        }
        setImage(image);
    }

    public void loseHealth() {
        if (health > 0) {
            health--;
            update();
        }
    }

    public boolean isAlive() {
        return health > 0;
    }
}


import greenfoot.*;

public class Dungeon extends World {
    private Player player;
    private HealthBar healthBar;
    public Dungeon(int difficulty, int initialHealth) {
        super(600, 400, 1);
        player = new Player(difficulty);
        addObject(player, 300, 200);
        populateMonsters();
    }
    public Dungeon(int initialHealth) {
        super(800, 600, 1);
        healthBar = new HealthBar(initialHealth);
        addObject(healthBar, 125, 30);
        
    }
    
    private void populateMonsters() {
        for (int i = 0; i < 10; i++) {
            addObject(new Monster(), Greenfoot.getRandomNumber(getWidth()), Greenfoot.getRandomNumber(getHeight()));
        }
        addObject(new Boss(), 500, 300);
    }
    
    public void act() {
        if (getObjects(Monster.class).isEmpty()) {
            
        }
    }
    
    public Player getPlayer() {
        return player;
    }
}


import greenfoot.*;

public class Button extends Actor {
    private String text;
    private int difficulty;

    public Button(String text, int difficulty) {
        this.text = text;
        this.difficulty = difficulty;
        updateImage();
    }

    private void updateImage() {
        GreenfootImage image = new GreenfootImage(text + " - Click to start", 24, Color.WHITE, Color.BLACK);
        setImage(image);
    }

    public void act() {
        if (Greenfoot.mouseClicked(this)) {
            int initialHealth = (difficulty == 1) ? 5 : ((difficulty == 2) ? 3 : 1);
            Greenfoot.setWorld(new Dungeon(initialHealth));
        }
    }
}

import greenfoot.*;

public class MainMenu extends World {
    
    public MainMenu() { 
        super(600, 400, 1); 
        prepare();
    }
    
    private void prepare() {
        addObject(new Button("Easy", 1), 300, 150);
        addObject(new Button("Medium", 2), 300, 200);
        addObject(new Button("Hard", 3), 300, 250);
    }
}
daviddd daviddd

2024/4/20

#
Btw, when you pick medium difficulty you will have 3 hearts, if you pick hard you will have 1
danpost danpost

2024/4/20

#
daviddd wrote...
Hey, i am trying to make a game, on the main menu screen you select your difficulty, e.g easy, you will have 5 lives and they will show up as hearts in the top left corner of the game, but when i pick medium or hard they will be moved a bit to the right, does anyone know why is that? << Code Omitted >>
The location of the HealthBar instance does not vary; but, its image size does. That is the essence of your problem. Either adjust the location as the health value changes or just don't change the size of the image. That is, replace health on line 12 with a 5 (the maximum number of hearts the image can have). The update method in the class can be as follows:
public void update() {
    GreenfootImage image = new GreenfootImage(50 * 5, 50);
    GreenfootImage heart = new GreenfootImage("heart.png");
    heart.scale(40, 40);
    for (int i = 0; i < health; i++) {
        image.drawImage(heart, 5+i * 50, 5);
    }
    setImage(image);
}
Line 2 (here) creates a new blank image, so it does not need cleared. Also, the heart image does not need to be created repeatedly; so, it does not need to be inside the loop (nor does the scalieing of the image). I also adjusted the horizontal placement of where the heart images are drawn to evenly space them within the main image.
You need to login to post a reply.