Here’s the code to apply to several layers, it’s been tested!
runtimeScene.setBackgroundColor(100,100,240);
// Liste des calques à traiter pour le culling
const layersToCull = ["", "layer1", "layer2"]; // Ajouter ici les noms des calques sur lesquels appliquer le culling
// Initialiser l'objet deletedObjects pour chaque calque si nécessaire
if (!runtimeScene.deletedObjects) {
runtimeScene.deletedObjects = {};
}
// Obtenir la valeur de la variable CullBuffer une seule fois
const cullBuffer = runtimeScene.getVariables().get("CullBuffer").getAsNumber();
// Processus de culling pour chaque calque
layersToCull.forEach(layerName => {
// Initialiser deletedObjects pour le calque courant
if (!runtimeScene.deletedObjects[layerName]) {
runtimeScene.deletedObjects[layerName] = {};
}
// Obtenir la position de la caméra et la taille du calque actuel
const cameraLayer = runtimeScene.getLayer(layerName);
const cameraX = cameraLayer.getCameraX();
const cameraY = cameraLayer.getCameraY();
const cameraWidth = cameraLayer.getCameraWidth();
const cameraHeight = cameraLayer.getCameraHeight();
// Calculer les limites de culling basées sur CullBuffer
const leftBoundary = cameraX - cameraWidth / 2 - cullBuffer;
const rightBoundary = cameraX + cameraWidth / 2 + cullBuffer;
const topBoundary = cameraY - cameraHeight / 2 - cullBuffer;
const bottomBoundary = cameraY + cameraHeight / 2 + cullBuffer;
// Récupérer tous les objets de la scène
const allObjectsInstances = runtimeScene.getAdhocListOfAllInstances();
// Créer des tableaux pour stocker les objets à supprimer et recréer
const objectsToDelete = [];
const objectsToStoreAndDelete = [];
// Limiter le nombre d'objets traités par frame pour éviter les pics d'usage CPU
const maxObjectsPerFrame = 50; // Ajustez cette valeur pour optimiser les performances
const startIndex = runtimeScene.getVariables().has("CullStartIndex_" + layerName)
? runtimeScene.getVariables().get("CullStartIndex_" + layerName).getAsNumber()
: 0;
const endIndex = Math.min(startIndex + maxObjectsPerFrame, allObjectsInstances.length);
runtimeScene.getVariables().get("CullStartIndex_" + layerName).setNumber(endIndex === allObjectsInstances.length ? 0 : endIndex);
// Obtenir le temps actuel de la scène pour les objets restaurés
const currentTime = runtimeScene.getTimeManager().getTimeFromStart() / 1000;
// Parcourir les objets du sous-ensemble sélectionné
for (let i = startIndex; i < endIndex; i++) {
const object = allObjectsInstances[i];
const objectName = object.getName();
const objectLayer = object.getLayer();
// Ne traiter que les objets du calque en cours
if (objectLayer !== layerName) continue;
const variables = object.getVariables();
// Vérifier si l'objet a une variable "ExcludeCull" définie à true
if (variables.has("ExcludeCull") && variables.get("ExcludeCull").getAsBoolean()) {
continue; // Exclure cet objet du culling
}
// Obtenir la boîte englobante de l'objet
const aabb = object.getAABB();
const objectLeft = aabb.min[0];
const objectRight = aabb.max[0];
const objectTop = aabb.min[1];
const objectBottom = aabb.max[1];
// Vérifier si l'objet est en dehors des limites du culling
if (objectRight < leftBoundary || objectLeft > rightBoundary || objectBottom < topBoundary || objectTop > bottomBoundary) {
// Vérifier si l'objet a une variable "Cull" définie à true
if (variables.has("Cull") && variables.get("Cull").getAsBoolean()) {
objectsToDelete.push(object); // Ajouter l'objet pour suppression immédiate
} else {
// Stocker les propriétés de l'objet pour recréation future
if (!runtimeScene.deletedObjects[layerName][objectName]) {
runtimeScene.deletedObjects[layerName][objectName] = [];
}
const objectProperties = {
x: object.getX(),
y: object.getY(),
zOrder: object.getZOrder(),
angle: object.getAngle(),
layer: objectLayer,
hidden: object.isHidden(),
variables: {},
timers: {},
cullTime: currentTime
};
// Enregistrer les variables de l'objet
const objectVariablesList = variables._variables.items;
for (const variableName in objectVariablesList) {
if (objectVariablesList.hasOwnProperty(variableName)) {
objectProperties.variables[variableName] = objectVariablesList[variableName].getAsString();
}
}
// Enregistrer les propriétés optionnelles
if (object.getWidth) objectProperties.width = object.getWidth();
if (object.getHeight) objectProperties.height = object.getHeight();
if (object.getOpacity) objectProperties.opacity = object.getOpacity();
// Enregistrer les timers de l'objet
if (object._timers && object._timers.items) {
const timerItems = object._timers.items;
for (const timerName in timerItems) {
if (timerItems.hasOwnProperty(timerName)) {
objectProperties.timers[timerName] = timerItems[timerName].getTime() / 1000.0;
}
}
}
runtimeScene.deletedObjects[layerName][objectName].push(objectProperties);
objectsToStoreAndDelete.push(object);
}
}
}
// Supprimer les objets complètement hors champ
objectsToDelete.forEach(obj => obj.deleteFromScene(runtimeScene));
objectsToStoreAndDelete.forEach(obj => obj.deleteFromScene(runtimeScene));
// Récupérer le temps actuel de la scène pour restaurer les objets
const restoreTime = runtimeScene.getTimeManager().getTimeFromStart() / 1000;
// Recréer les objets dans les limites
const deletedObjects = runtimeScene.deletedObjects[layerName];
for (let objectName in deletedObjects) {
const objectList = deletedObjects[objectName];
for (let i = objectList.length - 1; i >= 0; i--) {
const data = objectList[i];
const objectLeft = data.x;
const objectRight = data.x + (data.width || 0);
const objectTop = data.y;
const objectBottom = data.y + (data.height || 0);
// Vérifier si la position est dans les limites de recréation
if (objectRight >= leftBoundary && objectLeft <= rightBoundary && objectBottom >= topBoundary && objectTop <= bottomBoundary) {
const elapsedTime = restoreTime - data.cullTime;
// Recréer l'objet
const newObject = runtimeScene.createObject(objectName);
newObject.setPosition(data.x, data.y);
newObject.setZOrder(data.zOrder);
newObject.setAngle(data.angle);
newObject.setLayer(data.layer);
if (data.width !== undefined && newObject.setWidth) newObject.setWidth(data.width);
if (data.height !== undefined && newObject.setHeight) newObject.setHeight(data.height);
if (data.opacity !== undefined && newObject.setOpacity) newObject.setOpacity(data.opacity);
if (data.hidden !== undefined) newObject.hide(data.hidden);
const targetVariables = newObject.getVariables();
const sourceVariables = data.variables;
for (const variableName in sourceVariables) {
if (sourceVariables.hasOwnProperty(variableName)) {
targetVariables.get(variableName).setString(sourceVariables[variableName]);
}
}
const objectTimers = data.timers;
for (const timerName in objectTimers) {
const timerValue = objectTimers[timerName];
newObject.resetTimer(timerName);
newObject._timers.get(timerName).setTime((timerValue + elapsedTime) * 1000);
}
objectList.splice(i, 1);
}
}
}
for (let objectName in deletedObjects) {
if (deletedObjects[objectName].length === 0) {
delete deletedObjects[objectName];
}
}
});