top of page
Search
cedarcantab

Danmaku using Phaser 3 (lesson 33): "Waving" and "Bending" bullet revisited

Updated: Nov 21, 2021

In lesson 20 I created the "waving" bullet type. This was a bullet that changed its bearing from 90 degrees to -90 degrees around the original bearing over a fixed interval as it flew, giving the impression of "waving". The only parameter this bullet type took was a "cycleLength" which was the period in which the bullet would complete its "swing" cycle.


In this post I have added a parameter to specify the degree of the "swing". This is a simple modification so this post will be short, for a change.




Renaming the bulletype to "SWING"

First things first, I have changed the name of the bulletType.class from "WAVING" to "SWING".


In order to specify the degree of swing, I created a new parameter called swingDelta, which will be assigned to this.bulletSwingDelta. After that, it is simply a matter of amending the number tween used to create the "swing", as below.

// if WAVING type, then set up tween to adjust the bulletBearing
    if (this.bulletType === "SWING") {
      this.swing = this.scene.tweens.addCounter({
        from: -this.bulletSwingDelta * this.bulletSwitch,
        to: this.bulletSwingDelta * this.bulletSwitch,
        duration: this.bulletCycleLength,
        repeat: -1,
        yoyo: true
      }); // end of WAVING bullet tween set up
    } // end of if statement to check for "SWING"

The danmaku at the top of this post was created with the parameter set below.


  danmakuPattern.push({
    name: "10-WAY WITH WAVING BULLETS",
    danmakuConfig: {
      class: "NWAY" , count: 10,
      angle: 90
    },
 
    bulletType: {
      class: "SWING", swingDelta: 60, cycleLength: 1000,
      speed: 80, fireRate: 300,
      texture: "moth",
      frame: 3,
      lifeSpan: 15000
    },
  });


Updating the Bending bullet code

While I'm at it, I have also amended the curving bullet code slightly. In the previous version of the code, the bearing of the bullet was changed directly by a number tween which "swung" the bearing from bulletBearing to bulletBearing + 2PI. In the new version of the code, I have created a new variable called referenceBearing which is a copy of the original bulletBearing, and the "swing" number tween swings from 0 to 2PI, and the bulletBearing is set by adding the number tween value to refererenceBearing.


The number tween to give the "bend" factor is created by the code below.


// if bulletBearingVelocity is set, it means the bullet should fly along curve - so set up tween to adjust direction
    if (this.bulletBearingVelocity !== 0) {
      this.bearingChange = this.scene.tweens.addCounter({
        from: 0,
        to: Math.sign(this.bulletBearingVelocity) * 2 * Math.PI,
        duration: ((2 * Math.PI) / Math.abs(this.bulletBearingVelocity)) * 1000,
        repeat: -1
      }); // end of Bending Bullet tween set up
    } // end of if statement to check for "BEND"

Then within the preUpdate function, the following code is used to set the bulletBearing based on the sum of referenceBearing and the number tween value.


   // if there is bearing velocity set, then adjust the bearing angle of the velocity
    if (this.body.speed !==0 && this.bulletBearingVelocity !== 0) {
      this.bulletBearing = this.referenceBearing + this.bearingChange.getValue();
      // if the bullet is not rotating type, set the angle of bullet image in line with the bullet bearing
      if (this.bulletAngularVelocity === 0) {
        this.setRotation(this.bulletBearing);
      }
      this.adjustVelocity(this.bulletBearing, this.body.speed, this.bulletAcceleration);
    }

This change was made simply so that if we have a curving bullet with bounce property set, in the previous version of the code, it used to get stuck at the edge, as the code could not change the bearing of the velocity. Now the bullet does bounce even the curving kind.


// "BOUNCE!": reverse direction if hit left or right of screen
    if (this.bulletBounceX > 0 && this.hitEdgeX(this)) {
      if (this.x <= this.displayWidth / 2) {
        this.setX(this.displayWidth / 2 + 1)
      } else if (this.x >= WIDTH - this.displayWidth / 2) {
        this.setX(WIDTH - this.displayWidth / 2 - 1)
      }
      this.setVelocityX(-this.body.velocity.x * this.bulletBounceX);
      this.bounceOffWall();
    }

The following piece of code is called when a bullet is bounced off the wall.


bounceOffWall() {
    this.setRotation(Phaser.Math.Angle.Wrap(this.body.velocity.angle()));
      this.referenceBearing = this.rotation;
      this.bulletBearing = this.rotation;
      if (this.swing) {this.swing.restart()}
      if (this.bearingChange) {this.bearingChange.restart()}
  }

And that's it! Here is the CodePen for your perusal and comment.






Comments


記事: Blog2_Post
bottom of page