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

2020/4/18

Why is is not returning time

DaRafster DaRafster

2020/4/18

#
So I have a timer class which holds multiple timers, and I would like to access those timers through the world-class. I have created methods that would return the timers in the timer class, I tried to access them in the world-class (no errors) in order to get my game going. However the timers are " not working " in the world-class but the timers have no problem decrementing and so forth. The problem I'm guessing it that I am not accessing the method correctly within the timer class, but I'll let you guys be the judge of that. Here is my world-class code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Galaxy here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Galaxy extends World
{
    private GreenfootImage title = new GreenfootImage("Space Rush.png");
    private GreenfootImage bg = getBackground();
    private Score theScore;
    private Timer theTimer; 
    private Asteroid theAsteroid;
    private int asteroidCounter, speedCounter, healthCounter = 0;

    public Galaxy()
    {    
        super(1000, 900, 1); 
        prepare();
        theTimer = new Timer();
        theAsteroid = new Asteroid();
    }

    private void prepare()
    {
        Picture logo = new Picture(title,2,2);
        addObject(logo, getWidth()/2, getHeight()/10); 

        addObject(new Timer(), getWidth()/2 - getWidth()/3, getHeight()/15);

        Spacecraft spacecraft = new Spacecraft();
        addObject(spacecraft,getWidth()/5,getHeight()/2);

        theScore = new Score();
        addObject(theScore, getWidth()/2 + getWidth()/3, getHeight()/15);

        HealthBar healthBar = new HealthBar(300, 20, spacecraft);
        addObject(healthBar, getWidth()/2, getHeight() - getHeight()/22);

        bg.setColor(Color.WHITE);
        bg.drawRect(0, 115, getWidth(), 15);
        bg.drawRect(0, 800, getWidth(), 15);
        bg.setColor(new Color(83, 64, 34));    
        bg.fillRect(0, 116, getWidth(), 14);
        bg.fillRect(0, 801, getWidth(), 14);
    }

    public void scoreOverTime()
    {
        if(theTimer.getTimeLeft() > 0 && theTimer.getInitialCount() <= 0)
        {
            theScore.addScore(1);
        }
    }

    public Score getScore()
    {
        return theScore;
    }

    /*
     * Adds asteroids into the world, controlling the randomization 
     * and delay between asteroids spawned
     */ 
    public void addingAsteroid()
    {
        asteroidCounter++; 
        if(Greenfoot.getRandomNumber(30) < 1 && asteroidCounter > 10 )
        {
            addObject(new Asteroid(), getWidth(), getRandomNumber(160, 760));
            asteroidCounter = 0;
        }
    }

    /*
     * Adds speed boosts into the world, controlling the randomization
     * and delay between speed boosts spawned
     */
    public void addingSpeedPowerup()
    {
        speedCounter++;
        if(Greenfoot.getRandomNumber(500) < 1 && speedCounter > 350)
        {
            addObject(new Speed(), getWidth(), getRandomNumber(160, 760));
            speedCounter = 0;
        }
    }

    public void addingHealthPowerup()
    {
        healthCounter++;
        if(Greenfoot.getRandomNumber(300) < 1 && healthCounter > 500)
        {
            addObject(new Health(), getWidth(), getRandomNumber(160, 760));
            healthCounter = 0;
        }
    }

    public int getRandomNumber(int start,int end)
    {
        int normal = Greenfoot.getRandomNumber(end-start+1);
        return normal+start;
    }

    public void act()
    {

        if(theTimer.getInitialCount() <= 0)
        {
            if(theTimer.getTimeLeft() > 0)
            {
                addingAsteroid();
                addingSpeedPowerup();
                addingHealthPowerup();
                if(theTimer.getDelayLvl2() <= 0)
                {
                    NextGalaxy Lvl2 = new NextGalaxy();
                    Greenfoot.setWorld(Lvl2);
                }
            }
        }
        scoreOverTime();
    }   
}
and here is my timer class code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Timer here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Timer extends UI
{
    public int initialCount = 660;
    public int timeLeft = 3660;
    public int delayLvl2 = 400;

    public int getInitialCount()
    {
        return initialCount/60; 
        // Converts into real-like time
    }

    public int getTimeLeft()
    {
        return timeLeft/60;
    }
    
    public int getDelayLvl2()
    {
        return delayLvl2/60;
    }

    public void displayTimers()
    {
        initialCount--; 
        setImage(new GreenfootImage("GAME STARTS IN: " + getInitialCount(), 25, Color.WHITE, new Color(0,0,0,0)));
        if(initialCount <= 0)
        {
            timeLeft--;
            if (getTimeLeft() == 60)
            {
                setImage(new GreenfootImage("TIME REMAINING: 1:00", 25, Color.WHITE, new Color(0,0,0,0)));
            }
            else if(getTimeLeft() < 60)
            {
                displayTimeLeft();
            }

            if(getTimeLeft() <= 0)
            {
                nextLvlMsg();
                if(getTimeLeft() <= -5)
                {
                    delayLvl2--;
                    nextLvlTime();
                }
            }
        }
    }

    public void displayTimeLeft()
    {
        setImage(new GreenfootImage("TIME REMAINING: " + getTimeLeft(), 25, Color.WHITE, new Color(0,0,0,0)));
    }

    public void nextLvlTime()
    {
        setImage(new GreenfootImage("LEVEL 2 BEGINS IN: " + getDelayLvl2(), 25, Color.WHITE, new Color(0,0,0,0)));
    }

    public void nextLvlMsg()
    {
        setImage(new GreenfootImage("Level Complete!", 25, Color.WHITE, new Color(0,0,0,0)));
    }

    public void act() 
    {
        displayTimers();
    }
}
So am I referencing the timer class incorrectly? I'm not sure I fully understand accessing methods or variables from other classes still, I've already viewed the tutorial that people have been directed to multiple times but for some reason I still have trouble.
Super_Hippo Super_Hippo

