fix(studio): NPC-киты (robot→character-a), дверь по коду плавно распахивается
1) NPC-преследователь/торговец/волна: spawnNpc('robot') → 'character-a'
(модели 'robot' не существует в ModelTypes → spawnNpc возвращал null → ошибка).
2) Дверь по коду: верный код → ПЛАВНОЕ открытие вокруг петли (как дверь по E),
декор-панели вращаются вместе с полотном. Раньше полотно уезжало вниз,
декор оставался.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3bf1e77230
commit
fe8b6b5b38
@ -591,38 +591,49 @@ game.hud.setHpVisible(false);` }],
|
|||||||
{ type: 'cube', x: 0, y: 4.1, z: 0, sx: 0.4, sy: 0.4, sz: 3.5, color: '#3a4250', material: 'metal', name: 'Перемычка' },
|
{ type: 'cube', x: 0, y: 4.1, z: 0, sx: 0.4, sy: 0.4, sz: 3.5, color: '#3a4250', material: 'metal', name: 'Перемычка' },
|
||||||
],
|
],
|
||||||
scripts: [{ attachTo: 'on-target', code:
|
scripts: [{ attachTo: 'on-target', code:
|
||||||
`// Дверь по коду 1234. Поле ввода появляется ТОЛЬКО когда игрок рядом.
|
`// Дверь по коду 1234. Поле ввода появляется ТОЛЬКО рядом. Верный код →
|
||||||
|
// дверь ПЛАВНО распахивается вокруг петли (вместе с панелями).
|
||||||
const CODE = '1234';
|
const CODE = '1234';
|
||||||
const p0 = game.self.position;
|
const p0 = game.self.position;
|
||||||
|
const halfW = 1.3; // полуширина полотна (sz=2.6)
|
||||||
|
const hingeX = p0.x, hingeZ = p0.z - halfW;
|
||||||
const RADIUS = 6;
|
const RADIUS = 6;
|
||||||
let opened = false, near = false, inp = null;
|
let opened = false, near = false, cur = 0, target = 0;
|
||||||
game.ui.set('codehint', '', {});
|
const SPEED = Math.PI; // ~0.5с на 90°
|
||||||
game.onTick(() => {
|
|
||||||
if (opened) return;
|
// Декор полотна — двигается вместе с дверью.
|
||||||
const pl = game.player.position;
|
const decorNames = ['Панель двери', 'Панель двери низ', 'Кодовая панель'];
|
||||||
const dx = pl.x - p0.x, dz = pl.z - p0.z;
|
const decor = [];
|
||||||
const d = Math.sqrt(dx*dx + dz*dz);
|
for (const nm of decorNames) {
|
||||||
if (d < RADIUS && !near) {
|
const o = game.scene.findOne(nm);
|
||||||
near = true;
|
if (o && o.position) decor.push({ obj:o, dx:o.position.x-p0.x, dy:o.position.y-p0.y, dz:o.position.z-p0.z });
|
||||||
inp = game.gui.create('textbox', { id:'codein', x:50, y:86, w:24, h:8, anchor:'center', placeholder:'Код...', textSize:20 });
|
|
||||||
game.ui.set('codehint', '🔢 Введи код двери и нажми Enter', {x:50,y:78,anchor:'bottom',color:'#fff',size:16});
|
|
||||||
} else if (d >= RADIUS && near) {
|
|
||||||
near = false;
|
|
||||||
if (inp) game.gui.remove('codein');
|
|
||||||
game.ui.set('codehint', '', {});
|
|
||||||
}
|
}
|
||||||
|
function rotY(lx, lz, a){ const s=Math.sin(a),c=Math.cos(a); return { x: lx*c+lz*s, z: -lx*s+lz*c }; }
|
||||||
|
function place(a){
|
||||||
|
const pc = rotY(0, halfW, a);
|
||||||
|
const cx = hingeX + pc.x, cz = hingeZ + pc.z;
|
||||||
|
game.self.move(cx, p0.y, cz); game.self.rotate(a);
|
||||||
|
for (const d of decor){ const r = rotY(d.dx, d.dz, a); d.obj.move(cx+r.x, p0.y+d.dy, cz+r.z); if (d.obj.rotate) d.obj.rotate(a); }
|
||||||
|
}
|
||||||
|
game.onTick((dt) => {
|
||||||
|
if (cur !== target){ const st=SPEED*dt; cur = Math.abs(target-cur)<=st ? target : cur+Math.sign(target-cur)*st; place(cur); }
|
||||||
|
if (opened) return;
|
||||||
|
// Поле ввода появляется/прячется по дистанции.
|
||||||
|
const pl = game.player.position;
|
||||||
|
const d = Math.sqrt((pl.x-p0.x)**2 + (pl.z-p0.z)**2);
|
||||||
|
if (d < RADIUS && !near){ near = true;
|
||||||
|
game.gui.create('textbox', { id:'codein', x:50, y:86, w:24, h:8, anchor:'center', placeholder:'Код...', textSize:20 });
|
||||||
|
game.ui.set('codehint', '🔢 Введи код двери (1234) и нажми Enter', {x:50,y:78,anchor:'bottom',color:'#fff',size:16}); }
|
||||||
|
else if (d >= RADIUS && near){ near = false; game.gui.remove('codein'); game.ui.set('codehint','',{}); }
|
||||||
});
|
});
|
||||||
game.gui.onSubmit('codein', (text) => {
|
game.gui.onSubmit('codein', (text) => {
|
||||||
if (opened) return;
|
if (opened) return;
|
||||||
if (String(text).trim() === CODE){
|
if (String(text).trim() === CODE){
|
||||||
opened = true;
|
opened = true; target = Math.PI/2; // плавно распахнуть
|
||||||
game.self.move(p0.x, p0.y - 4.2, p0.z); // дверь уезжает вниз (открыта)
|
|
||||||
game.gui.remove('codein');
|
game.gui.remove('codein');
|
||||||
game.ui.set('codehint','✓ Открыто!', {x:50,y:78,anchor:'bottom',color:'#36d57a',size:18});
|
game.ui.set('codehint','✓ Открыто!', {x:50,y:78,anchor:'bottom',color:'#36d57a',size:18});
|
||||||
game.after(2, () => game.ui.set('codehint','',{}));
|
game.after(2, () => game.ui.set('codehint','',{}));
|
||||||
} else {
|
} else game.ui.set('codehint','✗ Неверный код', {x:50,y:78,anchor:'bottom',color:'#ff5555',size:18});
|
||||||
game.ui.set('codehint', '✗ Неверный код', {x:50,y:78,anchor:'bottom',color:'#ff5555',size:18});
|
|
||||||
}
|
|
||||||
});` }],
|
});` }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -690,7 +701,7 @@ game.onTick(() => {
|
|||||||
icon: 'chase', category: 'npc',
|
icon: 'chase', category: 'npc',
|
||||||
scripts: [{ attachTo: 'global', code:
|
scripts: [{ attachTo: 'global', code:
|
||||||
`// Спавним NPC, который преследует игрока.
|
`// Спавним NPC, который преследует игрока.
|
||||||
const enemy = game.scene.spawnNpc('robot', { x: 8, z: 8, name: 'Охотник', speed: 4 });
|
const enemy = game.scene.spawnNpc('character-a', { x: 8, z: 8, name: 'Охотник', speed: 4 });
|
||||||
if (enemy && enemy.follow) enemy.follow('player');` }],
|
if (enemy && enemy.follow) enemy.follow('player');` }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -760,7 +771,7 @@ game.self.onClick(() => {
|
|||||||
`// Каждые 5с спавнит 2 врагов из точки портала, они идут к игроку.
|
`// Каждые 5с спавнит 2 врагов из точки портала, они идут к игроку.
|
||||||
const p = game.self.position;
|
const p = game.self.position;
|
||||||
function wave(){
|
function wave(){
|
||||||
for (let i=0;i<2;i++){ const e = game.scene.spawnNpc('robot', { x:p.x+(Math.random()-0.5)*2, z:p.z+(Math.random()-0.5)*2, name:'Враг', speed:3 });
|
for (let i=0;i<2;i++){ const e = game.scene.spawnNpc('character-a', { x:p.x+(Math.random()-0.5)*2, z:p.z+(Math.random()-0.5)*2, name:'Враг', speed:3 });
|
||||||
if (e && e.follow) e.follow('player'); }
|
if (e && e.follow) e.follow('player'); }
|
||||||
}
|
}
|
||||||
game.after(2, wave); game.every(5, wave);` }],
|
game.after(2, wave); game.every(5, wave);` }],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user