[Phaser 3] Custom image class to make procedural sky


#1

Hi all,
I have made a custom image class for Phaser 3 to generate a sky for a small asteroids style game (the first with Phaser 3).
Here is the demo: https://jjcapellan.github.io/skygenerator/
Complete source code here: https://github.com/jjcapellan/skygenerator/blob/master/dist/skygenerator.js
This class does the following:

  • Generates two coordinate maps with transparencies.
  • Creates a texture for the clouds and three for the stars using a graphics object.
  • Using the map data, repeatedly draws the previous textures in a new texture that will be applied to the image itself.
    My first difficulty was getting a smooth gradient fill in a circle using the Graphics class. This was my best solution at the moment:
/**
   * Makes a "brush" based on overlayed semitransparent circles to get a gradient of transparency
   * f(x) = minRadius + k*x*x ------> x = step in for loop; f(x) = radius (quadratic easing in)
   * @param  {number} radius 
   * @param  {number} gradient Number between 0 and 1. 1 = Max softness.
   * @param  {boolean} isStar
   * @return {Phaser.GameObjects.Graphics}
   * @memberof SkyGenerator
   */
  makeBrush(radius, gradient, isStar) {
    let brush = this.scene.add.graphics();
    let steps = Math.round(200 * gradient);
    let k = (radius - 1) / (steps * steps);
    let alpha = this.starAlpha / steps;
    let prevRadius = 0;

    if (alpha < 0.005) alpha = 0.005;
    brush.setVisible(false);

    for (let i = 0; i < radius + 1; i++) {
      brush.fillStyle(0xffffff, alpha);
      let r = Math.round(1 + i * i * k);
      if (r < 1) r = 1;
      if (r > radius) r = radius;
      // prevents draw two times same circle
      if (r == prevRadius) {
        continue;
      } else {
        prevRadius = r;
      }
      brush.fillCircle(0, 0, r);
    }

    if (isStar) {
      if (this.starHardness == 0) this.starHardness = 0.001;
      brush.fillStyle(0xffffff, this.starAlpha);
      brush.fillCircle(0, 0, radius * this.starHardness);
    }
    return brush;
  }

Here some samples:


I still need to improve the point generation algorithm, since they tend to cluster in the same place.
This is my humble contribution to the community :grinning:. I hope someone finds it useful.
Greetings.


#2

Neat :+1:


#3

Thanks!.