I continue to expand the scope of parameters which can be passed as arrays.
With parameters that are passed "as-they-are" to the bullet.fire method from within the fireShot method, they can all be made to accept arrays, in principle, by inserting the readParam function. In addition to the bullet texture/frame, I have made changes so the following parameters, as shown below:
bullet bearing velocity (ie curving bullets)
bullet acceleration
bullet image rotation
bullet gravityX
bullet gravityY
if (this.flyAwayOption >0) {this.bulletTransform.bearing = flyAwayAngles[j]}
bullet.fire(scene, {
...
bulletBearingVelocity: readParam(readParam(this.bulletBearingVelocity,this.danmakuCounter),j),
bulletSwingDelta: readParam(readParam(this.bulletSwingDelta,this.danmakuCounter),j),
bulletSpeed: this.cannonShotSpeeds[i][j], // the speed of the bullet
bulletAcceleration: readParam(readParam(this.bulletAcceleration, this.danmakuCounter),j),
bulletAngle: direction, // angle of the bullet image - make it equal to cannon direction
bulletAngularVelocity: readParam(readParam(this.bulletAngularVelocity,this.danmakuCounter),j), // rotating bullet image
bulletTexture: readParam(bulletImage.texture, j),
bulletFrame: readParam(bulletImage.frame, j),
...
bulletGravityX: readParam(readParam(this.bulletGravityX,this.danmakuCounter),j),
bulletGravityY: readParam(readParam(this.bulletGravityY,this.danmakuCounter),j),
...
}); // end of bullet fire method
} // end of if statement which checks whether bullet is null
The only bit requiring additional care is if the parameter that requires converting to radians from degrees upon receipt by setProperties. This is taken care of by the newly created function below.
function DegToRad(param) {
if (typeof(param) === "number") {
return Phaser.Math.DegToRad(param)
} else {
const workArray = [];
param.forEach(item => {
workArray.push(DegToRad(item))
});
return workArray
}
} // converted array of angles in degrees to radians
With the above function, setting the respective danmaku properties within the setProperties method becomes easy, as follows:
this.bulletBearingVelocity = bulletConfig.bearingVelocity === undefined ? 0 : DegToRad(bulletConfig.bearingVelocity);
this.bulletSwingDelta = bulletConfig.swingDelta === undefined ? Math.PI/2 : DegToRad(bulletConfig.swingDelta)
Ability to set gravity to each "arm" of parallel bullets
With the ability to change the gravity, we can create the "split shot" available in the Phaser 2 example, I looked at a long time ago. With the following simple parameter set, which is essentially a 1-way with 3 cannons in parallel, but with the gravity in the x-direction of each "arm" set differently, we can have the player shoot bullets that "split" to the left and right.
this.playerdanmaku.setProperties(scene, {
// properties for cannon(s)
danmakuConfig: {
type: "PARALLEL", countB:3,
angle: -90,
},
cannonConfig: {
numberOfShots: 1,
sound: bulletSound1
},
// properties for individual bullets
bulletConfig: {
class: "NORMAL",
speed: 700, gravityX: [[500,0,-500]],
texture: "shell", frame: 3
},
Ability to set swing delta of each arm
With the ability to set swing delta (ie the degree to which bullets "swing", we can do something like this:
danmakuPattern.push({
name: "10-WAY WITH WAVING BULLETS",
danmakuConfig: {
countA: 10,
angle: 90
},
cannonConfig: {
fireRate: 200,
},
bulletConfig: {
class: "SWING", swingDelta: [[45,-45]], cycleLength: 1000,
speed: 100,
texture: "roundMID",
frame: [[1,2,3,4,5]],
lifeSpan: 15000
},
});
In the previous version of the code, I had created an overly convoluted mechanism involving passing the danmaku a cannonConfig.toggleOn flag, which was then passed onto the bullet object which in turn used it to switch the "direction" of the wave. I can now delete all of this code as using arrays is intuitively more obvious.
Simulating popular Toho bullet hell patterns
With the above changes, I have tried to simulate one of the most popular bullet hell patterns from the Toho series. In this post, with the amendments made, I have attempted to mimic the spell card called 金&水符 「マーキュリポイズン」 from 東方紅魔郷 with the following parameter set. You cannot really tell from the still picture (at the top of this post), but it is quite a pretty danmaku.
As always with this "challenge", my attempt is based only simple viewing of youtube videos and no looking at the actual code.
danmakuPattern.push({
name: "BI-DIRECTIONAL RINGS WITH STOP&GO",
danmakuConfig: {
countA:30,
},
cannonConfig: {
numberOfShots: 2,
stopShotsTime: 500,
fireRate: 70, // time between bullets in ms
},
bulletConfig: {
class: "NORMAL",
speed: [300, 250],
bearingVelocity: [20,18,-20,-18],
texture: "roundMID", frame: [5,5,3,3],
},
bulletTransform: {
class: "STOP&GO",
speed: 50,
acceleration: 10,
stage1Time: 200,
stage2Time: 0,
},
});
And that's it for this post. Here is the CodePen for your perusal and comment.
Comments