Created
May 21, 2020 16:20
-
-
Save kobaltcore/2d2d913e513d25f02f4800e41fbbee8d to your computer and use it in GitHub Desktop.
Experiments in Ren'Py heresy.
This file contains 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
label start: | |
"This is the {wiggle}wiggle effect{/wiggle}." | |
"This is the {nearest}nearest effect{/nearest}." | |
"This is the {fire}fire effect{/fire}." |
This file contains 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
init python: | |
import math | |
import random | |
import pygame | |
class Appearing(renpy.Displayable): | |
def __init__(self, text, opaque_distance, transparent_distance, **kwargs): | |
super(Appearing, self).__init__(**kwargs) | |
self.text = Text(text) | |
self.opaque_distance = opaque_distance | |
self.transparent_distance = transparent_distance | |
self.alpha = 0.0 | |
self.width = 0 | |
self.height = 0 | |
def render(self, width, height, st, at): | |
t = Transform(child=self.text, alpha=self.alpha) | |
child_render = renpy.render(t, width, height, st, at) | |
self.width, self.height = child_render.get_size() | |
render = renpy.Render(self.width * 0.98, self.height) | |
render.blit(child_render, (0, -(self.height * 0.1))) | |
return render | |
def event(self, ev, x, y, st): | |
distance = math.hypot(x, y - (self.height / 2)) | |
if distance <= self.opaque_distance: | |
alpha = 1.0 | |
elif distance >= self.transparent_distance: | |
alpha = 0.0 | |
else: | |
alpha = 1.0 - 1.0 * (distance - self.opaque_distance) / (self.transparent_distance - self.opaque_distance) | |
if alpha != self.alpha: | |
self.alpha = alpha | |
renpy.redraw(self, 0) | |
return self.text.event(ev, x, y, st) | |
def visit(self): | |
return [self.text] | |
class Wiggle(renpy.Displayable): | |
def __init__(self, text, **kwargs): | |
super(Wiggle, self).__init__(**kwargs) | |
self.text = Text(text) | |
self.chars = [Text(char) for char in text] | |
self.t = 0 | |
self.radius = 3 | |
self.speed = -0.3 | |
self.frequency = 5 | |
self.spread_x = 1.5 | |
def render(self, width, height, st, at): | |
width, height = self.text.size() | |
x0, y0 = 0, -(height * 0.15) | |
render = renpy.Render(width + (width * 0.15), height) | |
for i, char in enumerate(self.chars): | |
child_render = char.render(width, height, st, at) | |
dx = self.radius * math.cos(self.t / self.frequency + self.speed * i) * self.spread_x | |
dy = self.radius * math.sin(self.t / self.frequency + self.speed * i) | |
render.blit(child_render, (x0 + dx, y0 + dy)) | |
x0 += child_render.get_size()[0] | |
self.t += 1 | |
renpy.redraw(self, 0) | |
return render | |
def visit(self): | |
return self.chars | |
class Fire(renpy.Displayable): | |
def __init__(self, text, **kwargs): | |
super(Fire, self).__init__(**kwargs) | |
self.text = Text(text) | |
self.width, self.height = map(int, self.text.size()) | |
"""generate palette to draw intermediate fire""" | |
self.fire = [[0 for _ in range(self.height)] for _ in range(self.width)] | |
# generate palette | |
self.palette = [0 for _ in range(255)] | |
# palette should be something from black to yellow red | |
self.palette[0] = pygame.Color(0, 0, 0, 255) | |
for index in range(1, 255): | |
color = pygame.Color(0, 0, 0, 255) | |
# original C Comments | |
# Hue goes from 0 to 85: red to yellow | |
# Saturation is always the maximum: 255 | |
# Lightness is 0..100 for x=0..128, and 255 for x=128..255 | |
# color = HSLtoRGB(ColorHSL(x / 3, 255, std::min(255, x * 2))); | |
color.hsla = (index, 100, index / 1.2, 255) | |
self.palette[index] = color | |
def render(self, width, height, st, at): | |
render = renpy.Render(self.width, self.height) | |
text_render = self.text.render(self.width, self.height, st, at) | |
render.blit(text_render, (0, -(self.height * 0.1))) | |
array2d = render.canvas().get_surface() | |
"""update every frame""" | |
# random baseline | |
for x in range(self.width): | |
self.fire[x][self.height - 9] = abs(32768 + random.randint(0, 32768)) % 256 | |
# calculate each pixel according to neighbours | |
for y in range(self.height - 8): | |
for x in range(self.width): | |
# every new point depends on O Points | |
# N | |
# OOO | |
# O | |
self.fire[x][y] = \ | |
((self.fire[(x - 1) % self.width][(y + 1) % self.height] \ | |
+ self.fire[(x) % self.width][(y + 2) % self.height] \ | |
+ self.fire[(x + 1) % self.width][(y + 1) % self.height] \ | |
+ self.fire[(x) % self.width][(y + 3) % self.height]) \ | |
* 16) / 65 | |
# the last factor 16/65 should be slightly larger than 4 | |
# and lesser than 5 | |
# closer to 4 will make flames higher | |
array2d.set_at((x, y), self.palette[int(self.fire[x][y])]) | |
# render.blit(text_render, (0, -(self.height * 0.1))) | |
renpy.redraw(self, 0) | |
return render | |
def visit(self): | |
return [self.text] | |
def wiggle_tag(tag, argument, contents): | |
return [(renpy.TEXT_DISPLAYABLE, Wiggle(contents[0][1]))] | |
config.custom_text_tags["wiggle"] = wiggle_tag | |
def nearest_tag(tag, argument, contents): | |
if "(" in argument: | |
argument = eval(argument) | |
opaque_distance, transparent_distance = argument[0], argument[1] | |
elif not argument: | |
opaque_distance, transparent_distance = 100, 200 | |
return [(renpy.TEXT_DISPLAYABLE, Appearing(contents[0][1], opaque_distance, transparent_distance))] | |
config.custom_text_tags["nearest"] = nearest_tag | |
def fire_tag(tag, argument, contents): | |
return [(renpy.TEXT_DISPLAYABLE, Fire(contents[0][1]))] | |
config.custom_text_tags["fire"] = fire_tag |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment