Last active
March 9, 2025 00:14
-
-
Save lfarroco/10fcdf6b32ea487b268b3fde84673f2b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Phaser Energy Beam | |
// Created with the help of DeepSeek-R1 | |
// https://phaser.io/sandbox/scUBZ1Kv | |
class EnergyBeam extends Phaser.GameObjects.Graphics { | |
constructor(scene, config) { | |
super(scene, config); | |
scene.add.existing(this); | |
this.setBlendMode(Phaser.BlendModes.ADD); | |
// Configuration | |
this.start = config.start; | |
this.end = config.end; | |
this.segments = config?.segments || 40; | |
this.amplitude = config?.amplitude || 15; | |
this.frequency = config?.frequency || 2; | |
this.speed = config?.speed || 0.05; | |
this.color = config?.color || 0xFFD700; | |
this.thickness = config?.thickness || 20; | |
// Internal state | |
this.phase = 0; | |
this.points = []; | |
} | |
updateBeam() { | |
this.clear(); | |
// Calculate beam vector | |
const vec = new Phaser.Math.Vector2( | |
this.end.x - this.start.x, | |
this.end.y - this.start.y | |
); | |
// Normalize and get perpendicular vector | |
const normalized = vec.clone().normalize(); | |
const normal = new Phaser.Math.Vector2(-normalized.y, normalized.x); | |
// Generate points along the beam with sine wave offset | |
this.points = []; | |
for (let i = 0; i <= this.segments; i++) { | |
const t = i / this.segments; | |
const wave = Math.sin(t * Math.PI * this.frequency + this.phase); | |
// Calculate position using original vector direction | |
const basePos = new Phaser.Math.Vector2(this.start.x, this.start.y) | |
.add(vec.clone().scale(t)); | |
const offset = normal.clone().scale(wave * this.amplitude); | |
const pos = basePos.add(offset); | |
this.points.push(pos); | |
} | |
// Draw the beam | |
this.lineStyle(this.thickness, this.color, 0.8); | |
this.beginPath(); | |
this.moveTo(this.points[0].x, this.points[0].y); | |
for (let i = 1; i < this.points.length; i++) { | |
this.lineTo(this.points[i].x, this.points[i].y); | |
} | |
this.strokePath(); | |
// Update phase for animation | |
this.phase += this.speed; | |
} | |
} | |
class MainScene extends Phaser.Scene { | |
constructor() { | |
super({ key: "MainScene" }); | |
} | |
preload() { } | |
create() { | |
this.beams = [] | |
const simple = new EnergyBeam(this, { | |
start: { x: 100, y: 300 }, | |
end: { x: 600, y: 300 }, | |
segments: 12, | |
amplitude: 20, | |
frequency: 1, | |
thickness: 20, | |
color: 0xFFD700, | |
speed: 0.1, | |
}) | |
const twist1 = new EnergyBeam(this, { | |
start: { x: 100, y: 500 }, | |
end: { x: 600, y: 500 }, | |
segments: 12, | |
amplitude: 20, | |
frequency: 1, | |
thickness: 15, | |
color: 0xFFD700, | |
speed: 0.1, | |
}) | |
const twist2 = new EnergyBeam(this, { | |
start: { x: 100, y: 500 }, | |
end: { x: 600, y: 500 }, | |
segments: 11, | |
amplitude: 20, | |
frequency: 3, | |
thickness: 10, | |
color: 0xFFD700, | |
speed: 0.1, | |
}) | |
twist2.phase = 1.5 | |
const twist3 = new EnergyBeam(this, { | |
start: { x: 100, y: 500 }, | |
end: { x: 600, y: 500 }, | |
segments: 12, | |
amplitude: 20, | |
frequency: 1.5, | |
thickness: 5, | |
color: 0xFFD700, | |
speed: 0.1, | |
}) | |
twist3.phase = 2.5 | |
this.beams = [ | |
simple, twist1, twist2, twist3 | |
] | |
} | |
update(time) { | |
this.beams.forEach(beam => beam.updateBeam()) | |
} | |
} | |
const game = new Phaser.Game({ | |
type: Phaser.AUTO, | |
width: 800, | |
height: 800, | |
backgroundColor: '#111111', | |
scale: { | |
mode: Phaser.Scale.FIT, | |
autoCenter: Phaser.Scale.CENTER_BOTH | |
}, | |
scene: [MainScene] | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment