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

2022/2/10

I need help with my game. It doesn't set the current state to the new state. It allows the user to keep pressing "y"

Cole Cole

2022/2/10

#
public class MyWorld extends World
{
    private final int START = 0;
    private final int PLAYING1 = 1;
    private final int PLAYING2 = 2;
    private final int SUSPENDED = 3;
    private final int WIN = 4;
    private final int LOSE = 5;
    private int SPAWN_TIMER = 0;
    private int SPAWN_TIMER2 = 0;
    private int SPAWN_TIME_LIMIT = 65;
    private int SPAWN_TIME_LIMIT2 = 80;
    private int ENEMY_COUNTER = 0;
    private int ENEMY_COUNTER2 = 0;
    private int ENEMY_Y = 300;
    private Counter theCounter;
    private Counter theCounter2;
    
    private int curState;
    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public MyWorld()
    {    
        // Create a new world with 900x600 cells with a cell size of 1x1 pixels.
        super(900, 600, 1);
        theCounter = new Counter();
        curState = START;
        this.setBackground("start.jpg");
    }
    public void act() {
        
        // This starts the game whenever the player is ready
        if (curState == START && Greenfoot.isKeyDown("y") || Greenfoot.isKeyDown("Y"))
        {
            curState = PLAYING1;
            this.setBackground("PLAYING1.png");
            initializeLevel1();
        }
        
        // This spawns enemies at a certain rate
        if (curState == PLAYING1 && ENEMY_COUNTER < 15) {
            if (SPAWN_TIMER == SPAWN_TIME_LIMIT){
                spawnEnemy1();
                SPAWN_TIMER = 0;
                ENEMY_COUNTER ++;
            }
            else { 
                SPAWN_TIMER ++;
            }
        }
        
        // This sets the game to a suspended level when the player
        // finishes level 1
        
        if(curState == PLAYING1 && theCounter.getValue() == 15)
        {
            curState = SUSPENDED;
            removeLevel1Objs();
            this.setBackground("splash2.png");
        }
        
        if (curState == SUSPENDED && (Greenfoot.isKeyDown("y") || Greenfoot.isKeyDown("Y")))
        {
            initializeLevel2();
            this.setBackground("level2.png");
            curState = PLAYING2;
        }
        
        if (curState == PLAYING2 && ENEMY_COUNTER2 < 4) 
        {
            if (SPAWN_TIMER == SPAWN_TIME_LIMIT2){
                spawnEnemy2();
                SPAWN_TIMER = 0;
                ENEMY_COUNTER2 ++;
            }
            else { 
                SPAWN_TIMER ++;
            }
        }
        
        if(curState == PLAYING2 && theCounter.getValue() == 19)
        {
            curState = WIN;
            removeLevel2Objs();
            this.setBackground("win.png");
        }
        
    }
    // utility methods
    private void initializeLevel1() 
    {
        this.addObject(new Player(),100,300);
        this.addObject(new Computer(), 700,300);
    }
    
    private void initializeLevel2()
    {
       this.addObject(new Player(), 100, 300);
       this.addObject(new Rock(), 450, 100);
       this.addObject(new Rock(), 450, 500);
    }
    
    private void removeLevel1Objs()
    {
        List<Computer> myCList = this.getObjects(Computer.class);
        List<Player> myPList = this.getObjects(Player.class);
        for(Computer curComp : myCList) {
            this.removeObject(curComp);
            }
        for(Player curComp : myPList) {
            this.removeObject(curComp);
        }
        
    }
    
    private void removeLevel2Objs()
    {
        List<Computer2> myC2List = this.getObjects(Computer2.class);
        List<Player> myPList = this.getObjects(Player.class);
        List<Rock> myRList = this.getObjects(Rock.class);
        for(Computer2 curComp : myC2List) {
            this.removeObject(curComp);
            }
        for(Player curComp : myPList) {
            this.removeObject(curComp);
        }
        for(Rock curComp : myRList) {
            this.removeObject(curComp);
        }
        
    }
    
    // Method used to spawn enemies in the world
    private void spawnEnemy1() 
    {
        this.addObject(new Computer(),700,Greenfoot.getRandomNumber(ENEMY_Y));
    }
    