2020/4/18

#
The problem is this line:
addObject(new Timer(), getWidth()/2 - getWidth()/3, getHeight()/15);
You are not adding ‘theTimer’ to the world here, but a new one. You should add ‘theTimer’. But even that won’t work because for some reason, you have
theTimer = new Timer();
after the prepare method. So you can remove line 22 and use this to add the timer:
theTimer = new Timer();
addObject(theTimer, getWidth()/2 - getWidth()/3, getHeight()/15);
Otherwise, the timer displayed in your world is not the timer in the ‘theTimer’ variable on which you call methods.
RcCookie RcCookie

2020/4/18

#
It looks like you don’t actually add the timer instance to the world, meaning you have a reference but it is not displayed. This means (probably, I’m not 100% sure), that the act method of the counter isn’t executed. You can solve this two ways: either add the timer to the world via addObject or call the act method manually. What you could also do is make the displayTimers-method be called by the returning methods.
DaRafster DaRafster

2020/4/18

#
Super_Hippo wrote...
The problem is this line:
addObject(new Timer(), getWidth()/2 - getWidth()/3, getHeight()/15);
You are not adding ‘theTimer’ to the world here, but a new one. You should add ‘theTimer’. But even that won’t work because for some reason, you have
theTimer = new Timer();
after the prepare method. So you can remove line 22 and use this to add the timer:
theTimer = new Timer();
addObject(theTimer, getWidth()/2 - getWidth()/3, getHeight()/15);
Otherwise, the timer displayed in your world is not the timer in the ‘theTimer’ variable on which you call methods.
You saved me! I've looked over this multiple times but I never realized that was the problem. I will make sure this doesn't happen again!
RcCookie wrote...
It looks like you don’t actually add the timer instance to the world, meaning you have a reference but it is not displayed. This means (probably, I’m not 100% sure), that the act method of the counter isn’t executed. You can solve this two ways: either add the timer to the world via addObject or call the act method manually. What you could also do is make the displayTimers-method be called by the returning methods.
Also thanks RcCookie for trying to help, I appreciate it.
DaRafster DaRafster

2020/4/18

#
It looks like I ran into the problem again.... but in the actor class. I've reviewed this discussion multiple times, but couldn't pinpoint the problem. I double-checked by creating a return statement in the actor class and the timer class is not decrementing its timers. So my code is set up, but the timer is not decrementing. A little different from the problem I ran into previously, since before the timer decrementing wasn't the problem. Been looking at this for quite a while, and I don't think I can figure this out myself. It's probably very simple and I'm overlooking it. Here is the actor class code I'm having trouble with:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class EnemySpacecraft here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class EnemySpacecraft extends Actor
{
    private Timer theTimer;
    private int health, maxHealth, damage;
    private int speed = 5;
    public EnemySpacecraft()
    {
        GreenfootImage img = getImage();
        img.scale(img.getWidth()/6,img.getHeight()/6);
        setImage(img);  
        setRotation(270); 
        
        theTimer = new Timer();
    }
    
    public void randomShooting()
    {
        
        if(theTimer.getInitialCount() <= 0)
        {
            if(Greenfoot.getRandomNumber(50) < 1) 
            {
                getWorld().addObject(new Sphere(5), getX() - 50, getY());
            }
        }
    }
    
    public int returnTime()
    {
        return theTimer.getInitialCount();
    }
    
    public void act() 
    {
        randomShooting();
    }    
}
danpost danpost

2020/4/18

#
In your EnemySpacecraft class, line 21 creates a new Timer object, but now you have 2 different Timer objects -- one created here and one created in your Galaxy class.
DaRafster DaRafster

2020/4/19

#
The world that the enemySpacecraft actor is in is a world subclass of Galaxy. So would this still be the same thing? Would I have to access the timer from the original world?
danpost danpost

2020/4/19

#
DaRafster wrote...
The world that the enemySpacecraft actor is in is a world subclass of Galaxy. So would this still be the same thing? Would I have to access the timer from the original world?
That was little confusing -- as what would be the "original world". At any rate, let me explain this way. When you extend a class, what you are doing is creating a union of classes to describe the same type object as the class being extended creates. The extending class can add new possible states (fields) for the object or add, modify and/or remove behaviors that the object can do (by adding or overriding methods). When you create an instance of the extending class, you ARE creating an instance of the class it extends. This one in the same instance has properties of both classes. Inheritance is a one way street in that an object created from the extended class will not have properties described by any class extending it (at least, not due to them being described there). As far as using the new word, any time it is used, a NEW, never before used, object is being created. Go back and read that last sentence carefully. Try to understand what that means.
You need to login to post a reply.