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

2016/10/11

Health Bar

Samas Samas

2016/10/11

#
I have a health bar that I need to change based on when projectiles hit the player. The health bar I got with the help of greenfoot member so its not my personal code so I am only mostly sure I understand how it works.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import greenfoot.*;
import java.awt.Color;
import java.awt.color.*;
  
public class HealthBar extends Actor
{
    private final int maxValue = 200; // whatever max value you desire
    private int barValue = 200;
    private int lastValue = 0;
  
    public HealthBar()
    {
    }
  
    public void act()
    {
        if (barValue != lastValue)
        {
            lastValue = barValue;
            int pctHealth = (int) (200 * barValue / maxValue); // 200 is maxPixelHealth
            // Create thermometer -- sorta speak
            GreenfootImage imgOne = new GreenfootImage(206,25);
            imgOne.setColor(Color.CYAN);
            imgOne.fill();
            imgOne.setColor(Color.BLUE);
            imgOne.drawRect(2,2,202,21);
            // Add mercury, if there is any temperature -- sorta speak
            if (pctHealth != 0)
            {
                GreenfootImage imgTwo = new GreenfootImage(pctHealth,19);
                imgTwo.setColor(Color.RED);
                imgTwo.fill(); // Completes the second image
                imgOne.drawImage(imgTwo,3,3); // Puts mercury into the thermometer
            }
            // imgOne.scale(myX, myY); // Dimensions myX and myY are whatever size you wish to make it
            imgOne.setTransparency(128); // Adjust value as wanted or delete statement for no transparency
            setImage(imgOne);
        }
    }
  
    public void chgHealth(int chgValue)
    {
        barValue += chgValue;
        if (barValue > maxValue) barValue = maxValue;
        if (barValue < 0) barValue = 0;
    }
  
    public int getHealth()
    {
        return barValue;
    }
}
I want the Ship( player ) to lose health every time a MeanMissile ( enemy projectile) makes contact. Ship Code-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import greenfoot.*;
 
/**
 * An demo class which is meant to be a camera follower.
 * It moves to face your mouse cursor, and it can move
 * back and forward.
 *
 * @author Sven van Nigtevecht
 * @version 1.0
 */
public class Bug extends ScrollActor
{
    /** The number of cells we move forward and backword */
    private static final int MOVE_AMOUNT = 5;
    private int shootingCounter;
    public int angle;
    public int barValue;
    /**
     * Move to face the mouse,
     * and listen to the up and down keys.
     */
    public void act()
    {
        MouseInfo m = Greenfoot.getMouseInfo();
        getWorld().setCameraDirection(getRotation());
        Actor First = null;
         
        if (Greenfoot.isKeyDown("down"))
            {
            // move the camera backwards:
            getWorld().moveCamera(-MOVE_AMOUNT);
            }
        if (Greenfoot.isKeyDown("up"))
            {
            // move the camera forwards:
            getWorld().moveCamera(MOVE_AMOUNT);
            }
        if (Greenfoot.isKeyDown("left"))
            {
             turn ( -3 );
             angle -= 3;
            }
        if (Greenfoot.isKeyDown("right"))
            {
             turn ( 3 );
             angle += 3;
            }
        if (Greenfoot.isKeyDown("b"))
            {
            getWorld().moveCamera( MOVE_AMOUNT * 2) ;
            }
        if (Greenfoot.isKeyDown("b"))
            {
            getWorld().moveCamera( MOVE_AMOUNT * 2) ;
            }
        if (First != null )
            {
            move (-10);
            }
        if ( angle > 360)
            {
            angle = 0;
            }
        if ( angle < 0)
            {
            angle = 360;
            }
        shoot();
        
        Actor MeanMissile;
        MeanMissile = getOneObjectAtOffset(0,0, MeanMissile.class);
        if ( MeanMissile != null )
            {
             
            World Galaxy;
            Galaxy = getWorld();
            Galaxy.removeObject(MeanMissile);
            Galaxy.addObject( new explosion(), getGlobalX(), getGlobalY());
             
             
             }  
    }
    public void shoot()
        {
        shootingCounter--;
        if(Greenfoot.isKeyDown("s") && shootingCounter <= 0  )
        {
            shootingCounter=20;
            getWorld().addObject(new ShipMissile(angle), getGlobalX(), getGlobalY());
             
        }
    }
    public int getGlobalY()
    {
        if (world == null)
            throw new IllegalStateException("Actor not in world. Either is hasn't"+
            " been inserted, or it has been deleted.");
        return globalY;
    }
    public int getGlobalX()
    {
        if (world == null)
            throw new IllegalStateException("Actor not in world. Either is hasn't"+
            " been inserted, or it has been deleted.");
        return globalX;
    }
     
    }
