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

2019/5/7

issues with modifying variable when using custom text

ErasedBlade ErasedBlade

2019/5/7

#
Im currently trying to use a method that creates it's own text and display's it (what's being said, style, and size being abstracted to change it to fit whatever i need) however im trying to use this text to display a variable for how much health the enemy actor has (hpE), however doing this i have put it in the constructor and the act methods, or each one separately. what I've accomplished by doing this is having it lag out (If in the act method) or not modifying it at all (If in constructor). does anyone have a solution?
Super_Hippo Super_Hippo

2019/5/7

#
Update the displayed text/value whenever it was changed. (And in the constructor.) But not every act without any reason to do so.
ErasedBlade ErasedBlade

2019/5/7

#
ok? so how would you do that? this is my text's code
        addObject(new Text("Enemy Health "+hpE, Font.PLAIN, 20), 400, 50);
sorry i responded late. I was in school still.
Super_Hippo Super_Hippo

2019/5/7

#
Show your Text class code.
ErasedBlade ErasedBlade

2019/5/7

#
oh ok private String txt; private int sty; private int textsize; /** * Creates text of diffrient styles */ public Text(String text, int style, int size) { int x = 1000; int y = 100; txt = text; sty= style; textsize = size; GreenfootImage img = new GreenfootImage(x,y); //img.setColor(Color.WHITE); //img.fill(); img.setColor(Color.CYAN); img.setFont(new Font("OptimusPrinceps",sty ,textsize)); img.drawString(text,(x/2),(y/4)); setImage(img); } the decoration class is just to group all of the objects together and resize them (Put this as a subclass just because of this)
Super_Hippo Super_Hippo

2019/5/8

#
I guess I would let the Enemy add the Text to the world and adjust it when needed:
private myText;

protected void addedToWorld(World w)
{
    myText = new Text("Enemy Health ", hpE, Font.PLAIN, 20);
    w.addObject(myText, 400, 50);
}

public void loseHealth(int amt)
{
    hpE -= amt;
    if (hpE <= 0)
    {
        hpE = 0;
        getWorld().removeObject(this);
    }
    myText.updateImage(hpE);
}
private String pre;
private int var, style, size;

public Text(String pre, int var, int style, int size)
{
    this.pre=pre; this.style=style, this.size=size;
    updateImage(var);
}

public void updateImage(int var)
{
    this.var = var;
    int x=1000, y=100;
    GreenfootImage img = new GreenfootImage(x, y);
    img.setColor(Color.CYAN);
    img.setFont(new Font("OptimusPrinceps", style, size));
    img.drawString(pre + var, x/2, y/4);
    setImage(img);
}
But since I am not exactly sure how and where you are using the hpE, this answer might not be accurate.
ErasedBlade ErasedBlade

2019/5/8

#
the hpE variable is being called from a super class of each individual level (As per suggestion of my instructor), however its being modified from the enemy class (Which is abstracted so it can be used for multiple enemies). i have modified the code so that it will now run in the world class, however, is there a reason why the variable hpE is declared as 3 in the constructor gets made 0? there is also a condition that if the hpE variable is 0, the level ends. and takes the player back to the previous screen (I messed with values to keep this from happening. and lastly can you explain the amt variable declared in the loseHealth methods heading?
Super_Hippo Super_Hippo

2019/5/8

#
ErasedBlade wrote...
i have modified the code so that it will now run in the world class, however, is there a reason why the variable hpE is declared as 3 in the constructor gets made 0?
I am not sure what you mean.
and lastly can you explain the amt variable declared in the loseHealth methods heading?
"amt" is meant to be the short form of "amount". I thought the "hpE" variable would be a variable of the Enemy class. What the method does is that when you call for example "loseHealth(2)" on an Enemy object, it will decrease its "hpE" variable by 2. (That's what "hpE -= amt" is doing which is the same as "hpE = hpE - amt".)
ErasedBlade ErasedBlade

2019/5/8

#
the world changes once the hpE = 0, and its called as 3 in the constructor of this priticular level. the method that is causing damage is in the superclass of the levels /** * returns remaining enemy hp value */ public int getHpE() { hpE = hpE - damageS; return hpE; } if your looking for the method to only get the variable itself the variable is called via protected int hpE; if it would help i can post the entire code for my Levels class, and my Level1 class (level being changed), Text class, weapon class, and my enemy class (all Actor classes)
Super_Hippo Super_Hippo

2019/5/8

#
Maybe it would help, yes. The structure seems to be a bit odd to me at least. Please use code-tags when posting code. (Individually for each class.)
ErasedBlade ErasedBlade

2019/5/8

#
ok here is the Levels class
import greenfoot.*;
/**
 * Write a description of class Levels here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public abstract class Levels extends World
{
    //Set Values
    //damage From ship
    protected static int damageS = 1;
    //damage from enemy
    protected static int damageE = 1 ;
    //total enemy health
    protected int hpE;
    //total ship Health
    protected int hpS = 3;
    //level counter (make multiple so taht if a player plays a previous level they still have access to their current level
    protected int level;
    //Set images for arrows to change worlds
    protected String [] arrowImage= {"RightArrow.png","LeftArrow.png"};
    //Star spawn timer
    public int sT;
    //Return  Values   
    /**
     * returns remaining enemy hp value
     */
    public int getHpE()
    {
        hpE = hpE - damageS;
        return hpE;
    }   

    /**
     * returns remaining ship hp value to remove if it hits 0
     */
    public int getHpS()
    {
        hpS = hpS - damageE;
        return hpS;
    }
    //Set up Worlds
    /**
     * Constructor for objects of class Levels
     */
    public Levels()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(600, 400, 1); 
    }

    /**
     * Level Constructor: calls Level(int, int, int, boolean) constructor with default bounding as true
     *
     * @param w the width of (or number of cells across) the world as an integer value
     * @param h the height of (or number of cells down) the world as an integer value
     * @param c the cellsize (width and height of a single cell) as an integer value
     */
    public Levels(int w, int h, int c)
    {
        this(w, h, c, true);
    }

    /**
     * This main constructor creates the common objects and sets the field values; common steps in construction among
     * all levels can be appended to the code; steps that are not common to all levels should be done in the constructor
     * of those particular levels
     *
     * @param w the width of (or number of cells across) the world as an integer value
     * @param h the height of (or number of cells down) the world as an integer value
     * @param c the cellsize (width and height of a single cell) as an integer value
     * @param b the bounding flag (whether the world is bounded or not) as a boolean value
     */
    public Levels(int w, int h, int c, boolean b)
    {
        super(w, h, c, b);
    }

    /**
     * switch to win screen if you beat all levels
     */
    public void winSwitch()
    {
        if(level ==500)
        {
            Greenfoot.setWorld(new Win());
        }
    }
    //Spawning
    public void spawnStars()
    {
        sT++;
        if(sT ==50)
        {
            addObject(new Stars(),399, Greenfoot.getRandomNumber(399)+1);
            sT= 0;
        }
    }

}
this is the level 1 class (Is a subclass of screen1 for orginization only. screen 1 is a subclass of Levels by the way)
import greenfoot.*;
import java.awt.Font;
/**
 * Write a description of class Level1 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Level1 extends Screen1
{
    //respawn timer
    private int hpt;
    //Theme song music
    private GreenfootSound music = new GreenfootSound("Think Fast.wav");
    //sets enemy remaining value
    protected static int er1= 1;
    //Checks if level2 has been complete
    protected static boolean level1Complete = false;
    //text
    private Text myText;
    //Audio
    /**
     * Play music in a loop
     */
    public void started()
    {
        music.playLoop();
    }

    /**
     * stop the music
     */
    public void stopped()
    {
        music.stop();
    }
    //Set up world
    /**
     * Sets values for variables used in the world, creates text and objects, on world start
     */
    public Level1()
    {
        super (600, 400, 1);
        prepare();
        addedToWorld();
        loseHealth(1);
        hpS= 3;
        damageE = 1;
        damageS = 1;
        hpE = 3;
        er1 = 1;
    }
    //Spawning
    /**
     * creates objects
     */
    private void prepare()
    {
        Ship ship = new Ship();
        addObject(ship, 75, 221);
        Section1 section1 = new Section1("Ufo.png",105,2);
        addObject(section1, 563, 215);
    }

    protected void addedToWorld()
    {
        myText = new Text("Enemy Health ", hpE, Font.PLAIN, 20);
        addObject(myText, 400, 50);
    }

    public void loseHealth(int amt)
    {
        hpE -= amt;
        if (hpE <= 0)
        {
            removeObject(myText);
        }
        myText.updateImage(hpE);
    }

    /**
     * Respawn Enemy at a random location after 250 cycles only if there is no enemys
     */
    private void respawn()
    {
        if (getObjects(Section1.class).size() !=1)
        {
            changeValue();
            hpt++; 
            if(hpt ==250)
            {
                addObject(new Section1("Ufo.png",105,2), 563,Greenfoot.getRandomNumber(325)+75);
                hpt =0;
                hpE = 3;
            }
        }
    }   
    //Losing
    /**
     * changes the world if you lose all your hp
     */
    private void changeWorlds()
    {
        Screen1 screen1= new Screen1();
        if ((hpS <= 0))
        {
            level1Complete = false;
            level= 0;
            stopped();
            Greenfoot.setWorld(screen1);
        }
    }
    //Alterations
    /**
     * if the enemy;s remaining is 0, return the player to the title screen, as well as adding in level 2 button
     */
    public void setFields()
    {
        Screen1 screen1 = new Screen1();
        if (er1 == 0)
        {
            level1Complete = true;
            level = 1;
            stopped();
            Greenfoot.setWorld(screen1);
        }
    }

    /**
     * vhanges Enemy hp and damage if the enemy hp reaches 0, then respawn
     */
    private void changeValue()
    {
        if (hpE <=0)
        {
            er1 = er1-1;
        }
    }
    //Commands
    /**
     * changes the World, displays text, Plays music, spawns in enemies, changes the enemy values
     * , counts up a timer, and adds a new button
     */
    public void act()
    {
        respawn();
        addedToWorld();
        loseHealth(1);
        spawnStars();
        started();
        changeWorlds();
        setFields();
    }
}
this is the enemies class code
import greenfoot.*;

/**
 * Write a description of class Enemies here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public abstract class Enemies extends Actor
{
    //Set Values
    //alters speed variable
    protected int speed;
    // sets a timer for zero, and sets a value for moving up and down
    protected int timer = 0, ydirection;
    //sets shooting rate
    protected int fireRate;
    ///Set up Object
    public Enemies()
    {

    }
    //Spawning
    /**
     * Alters Location in the world 
     **/
    public void AIMovement()
    {
        int y=getY();
        timer++;
        if (timer > 50 && Greenfoot.getRandomNumber(20)>=19 || ydirection==-1 && getY() < 50 || getY()>getWorld().getHeight()-10)
        {
            timer=0;
            ydirection *= -1;
        }

        if (y<=75)
        {
            setLocation (getX(), y+5);
        }
        setLocation(getX(),getY()+ydirection);
    }

    /**
     * Alters enemy health and existence of enemy in the world
     */
    public void Destroy()
    {
        Levels levels = (Levels)getWorld();
        if (levels.getHpE() ==0)
        {
            getWorld().removeObject(this);
        }
    }
}
section1 is just a subclass for movement and firing of multiple types of enemies
import greenfoot.*;

