Creating new levels

Viewed 127

As a beginner in Java, I'm working on a project of Space Invaders. Looking to add more levels.

private void LevelInit() {
    aliens = new ArrayList<>();
    int currentLevel = 1;

        if (currentLevel == 1) {
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 4; j++) {

                    var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
                    aliens.add(alien);
                    //System.out.println(currentLevel);


                }

            }
        }
        else if (currentLevel == 2) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {

                    var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
                    aliens.add(alien);

                   // System.out.println(currentLevel);


                }
            }
        }
        else if (currentLevel == 3) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 6; j++) {

                    var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
                    aliens.add(alien);
                    //System.out.println(currentLevel);
                }

            }
        }
        




    player = new Player();
    bullet = new Bullet();


}

This function is the logic behind the code that initializes the game and gets called by the constructor. The simple way of adding levels is adding more Aliens. This is how it looks after being updated from yesterday, levels are being added but the arraylists are being stuck together. Like the 12 - 16 - 24 aliens are together printed, some spaceships take 1 hit some 2 and some 3 and when they are all destroyed system give message of You passed level 1 and 2 and 3 together which is confusing me why are they bound together like that and not being passed. And I can't figure it out. Also,

    private void update() {

    if (deaths == 12) {

            inGame = false;
            timer.stop();
            message = "Next Level!";

    }
    // player
    player.act();

    // shot
    if (bullet.isVisible()) {

        int shotX = bullet.getX();
        int shotY = bullet.getY();

        for (Alien alien : aliens) {

            int alienX = alien.getX();
            int alienY = alien.getY();

            if (alien.isVisible() && bullet.isVisible()) {
                if (shotX >= (alienX)
                        && shotX <= (alienX + Constants.ALIEN_WIDTH)
                        && shotY >= (alienY)
                        && shotY <= (alienY + Constants.ALIEN_HEIGHT)) {

                    var ii = new ImageIcon(explImg);
                    alien.setImage(ii.getImage());
                    alien.setDying(true);
                    deaths++;
                    bullet.die();
                }
            }
        }

        int y = bullet.getY();
        y -= 4;

        if (y < 0) {
            bullet.die();
        } else {
            bullet.setY(y);
        }
    }

    // aliens

    for (Alien alien : aliens) {

        int x = alien.getX();

        if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {

            direction = -1;

            for(Alien a2 : aliens) {
                a2.setY(a2.getY() + Constants.GO_DOWN);
            }
        }

        if (x <= Constants.BORDER_LEFT && direction != 1) {

            direction = 1;


            for(Alien a : aliens) {

                a.setY(a.getY() + Constants.GO_DOWN);
            }
        }
    }



    for(Alien alien : aliens) {


        if (alien.isVisible()) {

            int y = alien.getY();

            if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
                inGame = false;
                message = "Invasion!";
            }

            alien.act(direction);
        }
    }

    // bombs
    var generator = new Random();

    for (Alien alien : aliens) {

        int shot = generator.nextInt(15);
        Alien.Bomb bomb = alien.getBomb();

        if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {

            bomb.setDestroyed(false);
            bomb.setX(alien.getX());
            bomb.setY(alien.getY());
        }

        int bombX = bomb.getX();
        int bombY = bomb.getY();
        int playerX = player.getX();
        int playerY = player.getY();

        if (player.isVisible() && !bomb.isDestroyed()) {

            if (bombX >= (playerX)
                    && bombX <= (playerX + Constants.PLAYER_WIDTH)
                    && bombY >= (playerY)
                    && bombY <= (playerY + Constants.PLAYER_HEIGHT)) {

                var ii = new ImageIcon(explImg);
                player.setImage(ii.getImage());
                player.setDying(true);
                bomb.setDestroyed(true);
            }
        }

        if (!bomb.isDestroyed()) {

            bomb.setY(bomb.getY() + 1);

            if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {

                bomb.setDestroyed(true);
            }
        }
    }
}

This function is to update the game whenever anything happens. The code is made from a bunch of YouTube videos and GitHubs, so excuse the copying if you see any. I need to create new levels by simply adding more aliens, tried using a for loop but that resulted in either the aliens move faster or the bullet doesn't destroy an alien, it just hits.

Board class:

public class Board extends JPanel {

private Dimension d;
private List<Alien> aliens;
private Player player;
private Bullet bullet;
private int level;
private int direction = -1;
private int deaths = 0;

private boolean inGame = true;
private String explImg = "src/images/explosion.png";
private String message = "Game Over";

private Timer timer;


public Board() {


    initBoard();
    gameInit();
    LevelInit();


}

private void initBoard() {

    addKeyListener(new TAdapter());
    setFocusable(true);
    d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
    setBackground(Color.black);

    timer = new Timer(Constants.DELAY, new GameCycle());
    timer.start();

    gameInit();

}


private void gameInit() {

    aliens = new ArrayList<>();


    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {

            var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j,
                    Constants.ALIEN_INIT_Y + 18 * i);
            aliens.add(alien);

        }
    }


    player = new Player();
    bullet = new Bullet();

}
private void LevelInit() {


    inGame = true;
    timer.start();
    int level = 1;
    if (aliens.isEmpty()) {
        level++;
        int AlienCount;if(level == 2) {
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 6; j++) {
                    var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
                    aliens.add(alien);

                }
            }
        } else if (level == 3) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 6; j++) {
                    var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
                    aliens.add(alien);
                    
                }
            }
        }
    }
    player = new Player();
    bullet = new Bullet();
}





private void drawAliens(Graphics g) {

    for (Alien alien : aliens) {

        if (alien.isVisible()) {

            g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this);
        }

        if (alien.isDying()) {

            alien.die();
        }
    }
}

private void drawPlayer(Graphics g) {

    if (player.isVisible()) {

        g.drawImage(player.getImage(), player.getX(), player.getY(), this);
    }

    if (player.isDying()) {

        player.die();
        inGame = false;
    }
}

private void drawShot(Graphics g) {

    if (bullet.isVisible()) {

        g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
    }
}

private void drawBombing(Graphics g) {

    for (Alien a : aliens) {

        Alien.Bomb b = a.getBomb();

        if (!b.isDestroyed()) {

            g.drawImage(b.getImage(), b.getX(), b.getY(), this);
        }
    }
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    doDrawing(g);
}

private void doDrawing(Graphics g) {

    g.setColor(Color.black);
    g.fillRect(0, 0, d.width, d.height);
    g.setColor(Color.green);

    if (inGame) {

        g.drawLine(0, Constants.GROUND,
                Constants.BOARD_WIDTH, Constants.GROUND);

        drawAliens(g);
        drawPlayer(g);
        drawShot(g);
        drawBombing(g);

    } else {

        if (timer.isRunning()) {
            timer.stop();
        }

        gameOver(g);
    }

    Toolkit.getDefaultToolkit().sync();
}

private void gameOver(Graphics g) {

    g.setColor(Color.black);
    g.fillRect(0, 0, Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);

    g.setColor(new Color(0, 32, 48));
    g.fillRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
    g.setColor(Color.white);
    g.drawRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);

    var small = new Font("Helvetica", Font.BOLD, 14);
    var fontMetrics = this.getFontMetrics(small);

    g.setColor(Color.white);
    g.setFont(small);
    g.drawString(message, (Constants.BOARD_WIDTH - fontMetrics.stringWidth(message)) / 2,
            Constants.BOARD_WIDTH / 2);
}

private void update() {

    if (deaths == aliens.size()) {

            inGame = false;
            timer.stop();
            message = "Next Level!";


    }
    // player
    player.act();

    // shot
    if (bullet.isVisible()) {

        int shotX = bullet.getX();
        int shotY = bullet.getY();

        for (Alien alien : aliens) {

            int alienX = alien.getX();
            int alienY = alien.getY();

            if (alien.isVisible() && bullet.isVisible()) {
                if (shotX >= (alienX)
                        && shotX <= (alienX + Constants.ALIEN_WIDTH)
                        && shotY >= (alienY)
                        && shotY <= (alienY + Constants.ALIEN_HEIGHT)) {

                    var ii = new ImageIcon(explImg);
                    alien.setImage(ii.getImage());
                    alien.setDying(true);
                    deaths++;
                    bullet.die();
                }
            }
        }

        int y = bullet.getY();
        y -= 4;

        if (y < 0) {
            bullet.die();
        } else {
            bullet.setY(y);
        }
    }

    // aliens

    for (Alien alien : aliens) {

        int x = alien.getX();

        if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {

            direction = -1;

            Iterator<Alien> i1 = aliens.iterator();

            while (i1.hasNext()) {

                Alien a2 = i1.next();
                a2.setY(a2.getY() + Constants.GO_DOWN);
            }
        }

        if (x <= Constants.BORDER_LEFT && direction != 1) {

            direction = 1;

            Iterator<Alien> i2 = aliens.iterator();

            while (i2.hasNext()) {

                Alien a = i2.next();
                a.setY(a.getY() + Constants.GO_DOWN);
            }
        }
    }

    Iterator<Alien> it = aliens.iterator();

    while (it.hasNext()) {

        Alien alien = it.next();

        if (alien.isVisible()) {

            int y = alien.getY();

            if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
                inGame = false;
                message = "Invasion!";
            }

            alien.act(direction);
        }
    }

    // bombs
    var generator = new Random();

    for (Alien alien : aliens) {

        int shot = generator.nextInt(15);
        Alien.Bomb bomb = alien.getBomb();

        if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {

            bomb.setDestroyed(false);
            bomb.setX(alien.getX());
            bomb.setY(alien.getY());
        }

        int bombX = bomb.getX();
        int bombY = bomb.getY();
        int playerX = player.getX();
        int playerY = player.getY();

        if (player.isVisible() && !bomb.isDestroyed()) {

            if (bombX >= (playerX)
                    && bombX <= (playerX + Constants.PLAYER_WIDTH)
                    && bombY >= (playerY)
                    && bombY <= (playerY + Constants.PLAYER_HEIGHT)) {

                var ii = new ImageIcon(explImg);
                player.setImage(ii.getImage());
                player.setDying(true);
                bomb.setDestroyed(true);
            }
        }

        if (!bomb.isDestroyed()) {

            bomb.setY(bomb.getY() + 1);

            if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {

                bomb.setDestroyed(true);
            }
        }
    }
}

private void doGameCycle() {

    update();
    repaint();
}

private class GameCycle implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {

        doGameCycle();
    }
}

private class TAdapter extends KeyAdapter {

    @Override
    public void keyReleased(KeyEvent e) {

        player.keyReleased(e);
    }

    @Override
    public void keyPressed(KeyEvent e) {

        player.keyPressed(e);

        int x = player.getX();
        int y = player.getY();

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_SPACE) {

            if (inGame) {

                if (!bullet.isVisible()) {

                    bullet = new Bullet(x, y);
                }
            }
        }
    }
}

}

1 Answers

As @JoachimSauer mentioned, your code needs refactoring. Here is one possible solution to your problem.


Additions

You will need two extra variables and one extra method.

  • Variables

    1: int currentLevel - keeps track of the current level
    2: boolean isLevelOver - keeps track if the current level is still active or not
    
  • Method

    private void levelInit(int currentlevel)
    {
        aliens = new ArrayList<>();
        int alienCount = //calculate alien count depending upon the current level
    
        //Add aliens to aliens ArrayList
    
        player = new Player();
        bullet = new Bullet();
    }
    

You have to provide implementation of how alienCount will be calculated depending upon currentLevel. The nested loop you used earlier to add aliens to aliens will also change. You have to make the loop dependent upon currentLevel.


Changes

Few of your methods will require some change.

public Board() 
{
    initBoard();
}

private void initBoard()
{
    addKeyListener(new TAdapter());
    setFocusable(true);
    d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
    setBackground(Color.black);

    levelInit(currentLevel);

    timer = new Timer(Constants.DELAY, new GameCycle());
    timer.start();
}

private void update() 
{
    if (deaths == aliens.size()) 
    {
        isLevelOver = true;
        currentLevel++;
        message = "Next Level!";
        return;
    }

    ...
}

private void doGameCycle() 
{
    if (isLevelOver)
    {
        levelInit(currentLevel);
        isLevelOver = false;
    }
    
    update();
    repaint();
}

Notes

  • This is one of the possible ways to achieve what you want. There might be other ways, probably better, but this is what I came up with.
  • I tried to find as many additions and updation required in your code. However, I do not know its structure, you do. So there might be more additions or changes required.
  • I noticed you are were calling gameInit() in initBoard() and then again in Board() constructor. I think that might be unnecessary, please look into it.
  • You made one call to timer.stop() after setting isGame = false. This again might be unnecessary since you are already doing so inside doDrawing(...). Please also check that.
  • You should probably set a limit to either the levelCount() or max alien that can be on the screen since if you just keep on adding more aliens in each new level, they might fill up the entire screen.

I have provided many hints which should help you in your problem. If you still face any more problems or someone finds anything wrong with the answer, please comment.

Related