top of page
Search
cedarcantab

Danmaku using Phaser 3 (lesson 40 part 4): Curve, Gravity, Acceleration, Rotation as Arrays

Updated: Dec 4, 2021

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


記事: Blog2_Post
bottom of page