/**
 * Write a description of class Boss1 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Section1 extends Enemys
{
    private String eImage;
    //Constructor
    /**
     * changes the image when is created
     */
    public Section1(String enemyImage, int shotSpeed,int moveSpeed)
    {
        //Use abstracction for movement speed depending on the level
        eImage = enemyImage;
        setImage(enemyImage);
        fireRate = shotSpeed;
        speed = moveSpeed;
        ydirection = 0-speed;
        assignImage();
    }
    //Alterations
    /**
     * Alters the image size
     */
    private void assignImage()
    {
        //change the boss ships size
        if (eImage == "Boss1.png")
        {
            GreenfootImage image = getImage();
            image.scale(image.getWidth() +10, image.getHeight() +20);
        }
        if (eImage == "Ufo.png")
        {
            GreenfootImage image = getImage();
            image.scale(image.getWidth() +25, image.getHeight() +15);
        }
        if (eImage == "Miniboss1")
        {
            GreenfootImage image = getImage();
            image.scale(image.getWidth() +25, image.getHeight() +10);
        }
    }

    /**
     * spawns in EnemyLasers and plays shooting sound
     */
    public void fire()
    {
        if (Greenfoot.getRandomNumber(Math.abs(fireRate)+1) == 1)
        {
            if (eImage == "Ufo.png")
            {
                EnemyLaser EnemyLaser = new EnemyLaser("Ufo1_laser.png");
                getWorld().addObject(EnemyLaser, getX()-40, getY());
                Greenfoot.playSound("shot.wav");
            }
            else
            {
                EnemyLaser EnemyLaser = new EnemyLaser("Boss1_laser.png");
                getWorld().addObject(EnemyLaser, getX()-40, getY());
                Greenfoot.playSound("shot.wav");
            }
        }
    }

    //Commands
    /**
     * Shoot and move
     */
    public void act() 
    {
        fire();
        AIMovement();
    }    
}
here is my weapon class
import greenfoot.*;

