Last active
December 27, 2024 05:52
-
-
Save shifterbit/c7ef035d1ae658dd27a6dc19b2e83f94 to your computer and use it in GitHub Desktop.
Fraymakers Text Generation Code
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
| 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