How to manage multiple enemy spawning patterns in a 2D shooter game

I’m working on a 2D shooting game and currently have just one enemy that follows the player around. What I want to achieve is spawning groups of enemies at regular intervals - maybe 5 to 10 enemies every 10 seconds or so.

List<Monster> monsters = new ArrayList<Monster>();

for (Monster m : monsters) {
    m.render(graphics);
}

Is using an ArrayList the right approach for handling multiple enemies? Also, I need help with positioning strategies. I don’t want all enemies appearing in the same spot. My idea is to have the first wave spawn from the top edge, then the next group comes from the left side, and so on.

I’m also struggling with where exactly to populate this list. I tried something like:

monsters.add(new Monster(400, 50));

But it’s not working as expected. What’s the best way to handle enemy spawning and movement patterns for this type of game?

Had this exact problem building my tower defense game. ArrayList works great for enemies - the real issue is spawn timing that doesn’t depend on framerate. You’re probably adding enemies every frame instead of using controlled intervals. Game state timer saved my butt here. Don’t count frames - track elapsed game time and manage waves separately from your render loop. For positioning, skip fixed spawn points and use spawn zones instead. You get way more natural enemy distribution that way. Create rectangular areas just outside screen bounds rather than spawning right at edges. Stops enemies from looking too predictable. Here’s what the other answers missed: enemy cleanup. Remove dead or off-screen enemies from your ArrayList or you’ll hit memory problems in longer sessions. Learned this when my game started chugging after wave 15.

ArrayList works fine for enemies, but you need a decent spawning system. I built something like this last year - here’s what worked.

Make a spawn manager class that handles timing and spawn points:

class SpawnManager {
    private long lastSpawnTime = 0;
    private int currentWave = 0;
    private Point[] spawnPoints = {
        new Point(width/2, 0),     // top
        new Point(0, height/2),    // left  
        new Point(width, height/2), // right
        new Point(width/2, height)  // bottom
    };
    
    public void update(List<Monster> monsters) {
        if (System.currentTimeMillis() - lastSpawnTime > 10000) {
            spawnWave(monsters);
            lastSpawnTime = System.currentTimeMillis();
        }
    }
    
    private void spawnWave(List<Monster> monsters) {
        Point spawn = spawnPoints[currentWave % 4];
        for (int i = 0; i < 7; i++) {
            int offsetX = (int)(Math.random() * 100 - 50);
            int offsetY = (int)(Math.random() * 100 - 50);
            monsters.add(new Monster(spawn.x + offsetX, spawn.y + offsetY));
        }
        currentWave++;
    }
}

Just call spawnManager.update(monsters) in your main game loop. The random offset stops enemies from stacking on top of each other.

For movement, give each enemy a behavior type when you spawn it. Some chase the player, others move in straight lines or circles.

Your ArrayList approach works fine, but you need better spawn timing and positioning. I hit the same issues building my side-scrolling shooter. The problem with monsters.add(new Monster(400, 50)) is you’re probably spawning enemies non-stop instead of controlling when they appear. You need a timer system. Here’s what worked for me: java int frameCount = 0; int enemiesPerWave = 6; public void gameLoop() { frameCount++; if (frameCount % 600 == 0) { // Every 10 seconds at 60 FPS spawnEnemyWave(); } } private void spawnEnemyWave() { int side = (frameCount / 600) % 4; // Rotate spawn sides for (int i = 0; i < enemiesPerWave; i++) { int x = getSpawnX(side, i); int y = getSpawnY(side, i); monsters.add(new Monster(x, y)); } } For positioning, spread enemies along the edge instead of random offsets. Creates better formations and stops them from clustering together.