Skip to content

Commit 65d931e

Browse files
committed
e
1 parent f053e3d commit 65d931e

26 files changed

+2856
-10
lines changed

CharacterGlowEffect.hx

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
// Character Glow with Darkness Effect - Pure HScript Implementation
2+
// Creates a darkness overlay with character highlighting using only sprites
3+
4+
import flixel.FlxG;
5+
import flixel.FlxObject;
6+
import flixel.FlxSprite;
7+
import flixel.group.FlxGroup;
8+
import flixel.math.FlxMath;
9+
import flixel.tweens.FlxEase;
10+
import flixel.tweens.FlxTween;
11+
import flixel.util.FlxColor;
12+
import openfl.display.BlendMode;
13+
14+
// Effect components
15+
var darknessOverlay:FlxSprite;
16+
var glowSprite:FlxSprite;
17+
var targetCharacter:FlxObject;
18+
var effectGroup:FlxGroup;
19+
var isActive:Bool = false;
20+
21+
// Glow effect variables
22+
var glowRadius:Float = 150;
23+
var glowIntensity:Float = 0.8;
24+
var darknessAlpha:Float = 0.6;
25+
var pulseTime:Float = 0.0;
26+
var pulseSpeed:Float = 2.0;
27+
var followSpeed:Float = 0.08;
28+
var glowColor:FlxColor = FlxColor.fromRGB(255, 255, 180); // Warm white
29+
30+
// Animation variables
31+
var currentGlowX:Float = 0;
32+
var currentGlowY:Float = 0;
33+
34+
function onCreate() {
35+
// Create effect group to manage layering
36+
effectGroup = new FlxGroup();
37+
38+
// Create darkness overlay - full screen black sprite
39+
darknessOverlay = new FlxSprite(0, 0);
40+
darknessOverlay.makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
41+
darknessOverlay.alpha = darknessAlpha;
42+
darknessOverlay.scrollFactor.set(0, 0); // Stay fixed to camera
43+
darknessOverlay.cameras = [FlxG.camera];
44+
45+
// Create glow sprite
46+
createGlowSprite();
47+
48+
// Add to effect group
49+
effectGroup.add(darknessOverlay);
50+
effectGroup.add(glowSprite);
51+
52+
trace("Character Glow Effect initialized!");
53+
}
54+
55+
function createGlowSprite() {
56+
var glowSize = Std.int(glowRadius * 2);
57+
glowSprite = new FlxSprite(0, 0);
58+
glowSprite.makeGraphic(glowSize, glowSize, FlxColor.TRANSPARENT);
59+
60+
// Create radial gradient glow effect by drawing circles
61+
var centerX = glowSize / 2;
62+
var centerY = glowSize / 2;
63+
var maxRadius = glowRadius * 0.8;
64+
65+
// Draw multiple circles with decreasing alpha for smooth gradient
66+
var steps = 20;
67+
for (i in 0...steps) {
68+
var radius = maxRadius * (steps - i) / steps;
69+
var alpha = 1.0 * i / steps;
70+
var color = FlxColor.fromRGBFloat(
71+
glowColor.redFloat,
72+
glowColor.greenFloat,
73+
glowColor.blueFloat,
74+
alpha * glowIntensity
75+
);
76+
77+
// Simple circle drawing using rectangles (HScript compatible)
78+
var circleRadius = Std.int(radius);
79+
for (x in -circleRadius...circleRadius) {
80+
for (y in -circleRadius...circleRadius) {
81+
var dist = Math.sqrt(x * x + y * y);
82+
if (dist <= radius && dist > radius - 3) {
83+
var pixelX = Std.int(centerX + x);
84+
var pixelY = Std.int(centerY + y);
85+
if (pixelX >= 0 && pixelX < glowSize && pixelY >= 0 && pixelY < glowSize) {
86+
// This creates the glow effect
87+
glowSprite.pixels.setPixel32(pixelX, pixelY, color);
88+
}
89+
}
90+
}
91+
}
92+
}
93+
94+
// Set blend mode for additive glow effect
95+
glowSprite.blend = BlendMode.ADD;
96+
glowSprite.scrollFactor.set(0, 0);
97+
glowSprite.cameras = [FlxG.camera];
98+
}
99+
100+
function onCreatePost() {
101+
// Set default target to boyfriend
102+
if (game.boyfriend != null) {
103+
setGlowTarget(game.boyfriend);
104+
}
105+
}
106+
107+
function onUpdate(elapsed:Float) {
108+
if (!isActive) return;
109+
110+
// Update pulse animation
111+
pulseTime += elapsed * pulseSpeed;
112+
var pulseValue = Math.sin(pulseTime) * 0.3 + 0.7; // Pulse between 0.4 and 1.0
113+
114+
// Update glow intensity based on pulse
115+
glowSprite.alpha = glowIntensity * pulseValue;
116+
117+
// Follow target character smoothly
118+
if (targetCharacter != null) {
119+
var targetX = targetCharacter.x + targetCharacter.width * 0.5 - glowRadius;
120+
var targetY = targetCharacter.y + targetCharacter.height * 0.5 - glowRadius;
121+
122+
// Convert world coordinates to screen coordinates
123+
targetX -= FlxG.camera.scroll.x;
124+
targetY -= FlxG.camera.scroll.y;
125+
126+
// Smooth following
127+
currentGlowX = FlxMath.lerp(currentGlowX, targetX, followSpeed);
128+
currentGlowY = FlxMath.lerp(currentGlowY, targetY, followSpeed);
129+
130+
glowSprite.x = currentGlowX;
131+
glowSprite.y = currentGlowY;
132+
}
133+
134+
// Update darkness overlay to punch hole where glow is
135+
updateDarknessWithHole();
136+
}
137+
138+
function updateDarknessWithHole() {
139+
if (darknessOverlay == null || glowSprite == null) return;
140+
141+
// Recreate darkness overlay with hole
142+
darknessOverlay.makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
143+
144+
// Create a "hole" in the darkness where the glow is
145+
var holeRadius = glowRadius * 0.7;
146+
var centerX = glowSprite.x + glowRadius;
147+
var centerY = glowSprite.y + glowRadius;
148+
149+
// Make pixels transparent in a circular area around the glow
150+
for (x in 0...FlxG.width) {
151+
for (y in 0...FlxG.height) {
152+
var dist = Math.sqrt((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY));
153+
if (dist < holeRadius) {
154+
// Create smooth falloff
155+
var transparency = 1.0 - (dist / holeRadius);
156+
transparency = Math.pow(transparency, 1.5); // Smoother curve
157+
var alpha = darknessAlpha * (1.0 - transparency);
158+
159+
var color = FlxColor.fromRGBFloat(0, 0, 0, alpha);
160+
darknessOverlay.pixels.setPixel32(x, y, color);
161+
}
162+
}
163+
}
164+
165+
// Apply changes
166+
darknessOverlay.dirty = true;
167+
}
168+
169+
// Public functions for controlling the effect
170+
171+
function enableGlowEffect(?target:FlxObject) {
172+
if (isActive) return;
173+
174+
// Add effects to the game
175+
game.add(effectGroup);
176+
177+
if (target != null) {
178+
setGlowTarget(target);
179+
}
180+
181+
// Fade in effect
182+
darknessOverlay.alpha = 0;
183+
glowSprite.alpha = 0;
184+
185+
FlxTween.tween(darknessOverlay, {alpha: darknessAlpha}, 0.5, {ease: FlxEase.quadOut});
186+
FlxTween.tween(glowSprite, {alpha: glowIntensity}, 0.5, {ease: FlxEase.quadOut});
187+
188+
isActive = true;
189+
trace("Character glow effect enabled!");
190+
}
191+
192+
function disableGlowEffect() {
193+
if (!isActive) return;
194+
195+
// Fade out effect
196+
FlxTween.tween(darknessOverlay, {alpha: 0}, 0.5, {
197+
ease: FlxEase.quadIn,
198+
onComplete: function(tween:FlxTween) {
199+
game.remove(effectGroup);
200+
}
201+
});
202+
FlxTween.tween(glowSprite, {alpha: 0}, 0.5, {ease: FlxEase.quadIn});
203+
204+
isActive = false;
205+
trace("Character glow effect disabled!");
206+
}
207+
208+
function setGlowTarget(character:FlxObject) {
209+
targetCharacter = character;
210+
if (character != null) {
211+
// Immediately position glow on target
212+
currentGlowX = character.x + character.width * 0.5 - glowRadius - FlxG.camera.scroll.x;
213+
currentGlowY = character.y + character.height * 0.5 - glowRadius - FlxG.camera.scroll.y;
214+
215+
if (glowSprite != null) {
216+
glowSprite.x = currentGlowX;
217+
glowSprite.y = currentGlowY;
218+
}
219+
220+
trace("Glow target set to character");
221+
}
222+
}
223+
224+
function setGlowColor(color:FlxColor) {
225+
glowColor = color;
226+
createGlowSprite(); // Recreate with new color
227+
228+
// Update in effect group
229+
effectGroup.remove(effectGroup.members[1]); // Remove old glow
230+
effectGroup.add(glowSprite); // Add new glow
231+
}
232+
233+
function setGlowIntensity(intensity:Float, ?tweenDuration:Float = 0.0) {
234+
glowIntensity = intensity;
235+
if (tweenDuration > 0 && glowSprite != null) {
236+
FlxTween.tween(glowSprite, {alpha: intensity}, tweenDuration);
237+
}
238+
}
239+
240+
function setDarknessLevel(alpha:Float, ?tweenDuration:Float = 0.0) {
241+
darknessAlpha = alpha;
242+
if (tweenDuration > 0 && darknessOverlay != null) {
243+
FlxTween.tween(darknessOverlay, {alpha: alpha}, tweenDuration);
244+
} else if (darknessOverlay != null) {
245+
darknessOverlay.alpha = alpha;
246+
}
247+
}
248+
249+
function setGlowSize(radius:Float) {
250+
glowRadius = radius;
251+
createGlowSprite(); // Recreate with new size
252+
253+
// Update in effect group
254+
effectGroup.remove(effectGroup.members[1]); // Remove old glow
255+
effectGroup.add(glowSprite); // Add new glow
256+
}
257+
258+
function setPulseSpeed(speed:Float) {
259+
pulseSpeed = speed;
260+
}
261+
262+
function dramaticFlash(flashIntensity:Float = 2.0, duration:Float = 1.0) {
263+
if (!isActive || glowSprite == null) return;
264+
265+
var originalIntensity = glowIntensity;
266+
var originalSize = glowRadius;
267+
268+
// Flash effect
269+
FlxTween.tween(glowSprite, {alpha: flashIntensity}, duration * 0.2, {
270+
ease: FlxEase.quadOut,
271+
onComplete: function(tween:FlxTween) {
272+
FlxTween.tween(glowSprite, {alpha: originalIntensity}, duration * 0.8, {
273+
ease: FlxEase.quadInOut
274+
});
275+
}
276+
});
277+
278+
// Size pulse
279+
var targetSize = originalSize * 1.5;
280+
setGlowSize(targetSize);
281+
FlxTween.tween(this, {glowRadius: originalSize}, duration, {
282+
ease: FlxEase.elasticOut,
283+
onUpdate: function(tween:FlxTween) {
284+
setGlowSize(glowRadius);
285+
}
286+
});
287+
}
288+
289+
// Event system integration
290+
function onEvent(eventName:String, value1:String, value2:String, strumTime:Float) {
291+
switch(eventName) {
292+
case "Character Glow" | "Glow Effect":
293+
var action = value1.toLowerCase();
294+
switch(action) {
295+
case "enable" | "on":
296+
enableGlowEffect();
297+
case "disable" | "off":
298+
disableGlowEffect();
299+
case "bf" | "boyfriend":
300+
setGlowTarget(game.boyfriend);
301+
case "dad" | "opponent":
302+
setGlowTarget(game.dad);
303+
case "gf" | "girlfriend":
304+
if (game.gf != null) setGlowTarget(game.gf);
305+
case "flash" | "dramatic":
306+
var intensity = Std.parseFloat(value2);
307+
if (Math.isNaN(intensity)) intensity = 2.0;
308+
dramaticFlash(intensity);
309+
case "intensity":
310+
var value = Std.parseFloat(value2);
311+
if (!Math.isNaN(value)) setGlowIntensity(value, 0.5);
312+
case "darkness":
313+
var value = Std.parseFloat(value2);
314+
if (!Math.isNaN(value)) setDarknessLevel(value, 0.5);
315+
case "size":
316+
var value = Std.parseFloat(value2);
317+
if (!Math.isNaN(value)) setGlowSize(value);
318+
case "speed":
319+
var value = Std.parseFloat(value2);
320+
if (!Math.isNaN(value)) setPulseSpeed(value);
321+
case "blue":
322+
setGlowColor(FlxColor.fromRGB(100, 150, 255));
323+
case "red":
324+
setGlowColor(FlxColor.fromRGB(255, 100, 100));
325+
case "green":
326+
setGlowColor(FlxColor.fromRGB(100, 255, 150));
327+
case "purple":
328+
setGlowColor(FlxColor.fromRGB(200, 100, 255));
329+
case "white":
330+
setGlowColor(FlxColor.WHITE);
331+
}
332+
}
333+
}
334+
335+
// Keyboard controls for testing
336+
function onUpdatePost(elapsed:Float) {
337+
// Test controls (remove in production)
338+
if (FlxG.keys.justPressed.G) {
339+
if (isActive) {
340+
disableGlowEffect();
341+
} else {
342+
enableGlowEffect(game.boyfriend);
343+
}
344+
}
345+
346+
if (FlxG.keys.justPressed.ONE && isActive) {
347+
setGlowTarget(game.boyfriend);
348+
}
349+
350+
if (FlxG.keys.justPressed.TWO && isActive) {
351+
setGlowTarget(game.dad);
352+
}
353+
354+
if (FlxG.keys.justPressed.THREE && isActive) {
355+
dramaticFlash();
356+
}
357+
}
358+
359+
// Cleanup
360+
function onDestroy() {
361+
if (isActive) {
362+
disableGlowEffect();
363+
}
364+
365+
if (effectGroup != null) {
366+
effectGroup.destroy();
367+
}
368+
}

0 commit comments

Comments
 (0)