So far I have created danmaku patterns based on some kind of algorithm that alters the direction of the bullet and the speed, based on fixed parameters fed to the danmaku object. What if we could actually pass the "pattern" of the bullet as a parameter? That is the subject of this post - "PAINT" danmaku.
In principle, similar to the NWAY function
Simple things first: to tell the danmaku object that we want a "PAINT" danmaku, we set the danmakuType to "PAINT".
To tell what kind of "picture" to paint, we create a new variable called picture, which is an array of strings (each string representing 1 row) which consist of space and placeholders for where the bullet should be "painted" (any character would do). The picture array used for the above example is as below ("x" has been used as the placeholder, but anything other than space would do).
const star = [
" x ",
" x x ",
"xxxxxxxxxxxxx",
" x x x x ",
" x x ",
" x x x x ",
"xxxxxxxxxxxxx",
" x x ",
" x "
]
Within the setProperties method, the following code has been inserted to set the this.numberOfShots to the number of "rows" of the picture object to be painted.
// danmakuType = "PAINT"
this.danmakuType = danmakuType;
this.picture = picture;
if (danmakuType === "PAINT") {
this.numberOfShots = this.picture.length-1;
}
The mechanism I have used to "paint" the picture is similar to the NWAY algorithm, with the cannonAngleRange representing how "wide" the picture spreads, and numberOfCannons being represented by the number of characters in each line of the picture.
Within the switch statement of the setUpCannons function, the following code has been added to calculate the angle of cannons (the bullet speed is consistent).
case "PAINT":
let cannonsInGroup = [];
// this.cannonAngleRange must be below 180
// this.numberOfShots = number of "rows" in the picture
// this.repeatShotsTimer.repeatCount holds the current "row" to be painted
const line = this.picture[this.repeatShotsTimer.repeatCount];
this.numberOfCannons = line.length;
for (let i = 0; i < this.numberOfCannons; i++) {
if (line.charAt(i) !== " ") {
this.cannonAngles.push(this.angle + this.cannonAngleRange * (0.5 - i / (this.numberOfCannons - 1)));
// bullets can only be normal type. no overtaking or spreadshots
cannonsInGroup.push(this.bulletSpeed);
}
} // end of for loop where cannon range is less than 360
this.cannonShotSpeeds.push(cannonsInGroup);
break;
And that's essentially it.
Creating Text
The complexity of the patterns is limited by the size of the canvas, but you can get quite interesting results. Here is an example which has the danmaku firing the text "BULLET".
The configuration for the above example is as below.
const bulletText = [
"#### # # # # #### #####",
"# # # # # # # # ",
"#### # # # # ### # ",
"# # # # # # # # ",
"#### ##### #### #### #### # "
];
danmakuPattern.push({
name: "PAINT-BULLET",
danmakuType: "PAINT",
picture: bulletText,
numberOfCannons: 10, // number of (pair in case of bi-directional danmaku) cannons
cannonAngle: 90, // direction in which the primary cannon faces.
cannonAngleRange: 90, // used to n-way type. angle range across which cannons are positioned.
numberOfShots: 5, // how many times to shoot the weapon in succession
stopShotsTime: 500,
// properties for individual bullets
bulletType: "NORMAL",
bulletSpeed: 200, // speed of bullets fired from cannon
timeBetweenShots: 100, // time between bullets in ms
bulletTexture: "bullet7" // specify the bullet image to be used,
});
The CodePen is available here for your perusal and comment.
Comments