alphabet effects!

This commit is contained in:
SrtHero278
2024-07-04 08:54:24 -07:00
parent 8fa83c9623
commit d3748355a6
7 changed files with 191 additions and 5 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
<!DOCTYPE codename-engine-alphabet-font>
<alphabetFont fps="24" advance="30" lineGap="70">
<alphabetFont fps="24" advance="30" lineGap="70" useColorOffsets="true">
<spritesheet>menus/alphabet</spritesheet>
<defaultAnim casing="upper">LETTER capital</defaultAnim>
+11
View File
@@ -51,6 +51,17 @@ class CoolUtil
return (v == null || isNaN(v)) ? defaultValue : v;
}
/**
* Applies the % operator, but without any negatives.
*
* @param dividend The intial value. The left side of the equation.
* @param divisor What to modulo by. The right side of the equation.
* @return A positive reminder of `dividend / divisor`.
*/
public static inline function positiveModulo(dividend:Float, divisor:Float) {
return ((dividend % divisor) + divisor) % divisor;
}
/**
* Shortcut to parse JSON from an Asset path
* @param assetPath Path to the JSON asset.
+35 -4
View File
@@ -1,11 +1,15 @@
package funkin.menus.ui;
import funkin.menus.ui.effects.RegionEffect;
import flixel.animation.FlxAnimation;
import flixel.util.FlxDirectionFlags;
import flixel.math.FlxPoint;
import haxe.xml.Access;
import flixel.animation.FlxAnimation;
using StringTools;
using flixel.util.FlxColorTransformUtil;
enum abstract AlphabetAlignment(Int) from Int to Int {
var LEFT;
@@ -46,6 +50,9 @@ enum abstract CaseMode(Int) from Int to Int {
}
class NewAlphabet extends FlxSprite {
public var effects:Array<RegionEffect> = [];
var __renderData:AlphabetRenderData;
public var text(default, set):String = "";
@:isVar public var textWidth(get, set):Float;
public var textHeight(get, null):Float;
@@ -62,6 +69,7 @@ class NewAlphabet extends FlxSprite {
public var originOffset:FlxPoint = FlxPoint.get();
public var font(default, set):String;
var transformMult:Int = 1; // 1 if multipliers (tint), 0 if offset.
var defaultAdvance:Float = 40.0;
var lineGap:Float = 75.0;
var fps:Float = 24.0;
@@ -75,6 +83,7 @@ class NewAlphabet extends FlxSprite {
public function new(?x:Float, ?y:Float, ?font:String = "bold") {
super(x, y);
this.font = font;
this.__renderData = new AlphabetRenderData(this);
}
override function update(elapsed:Float) {
@@ -97,6 +106,8 @@ class NewAlphabet extends FlxSprite {
// FLXOBJECT UPDATE END
__animTime += elapsed;
for (effect in effects)
effect.effectTime += FlxG.elapsed * effect.speed;
}
override function draw() {
@@ -115,6 +126,7 @@ class NewAlphabet extends FlxSprite {
if (__queueResize)
recalcSizes();
var curLine = 0;
var lastLine = 0;
var daText = switch (forceCase) {
case UPPER: text.toUpperCase();
case LOWER: text.toLowerCase();
@@ -128,11 +140,22 @@ class NewAlphabet extends FlxSprite {
frameOffset.x -= (textWidth - __laneWidths[0]) * alignmentMultiplier;
var isGraphicsShader = shader != null && shader is flixel.graphics.tile.FlxGraphicsShader;
var offsetMult = (1 - transformMult) * 255;
var ogRed:Float = colorTransform.redMultiplier;
var ogGreen:Float = colorTransform.greenMultiplier;
var ogBlue:Float = colorTransform.blueMultiplier;
for (i in 0...daText.length) {
var letter = daText.charAt(i);
__renderData.reset(this, daText.charAt(i));
for (effect in effects) {
if (effect.willModify(i, i - lastLine, __renderData))
effect.modify(i, i - lastLine, __renderData);
}
var letter = __renderData.letter;
if (letter == "\n") {
curLine++;
lastLine = i + 1;
frameOffset.x = ogOffX - (textWidth - __laneWidths[curLine]) * alignmentMultiplier;
frameOffset.y -= lineGap;
continue;
@@ -147,8 +170,8 @@ class NewAlphabet extends FlxSprite {
var frameToGet = Math.floor(__animTime * fps) % anim.numFrames;
frame = frames.frames[anim.frames[frameToGet]];
var offsetX = xOffset.exists(letter) ? xOffset.get(letter) : 0;
var offsetY = frame.sourceSize.y - lineGap + (yOffset.exists(letter) ? yOffset.get(letter) : 0);
var offsetX = (xOffset.exists(letter) ? xOffset.get(letter) : 0) + __renderData.offsetX;
var offsetY = frame.sourceSize.y - lineGap + (yOffset.exists(letter) ? yOffset.get(letter) : 0) + __renderData.offsetY;
frameOffset.x += offsetX;
frameOffset.y += offsetY;
if (!isOnScreen(camera)) {
@@ -160,11 +183,18 @@ class NewAlphabet extends FlxSprite {
if (isGraphicsShader)
shader.setCamSize(_frame.frame.x, _frame.frame.y, _frame.frame.width, _frame.frame.height);
setColorTransform(
__renderData.red * transformMult, __renderData.green * transformMult, __renderData.blue * transformMult, colorTransform.alphaMultiplier,
Math.round(__renderData.red * offsetMult), Math.round(__renderData.green * offsetMult), Math.round(__renderData.blue * offsetMult), 0
);
super.drawComplex(camera);
frameOffset.y -= offsetY;
frameOffset.x -= offsetX;
frameOffset.x -= advance;
}
colorTransform.redMultiplier = ogRed;
colorTransform.greenMultiplier = ogGreen;
colorTransform.blueMultiplier = ogBlue;
}
frameOffset.set(ogOffX, ogOffY);
@@ -266,6 +296,7 @@ class NewAlphabet extends FlxSprite {
lineGap = Std.parseFloat(xml.get("lineGap")).getDefault(75.0);
fps = Std.parseFloat(xml.get("fps")).getDefault(24.0);
forceCase = xml.get("forceCasing").getDefault("none").toLowerCase();
transformMult = (xml.get("useColorOffsets") == "true") ? 0 : 1;
for (node in xml.elements()) {
switch (node.nodeName) {
@@ -0,0 +1,22 @@
package funkin.menus.ui.effects;
import flixel.util.FlxColor;
import funkin.menus.ui.effects.RegionEffect;
class ColorWaveEffect extends RegionEffect {
public var period:Float = 30;
public var color1:FlxColor;
public var color2:FlxColor;
public function new(color1:FlxColor, color2:FlxColor, ?period:Float = 30) {
super();
speed = 5;
this.color1 = color1;
this.color2 = color2;
this.period = period;
}
override function modify(index:Int, lineIndex:Int, renderData:AlphabetRenderData) {
renderData.color = FlxColor.interpolate(color1, color2, (-effectTime + lineIndex).positiveModulo(period) / period);
}
}
@@ -0,0 +1,73 @@
package funkin.menus.ui.effects;
import flixel.util.FlxColor;
class AlphabetRenderData {
public var parent:NewAlphabet;
public var letter:String;
public var offsetX:Float = 0;
public var offsetY:Float = 0;
public var color(get, set):FlxColor;
public var red:Float = 0;
public var green:Float = 0;
public var blue:Float = 0;
public function new(parent:NewAlphabet) {
this.parent = parent;
}
public function reset(parent:NewAlphabet, letter:String) {
this.parent = parent;
this.letter = letter;
offsetX = 0;
offsetY = 0;
color = 0xFFFFFFFF;
}
function get_color():FlxColor {
return FlxColor.fromRGBFloat(red, green, blue);
}
function set_color(value:FlxColor):FlxColor {
red = value.redFloat;
green = value.greenFloat;
blue = value.blueFloat;
return value;
}
}
class RegionEffect {
public var effectTime:Float = 0;
public var speed:Float = 1;
public var enabled:Bool = true;
public var regionMin:Array<Int> = [];
public var regionMax:Array<Int> = [];
public function new() {}
public function resetRegions() {
regionMin.splice(0, regionMin.length);
regionMax.splice(0, regionMax.length);
}
public function addRegion(min:Int, max:Int) {
regionMin.push(min);
regionMax.push(max);
}
public function willModify(index:Int, lineIndex:Int, renderData:AlphabetRenderData):Bool {
if (!enabled) return false;
if (regionMin.length == 0) regionMin.push(0);
if (regionMax.length == 0) regionMax.push(-1);
for (i in 0...Std.int(Math.min(regionMin.length, regionMax.length))) {
var min = (regionMin[i] < 0) ? renderData.parent.text.length - regionMin[i] : regionMin[i];
var max = (regionMax[i] < 0) ? renderData.parent.text.length - regionMax[i] : regionMax[i];
if (index >= min && index <= max)
return true;
}
return false;
}
public function modify(index:Int, lineIndex:Int, renderData:AlphabetRenderData):Void {}
}
@@ -0,0 +1,23 @@
package funkin.menus.ui.effects;
import funkin.menus.ui.effects.RegionEffect;
class ShakeEffect extends RegionEffect {
public var intensityX:Float = 2;
public var intensityY:Float = 2;
public function new(?x:Float = 2, ?y:Float = 2) {
super();
intensityX = x;
intensityY = y;
}
override function willModify(index:Int, lineIndex:Int, renderData:AlphabetRenderData) {
return (intensityX != 0 || intensityY != 0) && super.willModify(index, lineIndex, renderData);
}
override function modify(index:Int, lineIndex:Int, renderData:AlphabetRenderData):Void {
renderData.offsetX += FlxG.random.float(-intensityX, intensityX);
renderData.offsetY += FlxG.random.float(-intensityY, intensityY);
}
}
@@ -0,0 +1,26 @@
package funkin.menus.ui.effects;
import funkin.menus.ui.effects.RegionEffect;
class WaveEffect extends RegionEffect {
public var intensityX:Float = 0;
public var intensityY:Float = 5;
public var period:Float = 10;
public function new(?x:Float = 0, ?y:Float = 5, ?p:Float = 10) {
super();
speed = 3;
intensityX = x;
intensityY = y;
period = p;
}
override function willModify(index:Int, lineIndex:Int, renderData:AlphabetRenderData) {
return period != 0 && (intensityX != 0 || intensityY != 0) && super.willModify(index, lineIndex, renderData);
}
override function modify(index:Int, lineIndex:Int, renderData:AlphabetRenderData):Void {
renderData.offsetX += intensityX * Math.cos((effectTime + lineIndex) * Math.PI * 2 / period);
renderData.offsetY += intensityY * Math.sin((effectTime + lineIndex) * Math.PI * 2 / period);
}
}