The N-way code so far allows us to specify the number of "cannons" (ie the bullet streams) and the angle range across which those cannons are positioned. If the angle range of the cannons is set to 360, the NWAY becomes a CIRCLE.
As an added variety, we build some extra code to allow "gaps" between the nways, like below.
Conceptually, this is straightforward. As before, we build the array of cannon angles across the cannon angle range. However, we repeat this process x number of times, cross 360 degrees. I have introduced a new parameter called "numberOfNWAY" to indicate the x.
We need to create a separate piece of code to build the array of cannon angles. The function to create this array (setCannonAngles) is already quite convoluted. To make make the maintenance of this function a little bit easier as with add further functionality, I now pass the danmakuType as a parameter, and use a switch/case statement, like below. The "default" is assumed to be "NWAY".
setCannonAngles(danmakuType) {
// this functinon returns an array of cannon angles according to the DanmakuType
const cannonAngles = [];
switch (danmakuType) {
case "SINGLE":
cannonAngles.push(this.angle + this.randomiseDirection());
break;
case "GAP_CIRCLE":
for (let i = 0; i < this.numberOfCannons; i++) {
cannonAngles.push((this.angle+180) + (i / (this.numberOfCannons - 1) - 0.5) * this.cannonAngleRange + this.randomiseDirection());
} // end of for loop where cannon range is less than 360
break;
case "BI_DIRECTIONAL":
for (let i = 0; i < this.numberOfCannons; i++) {
cannonAngles.push(this.angle + i * (360 / this.numberOfCannons) + this.randomiseDirection());
cannonAngles.push((360 - this.angle) + i * (360 / this.numberOfCannons) + this.randomiseDirection());
} // end of for loop
break;
case "MULTI_NWAY":
for (let j = 0; j < this.numberOfNWAY; j++) {
let nwaycentre = this.angle + j * (360 / this.numberOfNWAY);
for (let i = 0; i < this.numberOfCannons; i++) {
cannonAngles.push(nwaycentre + (i / (this.numberOfCannons - 1) - 0.5) * this.cannonAngleRange);
}
}
break;
default:
if (this.cannonAngleRange < 360) {
for (let i = 0; i < this.numberOfCannons; i++) {
cannonAngles.push(this.angle + (i / (this.numberOfCannons - 1) - 0.5) * this.cannonAngleRange + this.randomiseDirection());
} // end of for loop where cannon range is less than 360
} // end of if statement cannonAngleRange < 360
else
{
// get here if cannon angle range is 360
for (let i = 0; i < this.numberOfCannons; i++) {
cannonAngles.push(i * (360 / this.numberOfCannons) + this.angle + this.randomiseDirection());
} // end of for loop where cannonAngleRange = 360
} // end of case where cannonAngleRange = 360
} // end of switch statement
return cannonAngles;
} // end of setCannonAngle function
And that's pretty much it for the main piece of code, but as always I have made other minor changes, main one being the the firing mechanism for the danmaku (again). In the previuos version of the code, for endless loops, danmaku started firing as soon as the setProperties was called. Now, you do need to call fireRepeatTrigger manually. I though it would be easier to reintroduce the intermittent danmaku into this object at some point.
Also, as I have now specified a new danmakuType called "SINGLE" for where there is only one cannon, as looping through the standard NWAY code with 1 cannon could break the code if the angleRange was 360 as you would end up trying to divide by zero. This way, there is one nesting of if statements if we had to cope with this in the default NWAY calculation.
Another minor change is the a "new" danmakuType called GAP_CIRCLE. In the previous version of the code, I produced gap circle type of danmaku by simply setting the cannonAngleRange to less then 360. This resulted in the gap on the opposite side of the circle from the primary cannon. This is apparently not "correct". The gap should be where the primary cannon is pointing at. This means that if the "aim" property set to the player, the gap in the circle will always be aimed at the player - pretty weird. Anyway, I have now amended the code to reflect this.
I have also dropped the "WASHER" danmakuType as you could have combination of NWAY or MULTI_NWAY or even GAP_CIRCLE with washer type. Instead, I have simply assumed that if there is something assigned to the washer property, then it is a washer type.
As always, here is the Code Pen, for your perusal.
Comments