Saltearse al contenido

API para Desarrolladores

CinematicEngine ofrece una API modular y tipada en Java que permite a otros plugins reproducir cinemáticas por código, incorporar fábricas de pistas a medida, registrar curvas matemáticas de interpolación y generar secuencias dinámicas en memoria.


📦 Instalación de la Dependencia

Gradle (Kotlin DSL)

repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://repo.codemc.io/repository/maven-releases/")
}
dependencies {
compileOnly("com.darkbladedev:cinematic-core:1.0.0-SNAPSHOT")
compileOnly("com.darkbladedev:cinematic-runtime:1.0.0-SNAPSHOT")
compileOnly("com.darkbladedev:plugin-bootstrap:1.0.0-SNAPSHOT")
}

Descriptor de Plugin (paper-plugin.yml o plugin.yml)

depend:
- CinematicEngine
- packetevents

🎮 La Interfaz CinematicService

El punto principal de interacción con el motor es CinematicService:

import com.darkbladedev.cinematic.bootstrap.CinematicService;
import com.darkbladedev.cinematic.bootstrap.CinematicActionResult;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class QuestCutsceneManager {
private final CinematicService cinematicService;
public QuestCutsceneManager() {
// Obtener el proveedor de servicio registrado en Bukkit
this.cinematicService = Bukkit.getServicesManager().load(CinematicService.class);
}
public void triggerBossCutscene(Player player) {
CinematicActionResult result = cinematicService.play(player, "boss_intro");
switch (result) {
case SUCCESS -> player.sendMessage("¡Cinemática iniciada!");
case ALREADY_PLAYING -> player.sendMessage("¡Ya estás presenciando una cinemática!");
case SCENE_NOT_FOUND -> player.sendMessage("¡No se encontró la escena 'boss_intro'!");
default -> player.sendMessage("No se pudo iniciar la cinemática.");
}
}
public void abortCutscene(Player player) {
cinematicService.stop(player);
}
}

Códigos de Estado CinematicActionResult

ResultadoSignificado
SUCCESSLa acción solicitada se ejecutó exitosamente.
ALREADY_PLAYINGNo se puede iniciar; el jugador ya tiene una cinemática en curso.
NOT_PLAYINGNo se puede detener/pausar/reanudar; el jugador no está en cinemática.
SCENE_NOT_FOUNDLa escena solicitada no existe en el registro.
INVALID_STATEEl estado del jugador o del entorno no permite la reproducción.

🛠️ Registrar Tipos de Pistas Personalizadas

Es posible registrar factorías de pistas mediante TrackRegistry para soportar dinámicas propias del servidor, como subtítulos de diálogo, efectos en pantalla o cambios en la hora del mundo.

import com.darkbladedev.cinematic.dsl.registry.TrackRegistry;
import com.darkbladedev.cinematic.dsl.registry.TrackFactory;
import com.darkbladedev.cinematic.dsl.validator.TrackValidator;
import com.darkbladedev.cinematic.dsl.dto.TrackDTO;
import com.darkbladedev.cinematic.core.model.Track;
public class SubtitleTrackFactory implements TrackFactory {
@Override
public Track create(TrackDTO dto) {
// Interpretar los datos del DTO y retornar la instancia de Track
return new SubtitleTrack(dto.id(), dto.keyframes());
}
}
// Registro durante onLoad() u onEnable():
TrackRegistry trackRegistry = DefaultDslComponents.trackRegistry(interpolatorRegistry);
trackRegistry.register("subtitle", new SubtitleTrackFactory(), new SubtitleTrackValidator());

📐 Registrar Interpoladores Personalizados

Agrega curvas de aceleración propias (ej. rebotes elásticos o curvas Bézier complejas) mediante InterpolatorRegistry:

import com.darkbladedev.cinematic.dsl.mapper.InterpolatorRegistry;
import com.darkbladedev.cinematic.core.interpolation.Interpolator;
InterpolatorRegistry registry = InterpolatorRegistry.defaultRegistry();
// Registrar una curva de rebote descendente (bounce-out)
registry.register("bounce_out", new Interpolator() {
@Override
public double interpolate(double t) {
double n1 = 7.5625;
double d1 = 2.75;
if (t < 1 / d1) {
return n1 * t * t;
} else if (t < 2 / d1) {
return n1 * (t -= 1.5 / d1) * t + 0.75;
} else if (t < 2.5 / d1) {
return n1 * (t -= 2.25 / d1) * t + 0.9375;
} else {
return n1 * (t -= 2.625 / d1) * t + 0.984375;
}
}
});

Esta nueva curva queda inmediatamente disponible para cualquier escena YAML:

keyframes:
- tick: 40
interpolation: "bounce_out"

🧩 Construcción Dinámica de Escenas en Memoria

Las escenas también pueden ensamblarse completamente en Java sin emplear archivos YAML:

import com.darkbladedev.cinematic.core.model.Scene;
import com.darkbladedev.cinematic.camera.CameraTrack;
import com.darkbladedev.cinematic.camera.CameraFrame;
import com.darkbladedev.cinematic.camera.CameraPathMode;
import com.darkbladedev.cinematic.camera.targeting.FixedAnglesStrategy;
import com.darkbladedev.cinematic.core.interpolation.EaseInOutInterpolator;
import org.joml.Vector3d;
import java.util.List;
import java.util.Map;
List<CameraFrame> frames = List.of(
new CameraFrame(0, new Vector3d(0, 70, 0), 0f, 0f, 70f, EaseInOutInterpolator.INSTANCE),
new CameraFrame(100, new Vector3d(50, 80, 50), 90f, 15f, 85f, EaseInOutInterpolator.INSTANCE)
);
CameraTrack cameraTrack = new CameraTrack(
"main_cam",
frames,
CameraPathMode.SPLINE,
FixedAnglesStrategy.INSTANCE
);
Scene dynamicScene = new Scene(
"dynamic_intro",
100,
List.of(cameraTrack),
Map.of("author", "PluginAPI")
);