Completed basic effect functions (object oriented)

This commit is contained in:
loplkc loplkc 2022-01-20 14:15:42 -05:00
parent d1680bf63c
commit 47bde9f3ce
4 changed files with 430 additions and 381 deletions

View file

@ -3,3 +3,5 @@
The highly unfinished skeleton of an ambitious Roblox game. The highly unfinished skeleton of an ambitious Roblox game.
This is a Rojo project that uses Roblox-ts. You can compile it and play it yourself if you have Rojo and Roblox-ts installed. However, I cannot guarantee that it will actually work. This is a Rojo project that uses Roblox-ts. You can compile it and play it yourself if you have Rojo and Roblox-ts installed. However, I cannot guarantee that it will actually work.
(Remember to use `npm up` before attempting to edit or compile.)

635
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,77 +1,109 @@
const TweenService = game.GetService("TweenService"); const TweenService = game.GetService("TweenService");
type effectKeypoint = [number, Color3, Vector3, CFrame, number, Enum.EasingStyle?, Enum.EasingDirection?]; type effectKeypoint = [number, Color3, Vector3, CFrame, number, Enum.EasingStyle?, Enum.EasingDirection?];
type effect = [number, effectKeypoint[], MeshPart, number] // Time since last keypoint, effect keypoints, effect meshPart, effect priority
export function meshPartEffect( export interface effectMaker {
effectFolder: Folder, meshPartEffect: (
meshPart: MeshPart, meshPart: MeshPart,
material: Enum.Material, material: Enum.Material,
effectKeypoints: effectKeypoint[], effectKeypoints: effectKeypoint[],
) { priority?: number,
const effectMeshPart = meshPart.Clone(); ) => void;
effectMeshPart.Material = material; particleEffect: () => void;
effectMeshPart.Color = effectKeypoints[0][1];
effectMeshPart.Size = effectKeypoints[0][2];
effectMeshPart.CFrame = effectKeypoints[0][3];
effectMeshPart.Transparency = effectKeypoints[0][4];
effectMeshPart.CastShadow = false;
effectMeshPart.CanCollide = false;
effectMeshPart.Anchored = true;
effectMeshPart.Parent = effectFolder;
effectKeypoints.remove(0);
return [effectMeshPart, effectKeypoints, 0] as [MeshPart, effectKeypoint[], number];
// Do the interpolation on one thread somehow
} }
function particleEffect() {} export interface effectRunner {
/* runEffects: (
function getLerpKeypoint(time: number, pastKeypoint: effectKeypoint, futureKeypoint: effectKeypoint) { timeSinceLastFrame: number
let alpha = 0; ) => void;//(timeSinceLastFrame: number, effectsToRun: effect[]) => effect[]
if (pastKeypoint[5]) {
alpha = TweenService.GetValue(time / futureKeypoint[0], pastKeypoint[5], Enum.EasingDirection.InOut);
} else {
alpha = time;
}
let new
for (let i = 1; i < 5; i += 1) {
}
} }
*/
function runEffects(timeSinceLastFrame: number, effectsToRun: [MeshPart, effectKeypoint[], number][]) { interface effectHandler extends effectMaker, effectRunner {
for (const effect of effectsToRun) { EFFECT_FOLDER: Folder;
const meshPart = effect[0]; effectsToRun: effect[]
const futureKeypoint = effect[1][1]; }
const timeToNext = futureKeypoint[0];
const timeSinceLastKeypoint = effect[2] + timeSinceLastFrame; export function makeEffectHandler(effectFolder: Folder) {
if (timeSinceLastKeypoint >= timeToNext) { const effectHandler: effectHandler = {
// Remove keypoint meshPartEffect: function(meshPart: MeshPart, material: Enum.Material, effectKeypoints: effectKeypoint[], priority?: number) {
// Set effect[3] to 0 const effectMeshPart = meshPart.Clone();
// Delete effect if no keypoints left effectMeshPart.Material = material;
} else { effectMeshPart.Color = effectKeypoints[0][1];
effect[2] = timeSinceLastKeypoint; effectMeshPart.Size = effectKeypoints[0][2];
} effectMeshPart.CFrame = effectKeypoints[0][3];
const pastKeypoint = effect[1][0]; effectMeshPart.Transparency = effectKeypoints[0][4];
const easingStyle = pastKeypoint[5]; let effectDuration = 0
// Get the alpha effectKeypoints.forEach(effectKeypoint => {
let alpha = 0; effectDuration += effectKeypoint[0]
if (easingStyle) { });
alpha = TweenService.GetValue( effectMeshPart.CastShadow = false;
timeSinceLastKeypoint / timeToNext, effectMeshPart.CanCollide = false;
easingStyle, effectMeshPart.Anchored = true;
pastKeypoint[6] || Enum.EasingDirection.InOut, effectMeshPart.Parent = this.EFFECT_FOLDER;
); // Insert the effect before the effect that will end after it
} else { const effectsToRun = this.effectsToRun
alpha = timeSinceLastKeypoint / timeToNext; for (let index = 0; index < effectsToRun.size(); index += 1) {
} const effectInArray = effectsToRun[index];
// Alter the effect let effectInArrayDuration = -effectInArray[0]
meshPart.Color = pastKeypoint[1].Lerp(futureKeypoint[1], alpha); effectInArray[1].forEach(effectKeypoint => {
meshPart.Position = pastKeypoint[2].Lerp(futureKeypoint[2], alpha); effectInArrayDuration += effectKeypoint[0]
meshPart.CFrame = pastKeypoint[3].Lerp(futureKeypoint[3], alpha); });
meshPart.Transparency = pastKeypoint[4] + (futureKeypoint[4] - pastKeypoint[4]) * alpha; if (effectInArrayDuration > effectDuration) {
effectsToRun.insert(index, [0, effectKeypoints, effectMeshPart, priority || 0] as effect);
break
}
}
effectsToRun.insert(effectsToRun.size(), [0, effectKeypoints, effectMeshPart, priority || 0] as effect);
},
particleEffect: function() {},
runEffects: function(timeSinceLastFrame: number) {
let effectsToRun = this.effectsToRun
for (const effect of effectsToRun) {
// Update the effect time
let nextKeypoint = effect[1][1];
let timeOfNextKeypoint = nextKeypoint[0];
let timeSinceLastKeypoint = effect[0] + timeSinceLastFrame;
while (timeSinceLastKeypoint >= timeOfNextKeypoint) {
if (effect[1][2]) {
timeSinceLastKeypoint -= timeOfNextKeypoint;
effect[1].remove(0);
nextKeypoint = effect[1][1];
timeOfNextKeypoint = nextKeypoint[0];
} else {
effect[2].Destroy()
effectsToRun.remove(0)
continue // Move on if this effect is done
}
}
effect[0] = timeSinceLastKeypoint;
// Get the rest of the variables
const currentKeypoint = effect[1][0];
const easingStyle = currentKeypoint[5];
const meshPart = effect[2];
// Get the alpha
let alpha = 0;
if (easingStyle) {
alpha = TweenService.GetValue(
timeSinceLastKeypoint / timeOfNextKeypoint,
easingStyle,
currentKeypoint[6] || Enum.EasingDirection.InOut,
);
} else {
alpha = timeSinceLastKeypoint / timeOfNextKeypoint;
}
// Alter the effect
meshPart.Color = currentKeypoint[1].Lerp(nextKeypoint[1], alpha);
meshPart.Position = currentKeypoint[2].Lerp(nextKeypoint[2], alpha);
meshPart.CFrame = currentKeypoint[3].Lerp(nextKeypoint[3], alpha);
meshPart.Transparency = currentKeypoint[4] + (nextKeypoint[4] - currentKeypoint[4]) * alpha;
}
//this = effectsToRun;
},
EFFECT_FOLDER: effectFolder,
effectsToRun: [],
} }
return effectHandler;
} }
/* /*
local function horseEffModule(o,typ,a1,a2,a3,a4,a5,a6,a7) local function horseEffModule(o,typ,a1,a2,a3,a4,a5,a6,a7)

View file

@ -1,9 +1,11 @@
// "init": The local script. This script doesn't have to account for any other players. // "init": The local script. This script doesn't have to account for any other players.
const Players = game.GetService("Players"); const Players = game.GetService("Players");
const UserInputService = game.GetService("UserInputService"); const UserInputService = game.GetService("UserInputService");
const RunService = game.GetService("RunService");
const Workspace = game.GetService("Workspace"); const Workspace = game.GetService("Workspace");
import { bindToOutput, messageServer } from "./ClientMessenger"; import { bindToOutput, messageServer } from "./ClientMessenger";
import { handleGuiInput, drawGui, closeGui } from "./GuiHandler"; import { handleGuiInput, drawGui, closeGui } from "./GuiHandler";
import { makeEffectHandler, effectRunner } from "./EffectMaker";
const LOCALPLAYER = Players.LocalPlayer; const LOCALPLAYER = Players.LocalPlayer;
const PLAYERGUI = LOCALPLAYER.WaitForChild("PlayerGui", 1) as PlayerGui; const PLAYERGUI = LOCALPLAYER.WaitForChild("PlayerGui", 1) as PlayerGui;
assert( assert(
@ -58,3 +60,11 @@ function handleOutput(messageType: unknown, messageContent: unknown) {
// Action phase // Action phase
UserInputService.InputBegan.Connect(handleInput); UserInputService.InputBegan.Connect(handleInput);
bindToOutput(handleOutput); bindToOutput(handleOutput);
const effectRunners: effectRunner[] = [];
// Put stuff in the effectRunners table
RunService.RenderStepped.Connect(function(deltaTime) {
effectRunners.forEach(effectRunner => {
effectRunner.runEffects(deltaTime)
});
})