Shmup: Variable fire rate (Touhou/Danmaku-style)

Godot 4.3

Im a new dev working on a movement-focused vertical shmup. Part of my design is a fire rate that is refreshed when projectiles hit a collision. The idea is the player has a lower fire rate at the bottom of the screen where they are safest. Fire rate & damage increase the closer you get to an enemy.

I’m not sure how to do this. My ideas are:

  1. Have projectiles be objects that signal when they reach a distance from the generator or collide
  2. Have the generator have a timer for minimum and maximum time between shots fired. Use a signal when projectiles collide to trigger the next shot

Should I have the projectile telling the player script when it collides, or is that something that should be contained within the player script itself?

Potential issues:
A. I’m not sure I have the right idea of signals and how they work.
B. Current plan is to have each projectile be an object. I think particles would be more efficient, which will matter in the future when i add bullet pattern generators and the dodge, roll, boost mechanics.

First time poster, excited to finally be developing my first game! Thanks in advance for your help!!

You can do it the exact same way old shmup game do it, which is to implement a bullet limit. Simply make a variable that keep track of the amount of player bullet on screen, and prevent the player from shooting more when that variable exceed a limit.

1 Like

Expanding on what @otsamu-masto says, back in the elder days this was actually a function of limited hardware; systems had hard limits on the number of sprites they could display, so in a shooter it wasn’t uncommon to budget them out; maybe the player only gets four shot sprites, and if all of them are in flight either the oldest one gets reused, or the player can’t shoot again until one is freed up by going offscreen or hitting something.

The classic example of this is Pac Man; the arcade boards for that had (IIRC) two hardware sprites, but they wanted five sprites (everything else was tiles in a tilemap). The solution they used was, the player gets one sprite, the four enemies get the other sprite. Each of the enemies draws only one frame in four, but CRT phosphor persistence mostly keeps them visible. That made them translucent and flickery, though, so the devs made them look like ghosts and called it a feature.

If you don’t want a limited shot pool, you could use delta in _process() to track the passage of time, position.y to look at how far your ship is from the top of the screen, and do your interval math with that.

1 Like