/**
 * Write a description of class Boss1 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Section1 extends Enemies
{
    private String eImage;
    //Constructor
    /**
     * changes the image when is created
     */
    public Section1(String enemyImage, int shotSpeed,int moveSpeed)
    {
        //Use abstracction for movement speed depending on the level
        eImage = enemyImage;
        setImage(enemyImage);
        fireRate = shotSpeed;
        speed = moveSpeed;
        ydirection = 0-speed;
        assignImage();
    }
    //Alterations
    /**
     * Alters the image size
     */
    private void assignImage()
    {
        //change the boss ships size
        if (eImage == "Boss1.png")
        {
            GreenfootImage image = getImage();
            image.scale(image.getWidth() +10, image.getHeight() +20);
        }
        if (eImage == "Ufo.png")
        {
            GreenfootImage image = getImage();
            image.scale(image.getWidth() +25, image.getHeight() +15);
        }
        if (eImage == "Miniboss1")
        {
            GreenfootImage image = getImage();
            image.scale(image.getWidth() +25, image.getHeight() +10);
        }
    }

    /**
     * spawns in EnemyLasers and plays shooting sound
     */
    public void fire()
    {
        if (Greenfoot.getRandomNumber(Math.abs(fireRate)+1) == 1)
        {
            if (eImage == "Ufo.png")
            {
                EnemyLaser EnemyLaser = new EnemyLaser("Ufo1_laser.png");
                getWorld().addObject(EnemyLaser, getX()-40, getY());
                Greenfoot.playSound("shot.wav");
            }
            else
            {
                EnemyLaser EnemyLaser = new EnemyLaser("Boss1_laser.png");
                getWorld().addObject(EnemyLaser, getX()-40, getY());
                Greenfoot.playSound("shot.wav");
            }
        }
    }

    //Commands
    /**
     * Shoot and move
     */
    public void act() 
    {
        fire();
        AIMovement();
    }    
}
and finally the text class
import greenfoot.*;
import java.awt.Color;
import java.awt.Font;
/**
 * Write a description of class Text here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Text extends Decoration
{
    private String txt;
    private int sty;
    private int textsize;
    /**
     * Creates text of diffrient styles
     */
    public Text(String text, int style, int size)
    {
        int x = 1000;
        int y = 100;
        txt = text;
        sty= style;
        textsize = size;
        GreenfootImage img = new GreenfootImage(x,y);
        //img.setColor(Color.WHITE);
        //img.fill();
        img.setColor(Color.CYAN);
        img.setFont(new Font("OptimusPrinceps",sty ,textsize));
        img.drawString(text,(x/2),(y/4));
        setImage(img);	
    }

    private String pre;
    private int var, style, size;

    public Text(String pre, int var, int style, int size)
    {
        this.pre=pre; 
        this.style=style;
        this.size=size;
        updateImage(var);
    }

    public void updateImage(int var)
    {
        this.var = var;
        int x=1000, y=100;
        GreenfootImage img = new GreenfootImage(x, y);
        img.setColor(Color.CYAN);
        img.setFont(new Font("OptimusPrinceps", style, size));
        img.drawString(pre + var, x/2, y/4);
        setImage(img);
    }
}
sorry it's so long and lastly this is my first time programing a game at this scale (only began less than a year ago) so the structure may be off a bit i also might have found out what is causing the problem, but it ran fine before i changed the text (Was using showText method) when i inspect the world with level1 open i find that the hpE variable is declared twice. one as public int hpE. i this one is constantly counting down (guessing it's somewhere in level1) and the other as protected (hidden) int hpE this one is remaining the same value (somewhere in Levels class)
Super_Hippo Super_Hippo

2019/5/8

#
You call "loseHealth(1)" from the act method of Level 1 which reduces hpE by one every act cycle. But apparently your getter method is already doing that as well. (A getter method should only get the value without changing it so you can get it whenever you want.) It is really weird that you have the variables in your world class. Just imagine you have more than one Enemy, but one variable in the world class trying to make sure all enemies are acting correctly... For the two hpE variables. I can't see anything which could cause it from the code you posted. Maybe there is a duplicate in Screen1. You posted the Section1 class twice instead of your Weapon class. I am not sure why Section1 extends Enemy.
You need to login to post a reply.