LuaSTG Pattern Making Tool-Using For Loops

From LuaSTG Wiki
Jump to navigation Jump to search

In this tutorial we will build on the SpawnBullet function from the last tutorial by discussing how to spawn many bullets at the same time. As each function call to SpawnBullet spawns a bullet, many bullets can be spawned by many function calls to SpawnBullet. we can use a for loop to do that.


If two bullets are spawned at the same position with identical velocity and sprite, they will overlap and appear no different from a single bullet. We want to avoid this situation by varying some spawning parameters when we spawn the second bullet (note two bullets are guaranteed to not always overlap if any of x y a v fields is different). How do we decide how to vary those parameters? One obvious answer is to make a list of different spawn parameters of every bullet we are going to spawn, and we just go through the list and call SpawnBullet on each set of spawn parameters. But this is way too impractical when there are hundreds to thousands of bullets spawned over a short time. That is, we need a way to automatically generate spawn parameters for each bullet.


A simple way to do this follows: when we have spawned a bullet, we increment some spawn parameters by a fixed value and then spawn the next one. In this way bullets are guaranteed to have distinct spawn parameters because at least one of the parameter will always be increasing (and therefore never repeats, with the exception of modular variables like angles).


Spawning a Ring[edit | edit source]

Our first example will be spawning bullets on a ring. A ring of bullets is a circular shape formed by bullets, where each one of them appear evenly positioned on the circle. It is one of the most, if not the most commonly used patterns in a shmup game. Below shows an image of a ring of bullets and a piece of pseudo-code that spawns it. The fairy enemy in the image marks the spawn position of the bullets.

Generating a Ring of Bullets Using a For Loop


For bullets on the ring, the only parameter that differs is the bullet moving direction. In this case only the variable a is changed inside the loop. Nonetheless there are actually more than one way to generate rings of bullets besides changing the value of a. They can be initially spawned on a circle and moving in the same direction with the same speed, or both spawned on a circle and with an increment on a of 360 / nBullet.

Spawning Multiple Rings[edit | edit source]

We've talked about how to use a for loop to spawn a ring of bullets, and the next step we will look at an example that spawns multiple rings. We do this by adding another for loop over the original for loop, and the original loop is said to be nested inside the new for loop. We call the original loop wrapped inside the inner loop, and the entire new loop the outer loop. The way we can generate multiple rings is simply by using the outer loop to run the inner loop many times and generate single rings many times.


Suppose we want to shoot all the rings at the same time, and each ring of bullets' speed is slightly faster than the speed of the bullets in the previous ring (otherwise if we don't change the speed the rings will overlap with each other). We do this by increment the speed in the spawn parameters by a fixed value in the outer for loop. In this way the outer loop will modify speed, while the inner loop will modify direction.


But now we have a problem. We've been re-using the same table to shoot every bullet. In the inner loop, the table is modified where the value a is incremented. The value of a will end up being 360 instead of 0 after the inner loop finishes execution. In this case both values refer to the same angle, but this is not always true for incrementing x y v or with a different increment of a and therefore causes a potential problem.


A solution is to copy the entire table before the execution of the inner for loop. Then inside the inner loop we can safely modify the variables on the table copy. After the loop execution the copy of the table is polluted and that copy will be thrown away. The original values in the table of the outer for loop will be unaffected.

Generating Rings of Bullets Using a Nested For Loop


In the above example the code makes a copy of the table before both the inner for loop and the outer for loop. This prevents any modification to the initial table in addition to our previous point.


One may ask what is good about using this table method to store parameters. The answer is using table allows states to exist, be modified when the for loop is executing, and this tutorial will utilize this feature later. By the way even if you use other methods, the copying of parameters still can't be avoided.


In this page we've talked about how many bullets can be spawned by either a single for loop or a nested for loop. An example of pattern is given for both cases, and we discussed some differences between the pseudo-source code of these cases, and introduced for loop increments as a convenient way to change the spawning parameters between shots.