тест тек
ста
Сообщений 1 страница 7 из 7
ПеревестиПоделиться32026-07-11 00:16:07
<ambient:0x5b6ee1,0.3>
<sun:0xffffff,0>
<fog:0x0a0a1a,100,1500>
ПеревестиПоделиться42026-07-11 00:19:43
<light:0xadd400,900,3><floorY:350><darkness:10,0.5,0xadd400,additive,Actor1_1>
Поделиться62026-07-21 01:40:56
/*:
* @plugindate 2023-10-27
* @target MZ
* @orderAfter Sprite_Base
*
* @param camHeight
* @text Высота камеры (Y)
* @desc Высота камеры над картой. Больше = выше.
* @type number
* @default 800
*
* @param camDistance
* @text Отдаление камеры (Z)
* @desc Смещение камеры назад (к низу экрана).
* @type number
* @default 400
*
* @param camLookZ
* @text Наклон взгляда (Z)
* @desc Куда смотрит камера. 0 = центр экрана. Положительное число опускает проекцию вниз, отрицательное - поднимает вверх.
* @type number
* @default 0
*
* @help
* Создает 3D сцену с перспективой под 2D интерфейсом.
* Скрывает 2D карту, оставляя интерфейс (диалоги, меню) видимым.
*/
(() => {
'use strict';
const params = PluginManager.parameters('ThreeJS_Overlay');
const camHeight = Number(params.camHeight || 800);
const camDistance = Number(params.camDistance || 400);
const camLookZ = Number(params.camLookZ || 0);
let renderer, scene, camera, mapGrid;
let playerMesh;
let eventMeshes = [];
let isInitialized = false;
// Переменные для текстуры PIXI
let threeBaseTexture;
let threeTexture;
function initThreeJS() {
if (isInitialized) return;
if (typeof THREE === 'undefined') {
console.error("THREE is not loaded!");
return;
}
// Холст НЕ добавляется в HTML документ (DOM). preserveDrawingBuffer нужен для PIXI.
renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(Graphics.width, Graphics.height);
renderer.setClearColor(0x000000, 1); // Черный непрозрачный фон
// Создаем текстуру PIXI из холста Three.js
threeBaseTexture = new PIXI.BaseTexture(renderer.domElement);
threeTexture = new PIXI.Texture(threeBaseTexture);
scene = new THREE.Scene();
const aspect = Graphics.width / Graphics.height;
camera = new THREE.PerspectiveCamera(45, aspect, 1, 5000);
isInitialized = true;
}
function create3DMapGrid() {
if (!isInitialized) return;
if (mapGrid) {
scene.remove(mapGrid);
mapGrid.geometry.dispose();
mapGrid.material.dispose();
}
if (playerMesh) {
scene.remove(playerMesh);
playerMesh.geometry.dispose();
playerMesh.material.dispose();
}
for (let mesh of eventMeshes) {
scene.remove(mesh);
mesh.geometry.dispose();
mesh.material.dispose();
}
eventMeshes = [];
const mapW = $dataMap.width;
const mapH = $dataMap.height;
const tileW = $gameMap.tileWidth();
const tileH = $gameMap.tileHeight();
const totalW = mapW * tileW;
const totalH = mapH * tileH;
const geometry = new THREE.PlaneGeometry(totalW, totalH, mapW, mapH);
geometry.rotateX(-Math.PI / 2);
geometry.translate(totalW / 2, 0, totalH / 2);
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
wireframe: true,
transparent: true,
opacity: 0.6
});
mapGrid = new THREE.Mesh(geometry, material);
scene.add(mapGrid);
const playerGeo = new THREE.BoxGeometry(32, 48, 32);
const playerMat = new THREE.MeshBasicMaterial({ color: 0x0000ff });
playerMesh = new THREE.Mesh(playerGeo, playerMat);
playerMesh.position.y = 24;
scene.add(playerMesh);
if ($dataMap.events) {
for (let i = 0; i < $dataMap.events.length; i++) {
const ev = $dataMap.events[i];
if (ev) {
const evGeo = new THREE.BoxGeometry(32, 48, 32);
const evMat = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const evMesh = new THREE.Mesh(evGeo, evMat);
evMesh.position.y = 24;
evMesh.userData.eventId = ev.id;
eventMeshes.push(evMesh);
scene.add(evMesh);
}
}
}
}
function updateThreeScene() {
if (!isInitialized || !mapGrid) return;
const tileW = $gameMap.tileWidth();
const tileH = $gameMap.tileHeight();
if (playerMesh && $gamePlayer) {
playerMesh.position.x = $gamePlayer._realX * tileW;
playerMesh.position.z = $gamePlayer._realY * tileH;
}
for (let mesh of eventMeshes) {
const event = $gameMap.event(mesh.userData.eventId);
if (event) {
mesh.position.x = event._realX * tileW;
mesh.position.z = event._realY * tileH;
mesh.visible = true;
} else {
mesh.visible = false;
}
}
const scrollX = $gameMap.displayX() * tileW;
const scrollY = $gameMap.displayY() * tileH;
const screenCenterX = scrollX + Graphics.width / 2;
const screenCenterY = scrollY + Graphics.height / 2;
camera.position.x = screenCenterX;
camera.position.y = camHeight;
camera.position.z = screenCenterY + camDistance;
camera.lookAt(screenCenterX, 0, screenCenterY + camLookZ);
renderer.render(scene, camera);
if (threeBaseTexture) {
threeBaseTexture.update();
}
}
// ===== ИНТЕГРАЦИЯ В RPG MAKER MZ =====
const _Scene_Map_create = Scene_Map.prototype.create;
Scene_Map.prototype.create = function() {
_Scene_Map_create.call(this);
initThreeJS();
if (threeTexture) {
this._threeSprite = new PIXI.Sprite(threeTexture);
this._threeSprite.width = Graphics.width;
this._threeSprite.height = Graphics.height;
this.addChildAt(this._threeSprite, 0); // Помещаем 3D на самый низ сцены
// ЗАЩИТА ТЕКСТУРЫ: Без этого MZ удалит threeTexture при выходе из карты,
// и при возврате из меню выдаст ошибку 'valid' of null.
const origDestroy = this._threeSprite.destroy.bind(this._threeSprite);
this._threeSprite.destroy = function(options) {
origDestroy({ children: true, texture: false, baseTexture: false });
};
}
};
const _Scene_Map_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function() {
_Scene_Map_start.call(this);
// ИСПРАВЛЕНИЕ МЕЛЬКАНИЯ: Жестко скрываем 2D карту при старте сцены
// Это срабатывает, когда мы возвращаемся из меню (Escape)
if (this._spriteset) {
this._spriteset.visible = false;
}
};
const _Scene_Map_onMapLoaded = Scene_Map.prototype.onMapLoaded;
Scene_Map.prototype.onMapLoaded = function() {
_Scene_Map_onMapLoaded.call(this);
if (isInitialized) {
create3DMapGrid();
}
};
const _Scene_Map_update = Scene_Map.prototype.update;
Scene_Map.prototype.update = function() {
_Scene_Map_update.call(this);
// Скрываем стандартные 2D тайлы каждый кадр
if (this._spriteset) {
this._spriteset.visible = false;
}
updateThreeScene();
};
})();



