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

2023/2/3

Code only execute on first instance

Makuro Makuro

2023/2/3

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class RedPlane here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class RedPlane extends Planes
{
    /**
     * Act - do whatever the RedPlane wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    private Background bg;
    public RedPlane(){
        SetAsset("enemy_plane_red.png");
        image.rotate(180);
        this.health = 50;bg = (Background) getWorld();
        this.attSpeed = 1.5f;
        
    }
    
    public void act()
    {
        bg = (Background) getWorld();
    
        elapsedTime = System.currentTimeMillis() - currentTime;
        Move(1);
        Death();
        if(elapsedTime > 3000/this.attSpeed){
            Spawn();
            elapsedTime = 0;
            currentTime = System.currentTimeMillis();
        }
    }
    private long currentTime = 0;
    private long elapsedTime = 0;
    
    private void Spawn () {
        // create the item
        Projectile_Red projectile = new Projectile_Red();
        
        // add the item to the world
        getWorld().addObject(projectile, getX(), getY()+30);
    }
    
    public void Death(){
        if(this.health <= 0){
            bg.GM.destroy--;
            getWorld().removeObject(this);
        }
    }
    @Override
    public void Move(int moveSpeed){
        setLocation(getX(), getY()+moveSpeed);
        if(isAtEdge()){
            //doesnt increase escaped variable 
            bg.GM.escaped++;
            //both debug works but produce equals number "1" even  if there is more than 1 instance that execute the 
            //code 
            System.out.println(bg.GM.escaped);
            System.out.println("tess");
            getWorld().removeObject(this);
        }
    }
   
    public void TakeDamage(int damage){
        this.health-=damage;
    }
}
So the code above especially the bg.GM.escaped++ part only works on the first instance of the class which is redPlane but if I add new instance which is redPlane2 and save the world then bg.GM.escaped++ wont work is there a reason for this behaviour?
danpost danpost

2023/2/3

#
Makuro wrote...
<< Code Omitted >> So the code above especially the bg.GM.escaped++ part only works on the first instance of the class which is redPlane but if I add new instance which is redPlane2 and save the world then bg.GM.escaped++ wont work is there a reason for this behaviour?
You will need to show your Background class codes. That will include the GM part (hopefully) and your field declaration lines. You scenario will not quite run consistently when using real time. Any lag (due to any background events on the computer) will alter the way the scenario works. Granted it will not usually make a big difference; but, it could end up spawning multiple objects at near the same place if the lag is substantial. For consistency, count act steps to control the spawning of the objects. Remove the
bg = (Background) getWorld();
from both lines 19 and 26 and add the following to the code:
@Override
protected void addedToWorld(World world)
{
    bg = (Background) world;
}
to avoid having to do this every act step. It will not work at all from line 19 to begin with as that line is executed before the object is placed into any world (being it is in the constructor).. Well, line 19 will execute, but the value will be set to null (which is was to begin with).
Makuro Makuro

2023/2/3

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;

/**
 * Write a description of class Game_Manager here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */

public class Game_Manager extends Actor
{
    public static boolean isGameOver=false;
    public static boolean isVictory = false;
    public boolean getEnemies = false;
    public static int escaped= 0;
    public static int destroy  ;
    public static int totalEnemies;
    public static boolean playerIsAlive = true;
    private List<Planes> planes;
    GreenfootImage img = null;
    
    /**
     * Constructor for objects of class GameManager
     */
    public Game_Manager()
    {
        playerIsAlive = true;
        Game_Manager gm = this;
        gm.setImage(img);
        System.out.println("in GM: "+this);
    }
    
    public void act(){
        System.out.println("in GM: "+escaped);
        if(getEnemies == false){
            planes = getWorld().getObjects(Planes.class);
            destroy = planes.size();  
            getEnemies = true;
        }
        if(escaped !=0){
            
            isGameOver = true;
        }
        
        if(destroy==1 && playerIsAlive){
            isVictory = true;
        }
        
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;

/**
 * Write a description of class Background here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Background extends World
{

    /**
     * Constructor for objects of class Background.
     * 
     */
    private static final String bgImageName1 = "Blue_Nebula_03.png";
    private Player player = new Player();
    private GreenfootImage bgImage1;
    public Game_Manager GM;
    private int enemiesNumbers;
      
    public Background()
    {    
        super(600, 750, 1); 
        prepare();
        
        System.out.println("BG: "+GM.playerIsAlive);
        System.out.println("BG: "+GM.escaped);
        bgImage1 = new GreenfootImage(bgImageName1);
        setBackground(bgImage1);
        GM = (Game_Manager) getObjects(Game_Manager.class).get(0);
        System.out.println(GM); 
    }
    
    public void act()
    {
        if(GM == null)
            System.out.println("tes");
        GM.escaped = 0;
        showText("Health: "+ String.valueOf(player.health),60,10);
        if(GM.isGameOver){
            showText("Game Over", 600/2, 750/2);
            GM.isGameOver = false;
            Greenfoot.stop();
            GM.destroy = GM.totalEnemies;
        }
        
        if(GM.isVictory){
            GM.isVictory = false;
            showText("Victory", 600/2, 750/2);
            Greenfoot.stop();
            GM.getEnemies = false;
            GM.destroy = GM.totalEnemies;
        }
    }
    
    private void prepare()
    {

        addObject(player,320,238);
        player.setLocation(291,369);
        GreenPlane greenPlane = new GreenPlane();
        addObject(greenPlane,288,120);
        RedPlane redPlane = new RedPlane();
        addObject(redPlane,456,117);
        WhitePlane whitePlane = new WhitePlane();
        addObject(whitePlane,134,103);
        greenPlane.setLocation(285,108);
        greenPlane.setLocation(287,27);
        redPlane.setLocation(456,39);
        whitePlane.setLocation(123,33);
        player.setLocation(266,649);
        player.setLocation(270,700);
        Game_Manager game_Manager = new Game_Manager();
        addObject(game_Manager,200,456);
        RedPlane redPlane7 = new RedPlane();
        addObject(redPlane7,400,608);
    }
}
Thanks for your reply and here are the Game Manager and Background class respectively
danpost danpost

2023/2/4

#
Makuro wrote...
<< Codes Omitted >> Thanks for your reply and here are the Game Manager and Background class respectively
I really do not see the need of the Game_Manager class. All the information stored in fields there can be determined on the fly, with fair programming. A Game_Over class extending Actor could be used to show victory or failure and at the same time be used to stop the scenario when added into the world with (in Game_Over class):
protected void addedToWorld(World world)
{
    Greenfoot.stop();
}
Instead of setting fields and acting on their values later, best is to do what needs to be done immediately. That is, the entire Background class act method can be dismissed. When one escapes, do not set a value in a field; just, create the appropriate game over actor and add it into the world immediately; when player kills an enemy and no enemies remain, create a game over actor and add it into the world; etc.
You need to login to post a reply.