danpost danpost

2016/10/11

#
I see you have acquired one of my earliest versions of a HealthBar class. Fortunately, it was tested and did work. So, that code should be fine. The other class you posted seems to be a modified version of the Bug class from the 'Scrolling world' scenario by SPower. First, you do not need to copy any code (methods or fields) from the ScrollActor class into the Bug class. As a subclass of the ScrollActor class, anything not 'private' is inherently available to the Bug class. Second, you do not need to keep track of the rotation of the actor. You can use the 'getRotation' method to get that value when needed (the Actor class has a hidden 'private int rotation' field where that value is already stored for any and all actors that the 'getRotation' method returns the value of). Next, you have declared a couple, at least, fields that are being initialized, but not being utilized later on, at all. For example, line 24 gets a MouseInfo object and stores a reference to it in a local variable called 'm'; but, nowhere in the method after that are you making any use of that reference. Also, line 26 declares a local reference variable for an Actor called 'First', initialized to 'null'; yet, nowhere are you attempting to assign any valid reference to the variable -- so, it will always be null by the time execution gets to line 56; this makes line 58 essentially unreachable. Therefore, lines 24, 26 and 56 through 59 can be removed without changing what the code currently does. Now, for the health bar. I presume you create one and add it into the world. Also, I presume that you only have one ship, and therefore, only one health bar in the world. As such, you need to get, or keep, a reference to that health bar in the Bug class so that you can make the appropriate changes to it when needed. You can make use of the World class method 'getObjects' to get that reference:
1
HealthBar hb = (HealthBar)getWorld().getObjects(HealthBar.class).get(0);
However, keeping a reference to it in the Bug class is much less CPU intensive and makes it easier to work with. You can declare it as follows:
1
public HealthBar hb;
and in the world class, after creating the Bug object and its HealthBar object, you can set the reference:
1
2
3
4
Bug bug = new Bug();
HealthBar healthbar = new HealthBar();
bug.hb = healthbar; // sets the bug's reference to its health bar
healthbar.act();// initializes the image of the health bar
Then, in the Bug class, you can use any of the following:
1
2
3
int barValue = hb.getHealth();
// or
hb.chgHealth(-20); // for example
It is best to get the value of the bar from the bar and not have another field, 'barValue', for that value in the Bug class. Remove line 17.
Samas Samas

2016/10/11

#
so I did all the things you suggested however I get an error that says it can't find the method getHealth() or when I try chHealth()
Samas Samas

2016/10/11

#
Got code to work but health bar does not drain
Samas Samas

2016/10/11

#
Samas wrote...
Got code to work but health bar does not drain
meaning there are no errors but the bar value is not actually affected
danpost danpost

2016/10/12

#
You need to show everything dealing with the bar and specify where each part is (class and method).
Samas Samas

2016/10/12

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Galaxy()
   {   
       // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
       super(800, 600, 1, 12000, 12000);
       addObject( new First(), 700, 1000 );
       addCameraFollower(new Bug(), 0, 0);
       addObject( new MeanShip(), 520, 1000 );
       addObject( new MeanShip(), 540, 1000 );
       addObject( new MeanShip(), 560, 1000 );
       addObject( new MeanShip(), 580, 1000 );
        
       addObject( new HealthBar(), 690,580);
       Bug bug = new Bug();
       HealthBar healthbar = new HealthBar();
       bug.hb = healthbar;
       healthbar.act();
          
   }
That is the world.
1
2
3
4
5
6
7
8
9
10
11
12
13
Actor MeanMissile;
        MeanMissile = getOneObjectAtOffset(0,0, MeanMissile.class);
         
        if ( MeanMissile != null )
            {
             
            World Galaxy;
            Galaxy = getWorld();
            Galaxy.removeObject(MeanMissile);
            Galaxy.addObject( new explosion(), getGlobalX(), getGlobalY());
            HealthBar hb = (HealthBar)getWorld().getObjects(HealthBar.class).get(0);
            int barValue = hb.getHealth();
             }
That is in the act() method of the Ship
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import greenfoot.*;
import java.awt.Color;
import java.awt.color.*;
  
public class HealthBar extends OnScreen
{
    public final int maxValue = 200; // whatever max value you desire
    public int barValue = 200;
    public int lastValue = 0;
    public HealthBar hb;
    public HealthBar()
    {
    }
  