    public void spawnEnemy2()
    {
        this.addObject(new Computer2(), 700, Greenfoot.getRandomNumber(ENEMY_Y));
    }
    public Counter getCounter()
    {
        return theCounter;
    }
}
Super_Hippo Super_Hippo

2022/2/10

#
Line 35 seems to be missing a pair of braces:
if (curState == START && Greenfoot.isKeyDown("y") || Greenfoot.isKeyDown("Y"))
Compare it to line 64:
if (curState == SUSPENDED && (Greenfoot.isKeyDown("y") || Greenfoot.isKeyDown("Y")))
Cole Cole

2022/2/10

#
Wow...can't believe I missed that. That seems to have fixed it. Any idea on how I can implement a "lose" screen if the player is shot?
Super_Hippo Super_Hippo

2022/2/10

#
You can either change to a new world which has the lose screen as the background or add an actor to the world which has the lose screen as its image.
danpost danpost

2022/2/10

#
The use of "this." seems a bit ... off. Each usage is on a method that is located in the World class, which is the "super" of this class. More appropriate would be to use "super." instead. However. the methods are not over-shadowed by methods with the same names in the MyWorld class, so ... that is why it still works. Greenfoot does not force the use of a subject for method calls. As such, I suggest just dropping all the "this."s from the class. Next, you can remove all objects from the world in one simple call by using "Actor..class" instead of calling out all the different types of actors. As far as field names, only the "final" ones should be in all caps (by convention). To help reduce the number of fields, the timer limit field can be adjusted per level and the timer itself can be re-used. Same goes for the enemy counter. Also, it seems the Counter theCounter2 is not used at all. The use of isKeyDown may be not quite what you want here. Better might be to use the getKey function. With the above in mind, it might look like this:
import greenfoot.*;

public class MyWorld extends World
{
    private final int START = 0;
    private final int PLAYING1 = 1;
    private final int PLAYING2 = 2;
    private final int SUSPENDED = 3;
    private final int WIN = 4;
    private final int LOSE = 5;
    private final int ENEMY_Y = 300;
    
    private int timer;
    private int timerLimit;
    private int enemyCount;
    private int currState;
    private Counter theCounter;
    
    public MyWorld()
    {
        super(900, 600, 1);
        setBackground("start.jpg");
        theCounter = new Counter();
    }
    
    public void act()
    {
        if (currState == WIN || currState == LOSE) return;
        if (currState == START || currState == SUSPENDED)
        {
            transitioning();
            return;
        }
        spawnEmeny();
        if (currState == PLAYING1 && theCounter.getValue() == 15) suspend();
        if (currState == PLAYING2 && theCounter.getValue() == 19) win();
    }
    
    private void win()
    {
        removeObjects(getObjects(Actor.class));
        currState = WIN;
        setBackground("win.png");
    }
    
    private void suspend()
    {
        removeObjects(getObjects(Actor.class));
        currState = SUSPENDED;
        setBackground("splash2.png");
    }
    
    private void spawnEnemy()
    {
        timer = (timer+1)%timerLimit;
        if (timer != 0) return;
        if (currState == PLAYING1) addObject(new Computer(), 700, ENEMY_Y);
        else if (currState == PLAYING2) addObject(new Computer2(), 700, ENEMY_Y);
        enemyCount++;
    }
    
    private void transitioning()
    {
        String key = Greenfoot.getKey();
        if (key == null || !"y".equals(key.toLowerCase())) return;
        if (currState == START) initializeLevel1();
        else if (currState == SUSPENDED) initializeLevel2();
    }
    
    private void initializeLevel1()
    {
        currState = PLAYING1;
        setBackground("PLAYING1.png");
        timerLimit = 65;
        addObject(new Player(), 100, 300);
        addObject(new Computer(), 700, ENEMY_Y);
    }
    
    private void initializeLevel2()
    {
        currState = PLAYING2;
        setBackground("level2.png");
        timerLimit = 80;
        enemyCount = 0;
        addObject(new Player(), 100, 300);
        addObject(new Rock(), 450, 100);
        addObject(new Rock(), 450, 500);
    }
}
You need to login to post a reply.