Skip to content

Instantly share code, notes, and snippets.

@shifterbit
Last active December 27, 2024 05:52
Show Gist options
  • Select an option

  • Save shifterbit/c7ef035d1ae658dd27a6dc19b2e83f94 to your computer and use it in GitHub Desktop.

Select an option

Save shifterbit/c7ef035d1ae658dd27a6dc19b2e83f94 to your computer and use it in GitHub Desktop.
Fraymakers Text Generation Code
function createColorShader(color) {
var shader = new RgbaColorShader();
shader.color = color;
shader.redMultiplier = 1 / 3;
shader.greenMultiplier = 1 / 2;
shader.blueMultiplier = 1;
return shader;
}
function disposeSprites(textSprites: Array<Sprite>) {
Engine.forEach(textSprites, function (sprite: Sprite, idx: Int) {
sprite.dispose();
return true;
}, []);
textSprites = [];
}
function createSpriteFromCharacter(char: String): Sprite {
var res = getContent("text");
var lowerCase = "abcdefghijklmnopqrstuvwxyz";
var upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var digits = "0123456789";
var symbols = "!\"#$%&'()*+,-./;<=>?@:[\\]^_`{|}~ ";
var lowerCaseIndex = lowerCase.indexOf(char);
var upperCaseIndex = upperCase.indexOf(char);
var digitIndex = digits.indexOf(char);
var symbolIndex = symbols.indexOf(char);
var isDigit = digitIndex >= 0;
var isLowerCase = lowerCaseIndex >= 0;
var isUpperCase = upperCaseIndex >= 0;
var isSymbol = symbolIndex >= 0;
var sprite: Sprite = Sprite.create(res);
if (isDigit) {
sprite.currentAnimation = "digits";
sprite.currentFrame = digitIndex + 1;
} else if (isSymbol) {
sprite.currentAnimation = "symbols";
sprite.currentFrame = symbolIndex + 1;
} else if (isLowerCase) {
sprite.currentAnimation = "lowercase";
sprite.currentFrame = lowerCaseIndex + 1;
} else if (isUpperCase) {
sprite.currentAnimation = "uppercase";
sprite.currentFrame = upperCaseIndex + 1;
} else {
sprite.currentAnimation = "symbols";
sprite.currentFrame = symbols.length - 1;
}
return sprite;
}
function parseHexCode(hex: String): Int {
var total: Int = 0;
hex = hex.toUpperCase();
var digits = "0123456789ABCDEF";
var numPart = hex.substr(1);
var idx = 0;
while (idx < numPart.length) {
var power = numPart.length - idx - 1;
var num = digits.indexOf(numPart.charAt(idx));
total += Math.round(num * Math.pow(16, power));
idx++;
}
return total;
}
function syntaxError(text: String, curr: Int): { text: String, color: Int, error: Bool, length: Int } {
var errorMessage: String = [
"Error Rendering Text: \nUnexpected character ",
("\"" + text.charAt(curr) + "\""),
"\nat character position ", curr.toString()].join("");
Engine.log(errorMessage, 0xFFC300);
return {
error: true,
color: 0xFF0000,
text: errorMessage
};
}
function parseTag(text: String, curr: Int): { text: String, color: Int, error: Bool, length: Int } {
var color = 0;
var content = "";
if ("<" == text.charAt(curr)) { curr++; } else { return syntaxError(text, curr); }
while (text.charAt(curr) == " ") { curr++; }
if (text.charAt(curr) == "#") {
var hexString = "#";
var nums = "0123456789ABCDEFabcdef";
curr++;
while (nums.indexOf(text.charAt(curr)) >= 0) {
hexString += text.charAt(curr);
curr++;
}
color = parseHexCode(hexString);
} else { return syntaxError(text, curr); }
while (text.charAt(curr) == " ") { curr++; }
if (text.charAt(curr) == ">") { curr++; } else { return syntaxError(text, curr); }
while (text.charAt(curr) != "<") {
if (text.charAt(curr) == "\\" && curr + 2 < text.length) {
content += text.charAt(curr + 1);
curr += 2;
} else {
content += text.charAt(curr);
curr++;
}
}
if (text.charAt(curr) == "<") { curr++; } else { return syntaxError(text, curr); };
if (text.charAt(curr) == "/") { curr++; } else { return syntaxError(text, curr); };
if (text.charAt(curr) == ">") { curr++; } else { return syntaxError(text, curr); };
return { color: color, text: content, length: curr };
}
function parseText(text: String): Array<{ text: String, color: Int, error: Bool, length: Int }> {
var nodes: Array<{ text: String, color: Int, error: Bool, length: Int }> = [];
var curr = 0;
var nodeIdx = 0;
while (curr < text.length) {
if (nodes[nodeIdx] == null) {
nodes[nodeIdx] = {
text: "",
color: 0xFFFFFF,
length: 0,
error: false
};
}
switch (text.charAt(curr)) {
case "\\": {
if (curr + 2 < text.length) {
nodes[nodeIdx].text += text.charAt(curr + 1);
nodes[nodeIdx].length += 1;
curr += 2;
} else {
nodes.push(syntaxError(text, curr));
break;
}
};
case "<": {
nodeIdx++;
var result = parseTag(text, curr);
if (!result.error) {
curr = result.length;
nodes[nodeIdx] = result;
nodes[nodeIdx].color = result.color;
nodeIdx++;
} else {
nodes[nodeIdx] = result;
break;
}
};
default: {
nodes[nodeIdx].text += text.charAt(curr);
nodes[nodeIdx].length += 1;
curr++;
};
}
}
return nodes;
}
function renderText(
text: String,
sprites: Array<Sprite>,
container: Container,
options: { autoLinewrap: Int, delay: Int, x: Int, y: Int, owner: Entity }
): { duration: Int, sprites: Array<Sprite> } {
var parsed: Array<{ text: String, color: Float, error: Boolean, length: number }> = parseText(text);
disposeSprites(sprites);
sprites = [];
var line = 0;
var col = 0;
function makeSprite(char: String, shaderOptions: { color: Int }) {
if (options != null && options.autoLinewrap > 0 && options.autoLinewrap < col && !options.wordWrap) {
col = 0;
line++;
}
var sprite: Sprite = createSpriteFromCharacter(char);
sprite.x = col * 6;
if (options != null && options.x != null) {
sprite.x += options.x;
}
sprite.y = line * 10;
if (options != null && options.y != null) {
sprite.y += options.y;
}
var shader: RgbaColorShader = createColorShader(shaderOptions.color);
sprite.addShader(shader);
return sprite;
}
Engine.forEach(parsed, function (node: {
text: String, color: Int, error: Boolean, length: number
}, _: Int) {
Engine.forCount(node.text.length, function (idx: Int) {
var char: String = node.text.charAt(idx);
if (char == "\n") {
line++;
col = 0;
} else {
var sprite = makeSprite(char, { color: node.color });
sprites.push(sprite);
col++;
}
return true;
}, []);
return true;
}, []);
var owner = self;
if (options.owner != null) {
owner = options.owner;
}
if (options.delay != null && options.delay > 0) {
Engine.forEach(sprites, function (sprite: Sprite, idx: Int) {
owner.addTimer(idx * options.delay, 1, function () {
container.addChild(sprite);
}, { persistent: true });
return true;
}, []);
return { sprites: sprites, duration: sprites.length * options.delay };
} else {
Engine.forEach(sprites, function (sprite: Sprite, _idx: Int) {
container.addChild(sprite);
return true;
}, []);
return { sprites: sprites, duration: -1 };
}
}
function renderLines(lines: Array<String>,
sprites: Array<Sprite>,
container: Container,
options: { delay: Int, x: Int, y: Int }): { duration: Int, sprites: Array<Sprite>, owner: Entity } {
var renderData = renderText(lines.join("\n"), sprites, container, { autoLinewrap: false, delay: delay, x: options.x, y: options.y, owner: options.owner });
return renderData;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment