133 lines
3.6 KiB
JavaScript
133 lines
3.6 KiB
JavaScript
const Phaser = require('phaser');
|
|
const { TEXT } = require('.././constants');
|
|
|
|
const BOX = `
|
|
#ifdef GL_ES
|
|
precision mediump float;
|
|
#endif
|
|
|
|
#extension GL_OES_standard_derivatives : enable
|
|
|
|
#ifdef GL_ES
|
|
precision mediump float;
|
|
#endif
|
|
|
|
#extension GL_OES_standard_derivatives : enable
|
|
|
|
uniform float time;
|
|
uniform vec2 resolution;
|
|
uniform vec2 dimensions;
|
|
uniform vec2 offset;
|
|
uniform vec3 colour;
|
|
uniform sampler2D uMainSampler;
|
|
|
|
|
|
varying vec2 outTexCoord;
|
|
varying vec4 outTint;
|
|
|
|
float sdBox( in vec2 p, in vec2 b )
|
|
{
|
|
vec2 d = abs(p)-b;
|
|
return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
|
|
vec2 p = (gl_FragCoord.xy / resolution.xy);
|
|
p.x -= offset.x / resolution.x + dimensions.x / (2.0 * resolution.x);
|
|
p.y -= -1.0 * offset.y / resolution.y + ((resolution.y - dimensions.y) / (2.0 * resolution.y)) + 0.5;
|
|
vec2 dim = 0.5 * dimensions / resolution.xy;
|
|
float d = sdBox(p, dim);
|
|
float tb = abs(sin(time)) + 0.9;
|
|
|
|
vec3 col = tb * colour - sign(d) * vec3(0.1);
|
|
col *= 0.0 + exp(-100.0 * abs(d));
|
|
col += colour * 0.8;
|
|
vec4 texel = texture2D(uMainSampler, outTexCoord);
|
|
texel *= vec4(outTint.rgb * outTint.a, outTint.a);
|
|
|
|
gl_FragColor = vec4(col, 1.0);
|
|
}
|
|
`;
|
|
|
|
|
|
class CustomPipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline {
|
|
constructor(game) {
|
|
super({ game, renderer: game.renderer, fragShader: BOX });
|
|
}
|
|
}
|
|
|
|
function rgbToHex(rgb) {
|
|
const getHex = (c) => {
|
|
const hex = Math.floor(c * 255).toString(16);
|
|
return hex.length === 1 ? `0${hex}` : hex;
|
|
};
|
|
return `0x${getHex(rgb[0])}${getHex(rgb[1])}${getHex(rgb[2])}`;
|
|
}
|
|
|
|
|
|
class BoxEffect extends Phaser.GameObjects.Graphics {
|
|
constructor(scene, x, y, width, height, colour, tag) {
|
|
super(scene);
|
|
this.tag = tag;
|
|
this.customPipeline = scene.game.renderer.addPipeline(tag, new CustomPipeline(scene.game));
|
|
this.customPipeline.setFloat2('resolution', 1600, 1000);
|
|
this.customPipeline.setFloat2('offset', x, y);
|
|
this.customPipeline.setFloat2('dimensions', width, height);
|
|
this.customPipeline.setFloat3('colour', colour[0], colour[1], colour[2]);
|
|
this.bgTime = 10.0;
|
|
|
|
const radius = height / 2;
|
|
this.fillStyle(rgbToHex(colour), 1.0);
|
|
this.fillRect(x + radius, y, width - radius * 2, height);
|
|
this.fillCircle(x + radius, y + radius, radius);
|
|
this.fillCircle(x + width - radius, y + radius, radius);
|
|
|
|
|
|
this.on('destroy', () => {
|
|
scene.game.renderer.removePipeline(tag);
|
|
});
|
|
}
|
|
|
|
activate() {
|
|
this.setPipeline(this.tag);
|
|
}
|
|
|
|
deactivate() {
|
|
this.resetPipeline();
|
|
}
|
|
|
|
update() {
|
|
this.bgTime += 0.05;
|
|
this.customPipeline.setFloat1('time', this.bgTime);
|
|
}
|
|
}
|
|
|
|
class Button extends Phaser.GameObjects.Group {
|
|
constructor(scene, props) {
|
|
const {
|
|
x, y, width, height, colour, glTag, bText, callback,
|
|
} = props;
|
|
|
|
super(scene, { classType: BoxEffect, runChildUpdate: true });
|
|
|
|
const leaveGame = scene.add
|
|
.rectangle(x, y, width, height, 0xaaaaaa, 0xffffff)
|
|
.setInteractive()
|
|
.setOrigin(0);
|
|
|
|
const effect = scene.add.existing(new BoxEffect(scene, x, y, width, height, colour, glTag));
|
|
this.add(effect);
|
|
|
|
leaveGame
|
|
.on('pointerdown', callback)
|
|
.on('pointerover', () => effect.activate())
|
|
.on('pointerout', () => effect.deactivate());
|
|
|
|
this.buttonText = scene.add.text(leaveGame.getCenter().x, leaveGame.getCenter().y, bText, TEXT.HEADER).setOrigin(0.5, 0.5);
|
|
}
|
|
}
|
|
|
|
module.exports = Button;
|