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

2013/7/23

problems with spawned units health bars

darkmist002 darkmist002

2013/7/23

#
i have made a class that creates a healthbar for the spawning units, but i have a few problems with it. a) it doesn't fill in the bar till the unit is hit b) it doesn't fill it proportionally trying to get it to show how much they've damaged the unit when the tower hits. here's the class for the healthbar:
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
public class healthbar extends Actor
{
    /**
     * Act - do whatever the healthbar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    GreenfootImage bar = new GreenfootImage(50, 10);//width and height
    public healthbar(int health)
    {
        bar.setColor(new Color(0,0,255));
        bar.fill();
        bar.setColor(new Color(0, 255, 0));
        bar.drawRect(0,0, 48, 8);
        bar.fillRect(0, 0, health, 8);
        setImage(bar);
    }
     
//     public void act()
//     {
//         // Add your action code here.
//         //imageUpdate();
//     }  
     
    public void imageUpdate(int health)
    {
        bar.clear();
        bar.setColor(new Color(0,0,255));
        bar.fill();
        bar.setColor(new Color(0, 255, 0));
        bar.fillRect(0, 0, health, 8);
        setImage(bar);
    }
}
and here's the class i'm implementing it in:
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
public class enemies extends Actor
{
    /**
     * Act - do whatever the enemies wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    int x = 0;
    int y = 0;
    private int wave = 1; //get from wave class
    public int health;
    public int mins;
    public int lifeLost;
    private int input = 0;
    private int i = 1;
    private int j = 0;
    private int slow = 0;
    private healthbar HPbar;
     
    public enemies()
    {
        //getWorld().addObject(new healthbar(health), this.getX(), this.getY() - 10);   
        HPbar = new healthbar(health);
    }
     
    public void act()
    {
        // Add your action code here.
        if(slowStat() && slow < 100)
        {
            slow++;
        }
        else
        {
           move();
           getWorld().addObject(HPbar, this.getX(), this.getY() - 20);
           HPbar.setLocation(this.getX(), this.getY() - 10);
           if(slow == 100)
           {
               ((tdpath)getWorld()).removeSlowMatter();
               slow = 0;
           }
        }
//         slowMove();
       checkHealth();
       checkWave();
       if(((tdpath)getWorld()).waveNum() > 5 && ((tdpath)getWorld()).spawnsDone() && ((tdpath)getWorld()).getSpawnsAlive() == 0)
       {
           input = 0;
       }
       if(j == 5)
            {
                i++;
                j = 0;
            }
    }   
     
    public int getHealth()
    {
        return health;
    }
     
    public void decHealth(int damage)
    {
        health = health - damage;
        HPbar.imageUpdate(health);
        checkHealth();
    }
     
    public void setHealth(int hp)
    {
        health = hp;
    }
     
    public void checkHealth()
    {
        if (health <= 0)
        {
             ((tdpath)getWorld()).mineralsAdd(mins);
             ((tdpath)getWorld()).killSpawn();
             getWorld().removeObject(HPbar);
            ((tdpath)getWorld()).removeObject(this);
        }
    }
     
    public void move()
    {
        if(getWorld().getColorAt(getX()+1, getY()).getRed() < 10 && getWorld().getColorAt(getX()+1, getY()).getGreen() < 10 && x !=-1)     
            {     
                setLocation(getX() + 1,getY());   
                 
                x = 1;
                y = 0;
            }     
            else if(getWorld().getColorAt(getX()-1, getY()).getRed() < 10 && getWorld().getColorAt(getX()-1, getY()).getGreen() < 10 && x !=1)     
            {     
                setLocation(getX()-1, getY());     
                 
                x = -1;
                y = 0;
            }
            
            else if(getWorld().getColorAt(getX(), getY()+1).getRed() < 10 && getWorld().getColorAt(getX(), getY()+1).getGreen() < 10 && y != -1)     
            {     
                setLocation(getX(), getY()+1);     
                x = 0;
                y = 1;
            }
            else if(getWorld().getColorAt(getX(), getY()-1).getRed() < 10 && getWorld().getColorAt(getX(), getY()-1).getGreen() < 10 && y !=1)     
            {     
                setLocation(getX(), getY()-1);  
                x = 0;
                y = -1;
            }
    }
     
    public void slowMove()
    {
        
    }
     
    public int getLivesLost()
    {
        return lifeLost;
    }
     
    public int getSlow()
    {
        return slow;   
    }
     
    public void checkWave()
    {
        if((((tdpath)getWorld()).waveNum() > 5) && input < 1)//&& (((tdpath)getWorld()).waveNum())%5 >= 1 && input < 1)
        {
            healthInc();
            input++;
            j++;
        }
    }
     
    public void healthInc()
    {
        setHealth(health*(2*(((tdpath)getWorld()).waveNum()/5)));
         
    }
     
    public boolean slowStat()
    {
        if(!getObjectsInRange(50, slowMatter.class).isEmpty())
        {
            return true;
        }
        return false;
    }
     
    public void setSlow(int SL)
    {
        slow = SL;
    }
}
Gevater_Tod4711 Gevater_Tod4711

2013/7/23

#
To your first problem: When you create an enemies object the health of this object is 0 (line 10). Then you create the healthbar object with a health of 0 so the bar is empty. To fix this problem you can either set the health of the enemies when constructing the object (while the declaration or in the constructor before creating the new healthbar) or always set the starting image of the health bar to a full healthbar (line 14: bar.fillRect(0, 0, 48, 8); ) I'm not shure what you mean by proportonally but I think if you use fillRect(1, 1, 48, 8) instead of fillRect(0, 0, 48, 8) that may fix the problem.
darkmist002 darkmist002

2013/7/23

#
this is the parent class of the units that spawn, and each of the children classes have their health value set in their constructors, which is why it isn't set in the parent. i'll try the fill rec part you mentioned tho. nope, didn't change it.
danpost danpost

2013/7/23

#
In line 14 of the healthbar class, instead of 'health', you need something like '48*health/maxHealth'.
darkmist002 darkmist002

2013/7/23

#
i thought of a different way of doing it, but i'm not getting the percents right.
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
public class healthbar extends Actor
{
    /**
     * Act - do whatever the healthbar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    GreenfootImage bar = new GreenfootImage(50, 10);//width and height
    private int percentHP;
    private int maxBar = 50;
    private int enemiesMaxHP;
    public healthbar(int health)
    {
        bar.setColor(new Color(0,0,255));
        bar.fill();
        bar.setColor(new Color(0, 255, 0));
        bar.drawRect(1,1, 48, 8);
        bar.fillRect(1, 1, 48, 8);
        setImage(bar);
        enemiesMaxHP = health;
    }
     
//     public void act()
//     {
//         // Add your action code here.
//         //barImage();
//     }  
     
    public void imageUpdate(int health)
    {
        percentHP = (int)((health / enemiesMaxHP) * 100);
        bar.clear();
        bar.setColor(new Color(0,0,255));
        bar.fill();
        bar.setColor(new Color(0, 255, 0));
        bar.fillRect(1, 1, percentHP, 8);
        setImage(bar);
    }
}
didn't see your post, i'll try that with my code to see if that changes it.
darkmist002 darkmist002

2013/7/23

#
ok, tried what you said and it didn't do it, still makes the bar go from full to 0 when the hp is 2, and goes to 1 (should go to 50% bar filled). changed line 30 of what i just posted to : percentHP = (int)(maxBar *(health / enemiesMaxHP)); but it isn't filling it half way EDIT: i found where the mistake was, i had the parenthesis wrong. should've made it this way instead: percentHP = (int)((maxBar *health) / enemiesMaxHP); thanks for both your help.
darkmist002 darkmist002

2013/7/24

#
sorry to reopen this up, but i found a problem i didn't see before. it will remove fine when the tower kills the unit, but when i try to get the defense spot remove it before removing the spawned unit that hits it, and it gives me a null pointer exception. can't figure out why it does that when i tell it to remove it before removing the unit that is spawned, and also when i have it remove it the same way the class removes it when it is killed by the towers.
1
2
3
4
5
public void removeUnit()
    {
            getWorld().removeObject(HPbar);
            ((tdpath)getWorld()).removeObject(this);
    }
that's the coding i use and call that method from the world, then send it to the defense spot to remove it when the unit is to be removed.
danpost danpost

2013/7/24

#
In the defensespot class after 'world.removeObject(unit);' add 'world.removeObject(((enemies)unit).HPbar);'.
darkmist002 darkmist002

2013/7/25

#
took me awhile, but i got it. ended up creating another if statement that checked the radius of the object that removes the units when they come, and had the radius check for healthbars. if it wasn't empty, i had it remove the first one it sees. of course wouldn't have taken me 2 hrs if i had looked on here first, but oh well (although i did try something similar to that, but it wouldn't remove it since the healthbar stops before it gets to the spot, which is why i had to add a radius if statement; also tried something else where i had it send a boolean value to the enemies class so it could remove the bar that way, but it would either remove them all, or none at all, which is why i ended up doing it the way i did). thanks for the help.
danpost danpost

2013/7/25

#
With the way I suggested above, the healthbar will be removed at the time the enemies object who owns it is removed.
You need to login to post a reply.