    public void act()
    {
        if (barValue != lastValue)
        {
            lastValue = barValue;
            int pctHealth = (int) (200 * barValue / maxValue); // 200 is maxPixelHealth
            // Create thermometer -- sorta speak
            GreenfootImage imgOne = new GreenfootImage(206,25);
            imgOne.setColor(Color.CYAN);
            imgOne.fill();
            imgOne.setColor(Color.BLUE);
            imgOne.drawRect(2,2,202,21);
            // Add mercury, if there is any temperature -- sorta speak
            if (pctHealth != 0)
            {
                GreenfootImage imgTwo = new GreenfootImage(pctHealth,19);
                imgTwo.setColor(Color.RED);
                imgTwo.fill(); // Completes the second image
                imgOne.drawImage(imgTwo,3,3); // Puts mercury into the thermometer
            }
            // imgOne.scale(myX, myY); // Dimensions myX and myY are whatever size you wish to make it
            imgOne.setTransparency(128); // Adjust value as wanted or delete statement for no transparency
            setImage(imgOne);
        }
        if (barValue==0) Greenfoot.stop();
    }
  
     public void chgHealth(int chgValue)
    {
        barValue += chgValue;
        if (barValue > maxValue) barValue = maxValue;
        if (barValue < 0) barValue = 0;
    }
   
    public int getHealth()
    {
        return barValue;
    }
That is the HealthBar
danpost danpost

2016/10/12

#
The problem is that the act method of the ship is not changing the value of the bar. Please post the entire class that that act method is in.
Samas Samas

2016/10/12

#
import greenfoot.*; /** * An demo class which is meant to be a camera follower. * It moves to face your mouse cursor, and it can move * back and forward. * * @author Sven van Nigtevecht * @version 1.0 */ public class Bug extends ScrollActor { /** The number of cells we move forward and backword */ private static final int MOVE_AMOUNT = 5; private int shootingCounter; public int angle; public HealthBar hb; /** * Move to face the mouse, * and listen to the up and down keys. */ public void act() { getWorld().setCameraDirection(getRotation()); Actor First = null; if (Greenfoot.isKeyDown("down")) { // move the camera backwards: getWorld().moveCamera(-MOVE_AMOUNT); } if (Greenfoot.isKeyDown("up")) { // move the camera forwards: getWorld().moveCamera(MOVE_AMOUNT); } if (Greenfoot.isKeyDown("left")) { turn ( -3 ); angle -= 3; } if (Greenfoot.isKeyDown("right")) { turn ( 3 ); angle += 3; } if (Greenfoot.isKeyDown("b")) { getWorld().moveCamera( MOVE_AMOUNT * 2) ; } if (Greenfoot.isKeyDown("b")) { getWorld().moveCamera( MOVE_AMOUNT * 2) ; } if (First != null ) { move (-10); } if ( angle > 360) { angle = 0; } if ( angle < 0) { angle = 360; } shoot(); Actor MeanMissile; MeanMissile = getOneObjectAtOffset(0,0, MeanMissile.class); if ( MeanMissile != null ) { World Galaxy; Galaxy = getWorld(); Galaxy.removeObject(MeanMissile); Galaxy.addObject( new explosion(), getGlobalX(), getGlobalY()); HealthBar hb = (HealthBar)getWorld().getObjects(HealthBar.class).get(0); int barValue = hb.getHealth(); } } public void shoot() { shootingCounter--; if(Greenfoot.isKeyDown("s") && shootingCounter <= 0 ) { shootingCounter=20; getWorld().addObject(new ShipMissile(angle), getGlobalX(), getGlobalY()); } } public int getGlobalY() { if (world == null) throw new IllegalStateException("Actor not in world. Either is hasn't"+ " been inserted, or it has been deleted."); return globalY; } public int getGlobalX() { if (world == null) throw new IllegalStateException("Actor not in world. Either is hasn't"+ " been inserted, or it has been deleted."); return globalX; } } this is the entire class of the ship
MissionAccomplish MissionAccomplish

2016/10/12

#
well how can anyone check codes in such detail. u all ROCK
danpost danpost

2016/10/12

#
Okay -- first issue is in your world constructor. You are creating multiple Bug and HealthBar objects and the Bug object in the world is not being assigned a Healthbar object. Change the world constructor to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Galaxy()
{
    super(800, 600, 1, 12000, 12000);
    addObject(new First(), 700, 1000);
    Bug bug = new Bug();
    HealthBar healthbar = new HealthBar();
    bug.hb = healthbar;
    healthbar.act();
    addCameraFollower(bug, 0, 0);
    addObject(healthbar, 690, 580);
    addObject(new MeanShip(), 520, 1000);
    addObject(new MeanShip(), 540, 1000);
    addObject(new MeanShip(), 560, 1000);
    addObject(new MeanShip(), 580, 1000);
}
Now in your Bug class, you can remove this line:
1
HealthBar hb = (HealthBar)getWorld().getObjects(HealthBar.class).get(0);
and the line after needs to change the value of 'hb', not get its value; although, you should probably get its value after the change and check it for zero health and do whatever needs done then.
You need to login to post a reply.