feat(phys8 ch2): Phase 4 Wave 2 — §30 Эрстед + §31 электромагнит + Финал главы 2
§30 Опыт Эрстеда: - 3 теории: открытие 1820, значение опыта, применения - IV-1: симуляция Эрстеда — провод + стрелка, slider'ы ключа и направления тока; без тока стрелка указывает на N (Землю), при включении тока отклоняется на 60° (по/против часовой в зависимости от направления) - IV-2: 5 вопросов о значимости опыта - IV-3: DnD 8 «есть/нет поля» (магниты, токи, нейтр. тела) - IV-4: 6 MCQ §31 Поле прямого провода + электромагнит: - 3 теории: окружности линий и правило правой руки, соленоид, электромагнит - IV-1: ГЛАВНЫЙ ВИЗУАЛ — электромагнит-конструктор: slider'ы I, N и dropdown сердечника (воздух/железо μ=500); катушка с витками, стержень, рассчитанный |B| и число поднимаемых скрепок - IV-2: 5 вопросов «правило правой руки» - IV-3: DnD 8 действий «усилит/ослабит поле» - IV-4: 6 MCQ ФИНАЛ ГЛАВЫ 2: - Шпаргалка из 12 формул и понятий - 10 интегрированных боссов: закон Ома, R=ρl/S, последов., параллельная, смешанная цепь, мощность, Джоуль-Ленц, кВт·ч за месяц, тариф, магистр электромагнетизма - Прогресс-бар + ачивка em_master (+50 XP) при 10/10 Глава 2 «Электромагнитные явления» (§§12-31, 20 параграфов) закончена. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -303,7 +303,8 @@ const ACH_LABELS = {
|
||||
p29_done:"Магнитное поле освоен!",
|
||||
p30_done:"Магнитное поле тока освоен!",
|
||||
p31_done:"Магнитное поле прямого проводника и катушки с током. Электромагнит освоен!",
|
||||
ch2_done:"Глава 2 пройдена!"
|
||||
ch2_done:"Глава 2 пройдена!",
|
||||
em_master:"Мастер электромагнетизма — все боссы главы 2 повержены!"
|
||||
};
|
||||
|
||||
const SIDEBARS = {
|
||||
@@ -436,9 +437,24 @@ const SIDEBARS = {
|
||||
["Линии замкнуты","нет источника / стока"],
|
||||
["Опилки","показывают линии $\\vec B$"]
|
||||
]},
|
||||
p30:{title:"Шпаргалка § 30",rows:[["В разработке","Phase 4 Wave 2"]]},
|
||||
p31:{title:"Шпаргалка § 31",rows:[["В разработке","Phase 4 Wave 2"]]},
|
||||
final2:{title:"Шпаргалка ★",rows:[["В разработке","Phase 4 Wave 2"]]}
|
||||
p30:{title:"Шпаргалка § 30",rows:[
|
||||
["Опыт Эрстеда","1820 г"],
|
||||
["Вывод","ток создаёт магн. поле"],
|
||||
["Связь","электричество $\\leftrightarrow$ магнетизм"],
|
||||
["Стрелка над током","отклоняется"]
|
||||
]},
|
||||
p31:{title:"Шпаргалка § 31",rows:[
|
||||
["Прямой проводник","линии — концентр. окружности"],
|
||||
["Правило прав. руки","большой палец = ток"],
|
||||
["Соленоид","как полосовой магнит"],
|
||||
["Электромагнит","катушка + сердечник"],
|
||||
["$|B|$ катушки","$\\propto I N$"]
|
||||
]},
|
||||
final2:{title:"Финал главы 2",rows:[
|
||||
["§§12-31","электромагнитные явления"],
|
||||
["3 части","статика, ток, магнетизм"],
|
||||
["Награда","+50 XP + Мастер ЭМ"]
|
||||
]}
|
||||
};
|
||||
|
||||
const TIPS=[
|
||||
@@ -460,9 +476,9 @@ const TIPS=[
|
||||
{sec:'p27',html:"Счётчик в квартире меряет энергию в <b>кВт·ч</b>: 1 кВт·ч — это работа за 1 час мощностью 1 кВт. Стоимость = энергия × тариф. ТБ: розетка под 220 В может ударить смертельным током."},
|
||||
{sec:'p28',html:"Два полюса магнита: N (север) и S (юг). Как и заряды: одноимённые отталкиваются, разноимённые притягиваются. Но в отличие от зарядов, разрезать магнит и получить «только N» нельзя — выскочат новые два полюса."},
|
||||
{sec:'p29',html:"Вокруг магнита есть магнитное поле — оно действует на железные предметы и магнитные стрелки. Линии поля выходят из N и входят в S, и они <b>замкнуты</b> (в отличие от линий эл. поля). Опилки на бумаге над магнитом красиво «рисуют» эти линии."},
|
||||
{sec:'p30',html:"Параграф § 30 будет реализован в Phase 4 Wave 2. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."},
|
||||
{sec:'p31',html:"Параграф § 31 будет реализован в Phase 4 Wave 2. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."},
|
||||
{sec:'final2',html:"Параграф ★ будет реализован в Phase 4 Wave 2. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."}
|
||||
{sec:'p30',html:"Великое открытие Эрстеда (1820): магнитная стрелка отклоняется около проводника с током. Значит, ток создаёт магнитное поле! Это первый «мост» между электричеством и магнетизмом."},
|
||||
{sec:'p31',html:"Линии поля вокруг прямого провода — концентрические окружности. Направление определяет правило правой руки. Катушка с током (соленоид) ведёт себя как полосовой магнит. Электромагнит = катушка + железный сердечник: сильный, управляемый магнит."},
|
||||
{sec:'final2',html:"Финал главы 2 — 10 интегрированных боссов по всей электротехнике 8 класса. Заряды, поле, ток, закон Ома, соединения, мощность, кВт·ч, магнетизм. +50 XP и ачивка «Мастер электромагнетизма»."}
|
||||
];
|
||||
|
||||
const BUILDERS = {
|
||||
@@ -484,9 +500,9 @@ const BUILDERS = {
|
||||
p27: ()=>{ build_p27(); },
|
||||
p28: ()=>{ build_p28(); },
|
||||
p29: ()=>{ build_p29(); },
|
||||
p30: ()=>{ const box=document.getElementById('p30-body'); box.innerHTML = buildStub('p30', 'Магнитное поле тока', 'Phase 4 Wave 2') + secNavFor('p30') + readButton('p30'); renderMath(box); wireReadBtn('p30'); },
|
||||
p31: ()=>{ const box=document.getElementById('p31-body'); box.innerHTML = buildStub('p31', 'Магнитное поле прямого проводника и катушки с током. Электромагнит', 'Phase 4 Wave 2') + secNavFor('p31') + readButton('p31'); renderMath(box); wireReadBtn('p31'); },
|
||||
final2: ()=>{ const box=document.getElementById('final2-body'); box.innerHTML = buildStub('final2', 'Финал главы', 'Phase 4 Wave 2') + secNavFor('final2') + readButton('final2'); renderMath(box); wireReadBtn('final2'); }
|
||||
p30: ()=>{ build_p30(); },
|
||||
p31: ()=>{ build_p31(); },
|
||||
final2: ()=>{ build_final2(); }
|
||||
};
|
||||
|
||||
function calcLevel(xp){ return Math.floor(Math.sqrt((xp||0)/100))+1; }
|
||||
@@ -4771,6 +4787,578 @@ function _initP29_mcq(){
|
||||
render();
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
PHASE 4 · WAVE 2 — §30, §31, FINAL 2
|
||||
====================================================================== */
|
||||
|
||||
/* ======== §30 — Магнитное поле тока. Опыт Эрстеда ======== */
|
||||
function build_p30(){
|
||||
const box = document.getElementById('p30-body');
|
||||
let h = '';
|
||||
|
||||
h += makeCard('theory', 'Опыт Эрстеда', '§ 30.1',
|
||||
'<p>В 1820 году датский физик Ханс Эрстед сделал революционное открытие. Он расположил магнитную стрелку под прямым проводником и включил ток.</p>'
|
||||
+'<p>Стрелка <b>повернулась</b>! Это значило: вокруг проводника с током есть <b>магнитное поле</b>.</p>'
|
||||
+'<p>До этого считалось, что электричество и магнетизм — совершенно независимы. Опыт Эрстеда показал: <b>это одно явление</b>.</p>'
|
||||
);
|
||||
h += makeCard('rule', 'Что говорит этот опыт', '§ 30.2',
|
||||
'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li>Ток (движущиеся заряды) создаёт магнитное поле.</li>'
|
||||
+'<li>Чем больше $I$, тем сильнее поле.</li>'
|
||||
+'<li>Без тока (ключ разомкнут) — поля нет, стрелка стоит как обычно (по полю Земли).</li>'
|
||||
+'<li>Если поменять направление тока — стрелка повернётся в обратную сторону.</li>'
|
||||
+'</ul>'
|
||||
+'<p>Это положило начало <b>электромагнетизму</b> — теории, объединяющей две силы природы.</p>'
|
||||
);
|
||||
h += makeCard('example', 'Применения', '§ 30.3',
|
||||
'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li>Электромагнит в реле, звонках, динамиках.</li>'
|
||||
+'<li>Электродвигатели всех видов.</li>'
|
||||
+'<li>Магнитные подвески поездов (маглев).</li>'
|
||||
+'<li>МРТ-сканеры в медицине.</li>'
|
||||
+'</ul>'
|
||||
);
|
||||
|
||||
/* IV1 — опыт Эрстеда */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-1</span><div class="wg-title">Опыт Эрстеда</div></div>'
|
||||
+'<div class="wg-help">Включи ток — стрелка отклонится. Поменяй направление — стрелка повернётся в другую сторону.</div>'
|
||||
+'<div class="sliders" style="margin-bottom:10px">'
|
||||
+'<label>Ключ: <select id="p30-key" class="tinp" style="width:auto;padding:6px 10px"><option value="0">разомкнут (тока нет)</option><option value="1">замкнут</option></select></label>'
|
||||
+'<label>Направление тока: <select id="p30-dir" class="tinp" style="width:auto;padding:6px 10px"><option value="1">→ (вправо)</option><option value="-1">← (влево)</option></select></label>'
|
||||
+'</div>'
|
||||
+'<svg id="p30-sim" viewBox="0 0 460 200" style="width:100%;height:auto;background:#f8fafc;border-radius:9px;border:1px solid var(--border)"></svg>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Стрелка отклонена на: <b id="p30-ang">0°</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV2 — викторина «что произойдёт» */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-2</span><div class="wg-title">Что в опыте Эрстеда?</div></div>'
|
||||
+'<div class="wg-help">Вопросы о значимости опыта.</div>'
|
||||
+'<div id="p30-quiz"></div>'
|
||||
+'<div class="actions"><button class="btn" id="p30-quiz-next">Следующий</button></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Раунд: <b id="p30-quiz-r">1</b> / 5</span><span>Правильно: <b id="p30-quiz-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV3 — DnD «где есть магн. поле» */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-3</span><div class="wg-title">Есть ли магнитное поле?</div></div>'
|
||||
+'<div class="wg-help">Распредели ситуации.</div>'
|
||||
+'<div id="p30-dnd-pool"></div>'
|
||||
+'<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">'
|
||||
+'<div class="drop-box"><h5>Есть поле</h5><div class="drop-items" data-cat="y"></div></div>'
|
||||
+'<div class="drop-box"><h5>Нет поля</h5><div class="drop-items" data-cat="n"></div></div>'
|
||||
+'</div>'
|
||||
+'<div class="actions"><button class="btn primary" id="p30-dnd-check">Проверить</button><button class="btn" id="p30-dnd-reset">Сброс</button></div>'
|
||||
+'<div class="feedback" id="p30-dnd-fb"></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV4 — MCQ */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-4</span><div class="wg-title">Тренажёр: 6 вопросов</div></div>'
|
||||
+'<div class="wg-help">4+ — +15 XP.</div>'
|
||||
+'<div id="p30-mcq"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p30-mcq-i">1</b> / 6</span><span>Правильно: <b id="p30-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p30') + readButton('p30');
|
||||
renderMath(box);
|
||||
wireReadBtn('p30');
|
||||
|
||||
_initP30_oersted();
|
||||
_initP30_quiz();
|
||||
_initP30_dnd();
|
||||
_initP30_mcq();
|
||||
}
|
||||
|
||||
function _initP30_oersted(){
|
||||
const svg = document.getElementById('p30-sim'); if(!svg) return;
|
||||
function draw(){
|
||||
const key = +document.getElementById('p30-key').value === 1;
|
||||
const dir = +document.getElementById('p30-dir').value;
|
||||
let s = '';
|
||||
/* провод горизонтальный */
|
||||
s += '<line x1="60" y1="60" x2="400" y2="60" stroke="#374151" stroke-width="4" stroke-linecap="round"/>';
|
||||
/* батарея слева, ключ */
|
||||
s += window.PHYS.batteryEMF(60, 130, '6 В', 'h');
|
||||
s += window.PHYS.wire(60, 112, 60, 60);
|
||||
s += window.PHYS.wire(60, 148, 60, 170);
|
||||
s += window.PHYS.wire(60, 170, 400, 170);
|
||||
s += window.PHYS.wire(400, 170, 400, 60);
|
||||
/* ключ на нижнем проводе */
|
||||
s += '<circle cx="200" cy="170" r="3" fill="#0f172a"/>';
|
||||
s += '<circle cx="240" cy="170" r="3" fill="#0f172a"/>';
|
||||
if(key) s += '<line x1="200" y1="170" x2="240" y2="170" stroke="#0f172a" stroke-width="3"/>';
|
||||
else s += '<line x1="200" y1="170" x2="235" y2="155" stroke="#0f172a" stroke-width="3"/>';
|
||||
/* стрелка тока на проводе */
|
||||
if(key){
|
||||
if(dir > 0) s += window.PHYS.drawArrow(200, 50, 260, 50, '#d97706', 2.2, 10);
|
||||
else s += window.PHYS.drawArrow(260, 50, 200, 50, '#d97706', 2.2, 10);
|
||||
s += '<text x="230" y="40" text-anchor="middle" font-family="JetBrains Mono,monospace" font-size="12" font-weight="700" fill="#d97706">I</text>';
|
||||
}
|
||||
/* магнитная стрелка под проводом */
|
||||
const cx = 230, cy = 100;
|
||||
/* угол отклонения */
|
||||
let angle = 0; /* 0 — стрелка вдоль провода (на запад/восток... условно вверх в нашем рисунке: будет указывать на N=верх) */
|
||||
/* без тока: стрелка указывает «на север» — то есть направлена вверх (в нашей рисовке север = верх) */
|
||||
/* с током: отклоняется перпендикулярно проводу.
|
||||
Эрстед: если ток слева направо (запад → восток), стрелка отклоняется по часовой стрелке (вид сверху, стрелка кажется поворачивается вправо). */
|
||||
if(key){
|
||||
angle = dir > 0 ? 60 : -60; /* 60° от исходного направления */
|
||||
}
|
||||
/* нарисуем стрелку: длина 36, поворот на angle */
|
||||
const rad = angle * Math.PI / 180;
|
||||
/* без поворота стрелка идёт вверх (от cx,cy+18 до cx,cy-18) */
|
||||
const lenH = 18;
|
||||
const ex1 = cx + lenH * Math.sin(rad);
|
||||
const ey1 = cy - lenH * Math.cos(rad); /* северный конец */
|
||||
const ex2 = cx - lenH * Math.sin(rad);
|
||||
const ey2 = cy + lenH * Math.cos(rad);
|
||||
s += '<circle cx="'+cx+'" cy="'+cy+'" r="4" fill="#0f172a"/>';
|
||||
s += '<line x1="'+cx+'" y1="'+cy+'" x2="'+ex1.toFixed(1)+'" y2="'+ey1.toFixed(1)+'" stroke="#dc2626" stroke-width="3"/>';
|
||||
s += '<polygon points="'+ex1.toFixed(1)+','+ey1.toFixed(1)+' '+(ex1-4*Math.cos(rad)).toFixed(1)+','+(ey1-4*Math.sin(rad)).toFixed(1)+' '+(ex1+4*Math.cos(rad)).toFixed(1)+','+(ey1+4*Math.sin(rad)).toFixed(1)+'" fill="#dc2626"/>';
|
||||
s += '<line x1="'+cx+'" y1="'+cy+'" x2="'+ex2.toFixed(1)+'" y2="'+ey2.toFixed(1)+'" stroke="#2563eb" stroke-width="3"/>';
|
||||
/* подпись стрелки */
|
||||
s += '<text x="'+(ex1+8*Math.sin(rad)).toFixed(1)+'" y="'+(ey1-2).toFixed(1)+'" font-family="Inter,sans-serif" font-size="11" font-weight="800" fill="#dc2626">N</text>';
|
||||
/* отклонение */
|
||||
document.getElementById('p30-ang').textContent = Math.abs(angle).toFixed(0)+'°';
|
||||
svg.innerHTML = s;
|
||||
}
|
||||
document.getElementById('p30-key').addEventListener('change', draw);
|
||||
document.getElementById('p30-dir').addEventListener('change', draw);
|
||||
draw();
|
||||
}
|
||||
|
||||
function _initP30_quiz(){
|
||||
const QS = [
|
||||
{q:'Что заметил Эрстед в опыте?', opts:['тёплый провод','отклонение стрелки около проводника с током','свечение проводника','ничего'], ans:1, why:'Магнитная стрелка отклонилась.'},
|
||||
{q:'Что доказывает опыт?', opts:['ток нагревает','ток создаёт магн. поле','магнит проводит ток','ничего'], ans:1, why:'Ток создаёт магнитное поле.'},
|
||||
{q:'В каком году провёл опыт?', opts:['1750','1820','1900','1950'], ans:1, why:'1820 год.'},
|
||||
{q:'Что произойдёт, если поменять направление тока?', opts:['стрелка не среагирует','стрелка повернётся в противоположную сторону','стрелка сломается','стрелка сделает оборот'], ans:1, why:'Направление поля зависит от направления тока.'},
|
||||
{q:'Без тока (ключ разомкнут) стрелка…', opts:['отклонена','указывает на север','вращается','не работает'], ans:1, why:'Под действием магнитного поля Земли указывает на N.'}
|
||||
];
|
||||
let i = 0, ok = 0;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p30-quiz'); if(!wrap) return;
|
||||
let html = '<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.5"><b>Вопрос '+(i+1)+'.</b> '+q.q+'</div><div style="display:grid;grid-template-columns:1fr;gap:6px">';
|
||||
q.opts.forEach((opt,k)=>{ html += '<button class="btn" data-k="'+k+'" style="text-align:left;padding:10px 14px">'+String.fromCharCode(65+k)+'. '+opt+'</button>'; });
|
||||
html += '</div><div class="feedback" id="p30-quiz-fb"></div>';
|
||||
wrap.innerHTML = html;
|
||||
document.getElementById('p30-quiz-r').textContent = (i+1);
|
||||
document.getElementById('p30-quiz-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-k]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true);
|
||||
const k = +btn.dataset.k; const fb = document.getElementById('p30-quiz-fb');
|
||||
if(k===q.ans){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(3,'p30-quiz'); bumpProgress('p30', 4); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p30-quiz-ok').textContent = ok;
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p30-quiz-next').addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP30_dnd(){
|
||||
const items = [
|
||||
{id:'a', cat:'y', html:'постоянный магнит'},
|
||||
{id:'b', cat:'y', html:'провод с током'},
|
||||
{id:'c', cat:'y', html:'движущийся электрон'},
|
||||
{id:'d', cat:'y', html:'катушка под током'},
|
||||
{id:'e', cat:'n', html:'нейтральный кусок железа'},
|
||||
{id:'f', cat:'n', html:'разомкнутая цепь'},
|
||||
{id:'g', cat:'n', html:'покоящийся заряд'},
|
||||
{id:'h', cat:'n', html:'батарейка без провода'}
|
||||
];
|
||||
const dnd = setupSorter({ poolId:'p30-dnd-pool', scopeSelector:'#sec-p30', cats:['y','n'], items, columnLayout:false });
|
||||
document.getElementById('p30-dnd-check').addEventListener('click', ()=>{
|
||||
const fb = document.getElementById('p30-dnd-fb');
|
||||
let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; });
|
||||
if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. Магн. поле создают: магниты, токи и движ. заряды.'; addXp(15,'p30-dnd'); bumpProgress('p30', 20); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'.'; }
|
||||
});
|
||||
document.getElementById('p30-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p30-dnd-fb'); fb.style.display='none'; });
|
||||
}
|
||||
|
||||
function _initP30_mcq(){
|
||||
const QS = [
|
||||
{q:'Кто открыл связь электричества и магнетизма?', opts:['Вольт','Ампер','Эрстед','Ом'], ans:2, why:'Х. Эрстед, 1820 г.'},
|
||||
{q:'Какое поле создаёт ток?', opts:['электрическое','магнитное','гравитационное','тепловое'], ans:1, why:'Магнитное.'},
|
||||
{q:'От чего зависит сила магн. поля у провода?', opts:['от U','от I','от R','от температуры'], ans:1, why:'Чем больше $I$, тем сильнее поле.'},
|
||||
{q:'Как меняется поле, если ток развернуть?', opts:['исчезает','усиливается','меняет направление','удваивается'], ans:2, why:'Меняет знак (направление).'},
|
||||
{q:'Применение опыта Эрстеда?', opts:['лампы','электромоторы','чайники','компасы'], ans:1, why:'Все электромоторы используют взаимод. тока и магн. поля.'},
|
||||
{q:'Что объединил Эрстед?', opts:['теплоту и свет','электричество и магнетизм','гравитацию и свет','химию и физику'], ans:1, why:'Электричество ↔ магнетизм.'}
|
||||
];
|
||||
let i = 0, ok = 0, done = 0, awarded = false;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p30-mcq'); if(!wrap) return;
|
||||
let h = '<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.5"><b>Вопрос '+(i+1)+'.</b> '+q.q+'</div><div style="display:grid;grid-template-columns:1fr;gap:6px">';
|
||||
q.opts.forEach((opt,k)=>{ h += '<button class="btn" data-k="'+k+'" style="text-align:left;padding:10px 14px">'+String.fromCharCode(65+k)+'. '+opt+'</button>'; });
|
||||
h += '</div><div class="feedback" id="p30-mcq-fb"></div><div class="actions"><button class="btn" id="p30-mcq-next">Следующий</button></div>';
|
||||
wrap.innerHTML = h;
|
||||
document.getElementById('p30-mcq-i').textContent = (i+1);
|
||||
document.getElementById('p30-mcq-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-k]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true);
|
||||
const k = +btn.dataset.k; const fb = document.getElementById('p30-mcq-fb');
|
||||
if(k===q.ans){ ok++; done++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(2,'p30-mcq'); bumpProgress('p30', 3); }
|
||||
else { done++; fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p30-mcq-ok').textContent = ok;
|
||||
if(done >= QS.length && !awarded && ok >= 4){ awarded = true; setTimeout(()=>{ const wf=document.getElementById('p30-mcq-fb'); wf.className='feedback ok'; wf.innerHTML='✓ +15 XP — тренажёр пройден.'; addXp(15,'p30-mcq-bonus'); bumpProgress('p30', 15); }, 600); }
|
||||
});
|
||||
});
|
||||
const nb = document.getElementById('p30-mcq-next'); if(nb) nb.addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
/* ======== §31 — Поле прямого провода и катушки. Электромагнит ======== */
|
||||
function build_p31(){
|
||||
const box = document.getElementById('p31-body');
|
||||
let h = '';
|
||||
|
||||
h += makeCard('theory', 'Поле прямого провода', '§ 31.1',
|
||||
'<p>Опыт с железными опилками показывает: линии магнитного поля вокруг прямого провода с током — <b>концентрические окружности</b> в плоскости, перпендикулярной проводу.</p>'
|
||||
+'<p><b>Правило правой руки</b>: если большой палец правой руки направить вдоль тока, то остальные пальцы покажут направление линий $\\vec B$.</p>'
|
||||
);
|
||||
h += makeCard('rule', 'Катушка с током (соленоид)', '§ 31.2',
|
||||
'<p>Если намотать провод спиралью и пропустить через него ток, получится <b>соленоид</b>. Его магнитное поле очень похоже на поле полосового магнита:</p>'
|
||||
+'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li>один торец становится «N» полюсом, другой — «S»;</li>'
|
||||
+'<li>линии $\\vec B$ выходят из N, входят в S, замыкаются;</li>'
|
||||
+'<li>сила поля растёт с током $I$ и числом витков $N$: $|B| \\propto I N$.</li>'
|
||||
+'</ul>'
|
||||
+'<p>Направление полюсов снова определяется правилом правой руки: пальцы — по витку с током, большой палец — в сторону северного полюса.</p>'
|
||||
);
|
||||
h += makeCard('example', 'Электромагнит', '§ 31.3',
|
||||
'<p>Если вставить внутрь катушки железный <b>сердечник</b>, поле резко усиливается (в 1000+ раз). Получается <b>электромагнит</b>.</p>'
|
||||
+'<p>Его преимущества:</p>'
|
||||
+'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li>включается и выключается по желанию (через ключ);</li>'
|
||||
+'<li>сила управляется током $I$;</li>'
|
||||
+'<li>можно сделать очень сильным.</li>'
|
||||
+'</ul>'
|
||||
+'<p>Применения: дверные звонки, реле, грузоподъёмные краны, левитирующие поезда.</p>'
|
||||
);
|
||||
|
||||
/* IV1 — электромагнит-конструктор */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-1</span><div class="wg-title">Электромагнит-конструктор</div></div>'
|
||||
+'<div class="wg-help">Меняй ток и число витков — увидь, сколько скрепок поднимает электромагнит.</div>'
|
||||
+'<div class="sliders" style="margin-bottom:10px">'
|
||||
+'<label>$I$, А: <b id="p31-iv">1.0</b><input type="range" id="p31-i" min="0" max="3" step="0.1" value="1"></label>'
|
||||
+'<label>Число витков $N$: <b id="p31-nv">50</b><input type="range" id="p31-n" min="0" max="200" step="10" value="50"></label>'
|
||||
+'<label>Сердечник: <select id="p31-core" class="tinp" style="width:auto;padding:6px 10px"><option value="1">воздух (без)</option><option value="500">железо</option></select></label>'
|
||||
+'</div>'
|
||||
+'<svg id="p31-sim" viewBox="0 0 460 220" style="width:100%;height:auto;background:#f8fafc;border-radius:9px;border:1px solid var(--border)"></svg>'
|
||||
+'<div class="score-display" style="margin-top:10px;flex-direction:column;align-items:flex-start;gap:3px">'
|
||||
+'<span>$|B| \\propto I \\cdot N \\cdot \\mu$: <b id="p31-bval">50</b> у.е.</span>'
|
||||
+'<span>Поднимет скрепок: <b id="p31-clips">2</b></span>'
|
||||
+'</div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV2 — викторина правило правой руки */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-2</span><div class="wg-title">Где северный полюс электромагнита?</div></div>'
|
||||
+'<div class="wg-help">По направлению тока определи полюсы.</div>'
|
||||
+'<div id="p31-quiz"></div>'
|
||||
+'<div class="actions"><button class="btn" id="p31-quiz-next">Следующий</button></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Раунд: <b id="p31-quiz-r">1</b> / 5</span><span>Правильно: <b id="p31-quiz-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV3 — DnD «что усилит поле» */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-3</span><div class="wg-title">Что усилит поле электромагнита?</div></div>'
|
||||
+'<div class="wg-help">Распредели действия.</div>'
|
||||
+'<div id="p31-dnd-pool"></div>'
|
||||
+'<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">'
|
||||
+'<div class="drop-box"><h5>Усилит</h5><div class="drop-items" data-cat="up"></div></div>'
|
||||
+'<div class="drop-box"><h5>Ослабит</h5><div class="drop-items" data-cat="dn"></div></div>'
|
||||
+'</div>'
|
||||
+'<div class="actions"><button class="btn primary" id="p31-dnd-check">Проверить</button><button class="btn" id="p31-dnd-reset">Сброс</button></div>'
|
||||
+'<div class="feedback" id="p31-dnd-fb"></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV4 — MCQ */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-4</span><div class="wg-title">Тренажёр: 6 вопросов</div></div>'
|
||||
+'<div class="wg-help">4+ — +15 XP.</div>'
|
||||
+'<div id="p31-mcq"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p31-mcq-i">1</b> / 6</span><span>Правильно: <b id="p31-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p31') + readButton('p31');
|
||||
renderMath(box);
|
||||
wireReadBtn('p31');
|
||||
|
||||
_initP31_emagnet();
|
||||
_initP31_quiz();
|
||||
_initP31_dnd();
|
||||
_initP31_mcq();
|
||||
}
|
||||
|
||||
function _initP31_emagnet(){
|
||||
const svg = document.getElementById('p31-sim'); if(!svg) return;
|
||||
function update(){
|
||||
const I = +document.getElementById('p31-i').value;
|
||||
const N = +document.getElementById('p31-n').value;
|
||||
const mu = +document.getElementById('p31-core').value;
|
||||
document.getElementById('p31-iv').textContent = I.toFixed(1);
|
||||
document.getElementById('p31-nv').textContent = N;
|
||||
const B = I * N * mu / 100; /* условная единица */
|
||||
document.getElementById('p31-bval').textContent = B.toFixed(0);
|
||||
const clips = Math.floor(B / 25);
|
||||
document.getElementById('p31-clips').textContent = clips;
|
||||
/* SVG: катушка + сердечник + поднятые скрепки */
|
||||
let s = '';
|
||||
/* батарея */
|
||||
s += window.PHYS.batteryEMF(50, 180, I.toFixed(1)+' А', 'h');
|
||||
/* провода */
|
||||
s += window.PHYS.wire(50, 162, 50, 100);
|
||||
s += window.PHYS.wire(50, 100, 130, 100);
|
||||
s += window.PHYS.wire(50, 198, 50, 200);
|
||||
s += window.PHYS.wire(50, 200, 360, 200);
|
||||
s += window.PHYS.wire(360, 200, 360, 100);
|
||||
s += window.PHYS.wire(360, 100, 320, 100);
|
||||
/* катушка — серия наклонных полудуг */
|
||||
const wireCount = Math.max(3, Math.min(20, Math.floor(N/10)));
|
||||
const coilX1 = 130, coilX2 = 320;
|
||||
const coilSpan = coilX2 - coilX1;
|
||||
const coilCy = 100;
|
||||
/* стержень-сердечник (если железо — заметнее) */
|
||||
if(mu > 1){
|
||||
s += '<rect x="'+(coilX1-10)+'" y="'+(coilCy-12)+'" width="'+(coilSpan+20)+'" height="24" fill="#cbd5e1" stroke="#0f172a" stroke-width="1.5" rx="3"/>';
|
||||
}
|
||||
for(let k=0; k<wireCount; k++){
|
||||
const cx = coilX1 + (k+0.5) * coilSpan/wireCount;
|
||||
s += '<ellipse cx="'+cx.toFixed(1)+'" cy="'+coilCy+'" rx="6" ry="18" fill="none" stroke="#d97706" stroke-width="2"/>';
|
||||
}
|
||||
/* N и S */
|
||||
s += '<text x="'+(coilX1-22)+'" y="'+(coilCy+5)+'" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="16" font-weight="900" fill="#dc2626">N</text>';
|
||||
s += '<text x="'+(coilX2+22)+'" y="'+(coilCy+5)+'" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="16" font-weight="900" fill="#2563eb">S</text>';
|
||||
/* скрепки притянуты к N полюсу */
|
||||
for(let k=0;k<clips && k<8;k++){
|
||||
const yC = 130 + k*10;
|
||||
s += '<path d="M '+(coilX1-30-k*4)+' '+yC+' Q '+(coilX1-15)+' '+(yC+3)+' '+(coilX1-15)+' '+yC+' Q '+(coilX1-15)+' '+(yC-3)+' '+(coilX1-30-k*4)+' '+yC+'" fill="none" stroke="#475569" stroke-width="2"/>';
|
||||
}
|
||||
/* подпись */
|
||||
s += '<text x="'+(coilX1+coilSpan/2)+'" y="50" text-anchor="middle" font-family="Inter,sans-serif" font-size="12" font-weight="700" fill="#7c3aed">|B| = '+B.toFixed(0)+', клипс: '+clips+'</text>';
|
||||
svg.innerHTML = s;
|
||||
}
|
||||
['p31-i','p31-n','p31-core'].forEach(id => document.getElementById(id).addEventListener('input', update));
|
||||
document.getElementById('p31-core').addEventListener('change', update);
|
||||
update();
|
||||
}
|
||||
|
||||
function _initP31_quiz(){
|
||||
const QS = [
|
||||
{q:'Большой палец правой руки = ток. Куда направлены остальные пальцы?', opts:['от N','вдоль линий $\\vec B$','к S','перпендикулярно'], ans:1, why:'Правило правой руки: пальцы по $\\vec B$.'},
|
||||
{q:'У катушки — какой полюс там, куда «выходят» линии?', opts:['N','S','оба','никакой'], ans:0, why:'Линии выходят из N.'},
|
||||
{q:'Что усилит поле катушки сильнее всего?', opts:['+ток','+витки','+железный сердечник','любое'], ans:2, why:'Сердечник усиливает поле в сотни раз.'},
|
||||
{q:'Электромагнит работает на постоянном…', opts:['напряжении','токе','тепле','магните'], ans:1, why:'Нужен постоянный ток.'},
|
||||
{q:'Что произойдёт, если выключить ток?', opts:['поле остаётся','поле исчезает','поле растёт','полюса меняются'], ans:1, why:'Поле существует только при токе.'}
|
||||
];
|
||||
let i = 0, ok = 0;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p31-quiz'); if(!wrap) return;
|
||||
let html = '<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.5"><b>Вопрос '+(i+1)+'.</b> '+q.q+'</div><div style="display:grid;grid-template-columns:1fr;gap:6px">';
|
||||
q.opts.forEach((opt,k)=>{ html += '<button class="btn" data-k="'+k+'" style="text-align:left;padding:10px 14px">'+String.fromCharCode(65+k)+'. '+opt+'</button>'; });
|
||||
html += '</div><div class="feedback" id="p31-quiz-fb"></div>';
|
||||
wrap.innerHTML = html;
|
||||
document.getElementById('p31-quiz-r').textContent = (i+1);
|
||||
document.getElementById('p31-quiz-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-k]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true);
|
||||
const k = +btn.dataset.k; const fb = document.getElementById('p31-quiz-fb');
|
||||
if(k===q.ans){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(3,'p31-quiz'); bumpProgress('p31', 4); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p31-quiz-ok').textContent = ok;
|
||||
renderMath(wrap);
|
||||
});
|
||||
});
|
||||
renderMath(wrap);
|
||||
}
|
||||
document.getElementById('p31-quiz-next').addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP31_dnd(){
|
||||
const items = [
|
||||
{id:'i', cat:'up', html:'увеличить ток $I$'},
|
||||
{id:'n', cat:'up', html:'добавить витков'},
|
||||
{id:'c', cat:'up', html:'вставить железный сердечник'},
|
||||
{id:'t', cat:'up', html:'намотать туже'},
|
||||
{id:'ki',cat:'dn', html:'уменьшить ток'},
|
||||
{id:'nn',cat:'dn', html:'убрать половину витков'},
|
||||
{id:'ne',cat:'dn', html:'вынуть сердечник'},
|
||||
{id:'op',cat:'dn', html:'разомкнуть цепь'}
|
||||
];
|
||||
const dnd = setupSorter({ poolId:'p31-dnd-pool', scopeSelector:'#sec-p31', cats:['up','dn'], items, columnLayout:false });
|
||||
document.getElementById('p31-dnd-check').addEventListener('click', ()=>{
|
||||
const fb = document.getElementById('p31-dnd-fb');
|
||||
let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; });
|
||||
if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. $|B| \\propto I N$ + сердечник усиливает в сотни раз.'; addXp(15,'p31-dnd'); bumpProgress('p31', 20); renderMath(fb); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'.'; }
|
||||
});
|
||||
document.getElementById('p31-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p31-dnd-fb'); fb.style.display='none'; });
|
||||
}
|
||||
|
||||
function _initP31_mcq(){
|
||||
const QS = [
|
||||
{q:'Линии $\\vec B$ вокруг прямого провода — это…', opts:['прямые','окружности','эллипсы','зигзаги'], ans:1, why:'Концентрические окружности перпендикулярно проводу.'},
|
||||
{q:'Что определяет правило правой руки?', opts:['знак заряда','направление $\\vec B$','напряжение','частоту'], ans:1, why:'Направление магнитного поля.'},
|
||||
{q:'Соленоид с током похож на…', opts:['прямой магнит','полосовой магнит','подковообразный','ничего'], ans:1, why:'Поле как у полосового магнита.'},
|
||||
{q:'Электромагнит = …', opts:['обычный магнит','катушка + сердечник','батарейка + лампа','любой провод'], ans:1, why:'Катушка с сердечником.'},
|
||||
{q:'Зачем сердечник?', opts:['для красоты','для прочности','для усиления магнитного поля','чтобы катушка не сгорала'], ans:2, why:'Железо концентрирует магнитное поле — усиливает в сотни раз.'},
|
||||
{q:'Где применяют электромагнит?', opts:['в МРТ','в кранах','в звонках, реле','везде перечисленное'], ans:3, why:'Все эти устройства!'}
|
||||
];
|
||||
let i = 0, ok = 0, done = 0, awarded = false;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p31-mcq'); if(!wrap) return;
|
||||
let h = '<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.5"><b>Вопрос '+(i+1)+'.</b> '+q.q+'</div><div style="display:grid;grid-template-columns:1fr;gap:6px">';
|
||||
q.opts.forEach((opt,k)=>{ h += '<button class="btn" data-k="'+k+'" style="text-align:left;padding:10px 14px">'+String.fromCharCode(65+k)+'. '+opt+'</button>'; });
|
||||
h += '</div><div class="feedback" id="p31-mcq-fb"></div><div class="actions"><button class="btn" id="p31-mcq-next">Следующий</button></div>';
|
||||
wrap.innerHTML = h;
|
||||
document.getElementById('p31-mcq-i').textContent = (i+1);
|
||||
document.getElementById('p31-mcq-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-k]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true);
|
||||
const k = +btn.dataset.k; const fb = document.getElementById('p31-mcq-fb');
|
||||
if(k===q.ans){ ok++; done++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(2,'p31-mcq'); bumpProgress('p31', 3); }
|
||||
else { done++; fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p31-mcq-ok').textContent = ok;
|
||||
renderMath(wrap);
|
||||
if(done >= QS.length && !awarded && ok >= 4){ awarded = true; setTimeout(()=>{ const wf=document.getElementById('p31-mcq-fb'); wf.className='feedback ok'; wf.innerHTML='✓ +15 XP — тренажёр пройден.'; addXp(15,'p31-mcq-bonus'); bumpProgress('p31', 15); }, 600); }
|
||||
});
|
||||
});
|
||||
const nb = document.getElementById('p31-mcq-next'); if(nb) nb.addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
renderMath(wrap);
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
/* ======== ФИНАЛ ГЛАВЫ 2 — 10 интегрированных боссов ======== */
|
||||
function build_final2(){
|
||||
const box = document.getElementById('final2-body');
|
||||
let h = '';
|
||||
|
||||
/* Шпаргалка */
|
||||
h += '<div class="card" style="background:linear-gradient(135deg,var(--sec-acc-soft),var(--card));border:1.5px solid var(--sec-acc)">'
|
||||
+'<div class="card-header"><div class="card-icon rule">'+ICONS.rule+'</div><div class="card-title">Шпаргалка главы 2</div></div>'
|
||||
+'<div class="card-body" style="display:grid;grid-template-columns:1fr 1fr;gap:14px">'
|
||||
+'<div><b>Заряд:</b> $q = Ne$, $e = 1{,}6\\cdot10^{-19}$ Кл</div>'
|
||||
+'<div><b>Поле:</b> $\\vec E$, линии от + к −</div>'
|
||||
+'<div><b>Напряжение:</b> $U = A/q$, $A = qU$</div>'
|
||||
+'<div><b>Ток:</b> $I = q/t$, [А]</div>'
|
||||
+'<div><b>Ом:</b> $I = U/R$</div>'
|
||||
+'<div><b>Сопротивление:</b> $R = \\rho l/S$</div>'
|
||||
+'<div><b>Последов.:</b> $R = R_1+R_2$, $I=$const, $U=U_1+U_2$</div>'
|
||||
+'<div><b>Паралл.:</b> $1/R = 1/R_1+1/R_2$, $U=$const, $I=I_1+I_2$</div>'
|
||||
+'<div><b>Мощность:</b> $P = UI = I^2R = U^2/R$</div>'
|
||||
+'<div><b>Джоуль-Ленц:</b> $Q = I^2Rt$</div>'
|
||||
+'<div><b>Энергия:</b> $W = Pt$ кВт·ч; $1$ кВт·ч $= 3{,}6\\cdot10^6$ Дж</div>'
|
||||
+'<div><b>Магниты:</b> N, S; одноим. отталк., разноим. притяг.</div>'
|
||||
+'</div></div>';
|
||||
|
||||
/* 10 интегрированных боссов */
|
||||
const BOSSES = [
|
||||
{n:1, title:'Закон Ома базовый', q:'$U = 36$ В, $R = 12$ Ом. Найди $I$ (А).', hint:'$I = U/R = 3$ А.', ans:3, tol:0.05, step:'0.01'},
|
||||
{n:2, title:'Сопротивление провода', q:'Медь $l = 50$ м, $S = 0{,}5$ мм². Найди $R$ (Ом). ($\\rho = 0{,}017$)', hint:'$R = \\rho l/S = 0{,}017\\cdot50/0{,}5 = 1{,}7$ Ом.', ans:1.7, tol:0.05, step:'0.01'},
|
||||
{n:3, title:'Послед. цепь', q:'$R_1 = 4$, $R_2 = 6$, $R_3 = 10$ Ом последовательно, $U = 40$ В. Найди $I$ (А).', hint:'$R = 20$, $I = 40/20 = 2$ А.', ans:2, tol:0.05, step:'0.01'},
|
||||
{n:4, title:'Паралл. цепь', q:'Два резистора $R_1 = R_2 = 12$ Ом параллельно. Найди $R_{общ}$ (Ом).', hint:'$R/2 = 6$ Ом.', ans:6, tol:0.1, step:'0.1'},
|
||||
{n:5, title:'Смешанная цепь', q:'$R_1 = 5$ Ом последовательно с параллельным блоком ($R_2 = R_3 = 10$ Ом каждый). $U = 20$ В. Найди общий $I$ (А).', hint:'$R_{пар} = 5$, $R = 10$, $I = 20/10 = 2$ А.', ans:2, tol:0.05, step:'0.01'},
|
||||
{n:6, title:'Мощность', q:'Чайник 1100 Вт работает при $U = 220$ В. Найди $I$ (А) и $R$ (Ом). Введи $R$.', hint:'$I = P/U = 5$ А, $R = U/I = 44$ Ом.', ans:44, tol:1, step:'1'},
|
||||
{n:7, title:'Джоуль-Ленц', q:'Спираль $R = 50$ Ом, $I = 4$ А, $t = 1$ мин. Сколько кДж выделится?', hint:'$Q = I^2Rt = 16\\cdot50\\cdot60 = 48\\,000$ Дж = $48$ кДж.', ans:48, tol:1, step:'1'},
|
||||
{n:8, title:'кВт·ч за месяц', q:'Холодильник 200 Вт работает 24 ч/день, 30 дней. Сколько кВт·ч за месяц?', hint:'$W = 0{,}2 \\cdot 24 \\cdot 30 = 144$ кВт·ч.', ans:144, tol:2, step:'1'},
|
||||
{n:9, title:'Стоимость энергии', q:'За месяц израсходовано 250 кВт·ч, тариф $0{,}25$ руб/(кВт·ч). Сколько руб?', hint:'$250 \\cdot 0{,}25 = 62{,}5$ руб.', ans:62.5, tol:0.5, step:'0.1'},
|
||||
{n:10, title:'Магистр электромагнетизма', q:'Электромагнит с $N = 200$ витками и $I = 1{,}5$ А. Поле в 10 раз сильнее, чем при $N = 50$ и $I = 0{,}6$ А. Во сколько раз поле сильнее в обычной катушке без сердечника, чем с железным сердечником (предположим, сердечник усиливает в 500 раз)? Введи число.', hint:'Сердечник увеличивает поле в 500 раз. Без сердечника поле в 500 раз слабее.', ans:500, tol:5, step:'1'}
|
||||
];
|
||||
|
||||
h += '<div class="card" style="margin-top:14px"><div class="card-header"><div class="card-icon example">'+ICONS.example+'</div><div class="card-title">10 боссов главы 2</div></div><div class="card-body">'
|
||||
+'<div class="boss-overall-bar" style="background:linear-gradient(135deg,rgba(15,23,42,.04),rgba(217,119,6,.04));border-radius:11px;padding:12px;display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin-bottom:14px">'
|
||||
+'<span style="font-weight:700">Боссов побеждено: <b id="f2-won">0</b> / 10</span>'
|
||||
+'<div style="flex:1;min-width:160px;height:8px;background:rgba(0,0,0,.08);border-radius:4px;overflow:hidden">'
|
||||
+'<div id="f2-bar" style="height:100%;background:linear-gradient(90deg,var(--sec-acc),var(--sec-acc-d));width:0%;transition:width .4s"></div>'
|
||||
+'</div></div>'
|
||||
+'<div id="f2-bosses"></div>'
|
||||
+'</div></div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('final2') + readButton('final2');
|
||||
renderMath(box);
|
||||
wireReadBtn('final2');
|
||||
|
||||
_initFinal2_bosses(BOSSES);
|
||||
}
|
||||
|
||||
function _initFinal2_bosses(BOSSES){
|
||||
const KEY = 'physics8_ch2_bosses';
|
||||
function loadState(){ try { return JSON.parse(localStorage.getItem(KEY) || '{}') || {}; } catch(e){ return {}; } }
|
||||
function saveState(s){ try { localStorage.setItem(KEY, JSON.stringify(s)); } catch(e){} }
|
||||
function updateBar(){
|
||||
const s = loadState();
|
||||
let won = 0; for(const k in s) if(s[k]) won++;
|
||||
document.getElementById('f2-won').textContent = won;
|
||||
document.getElementById('f2-bar').style.width = Math.round(won*100/BOSSES.length)+'%';
|
||||
if(won >= BOSSES.length && !STATE.achievements.has('em_master')){
|
||||
addXp(50, 'em-master');
|
||||
achievement('em_master');
|
||||
}
|
||||
return won;
|
||||
}
|
||||
function renderAll(){
|
||||
const cont = document.getElementById('f2-bosses');
|
||||
const state = loadState();
|
||||
let html = '';
|
||||
BOSSES.forEach(b=>{
|
||||
const solved = state[b.n];
|
||||
html += '<div class="boss-card'+(solved?' solved':'')+'" id="f2-boss-'+b.n+'" style="border:2px solid '+(solved?'#10b981':'var(--border)')+';border-radius:12px;padding:14px;margin-bottom:10px;background:var(--card)">'
|
||||
+'<div style="display:flex;gap:10px;align-items:center;margin-bottom:8px"><span style="font-family:Unbounded,sans-serif;font-size:.7rem;font-weight:800;padding:3px 8px;border-radius:99px;background:var(--sec-acc-soft);color:var(--sec-acc-d);text-transform:uppercase">Босс '+b.n+'</span><span style="font-weight:700">'+b.title+'</span></div>'
|
||||
+'<div style="padding:10px 12px;background:rgba(15,23,42,.04);border-radius:8px;margin-bottom:8px;font-size:.94rem;line-height:1.5">'+b.q+'</div>'
|
||||
+'<div class="boss-row">'
|
||||
+'<input type="number" step="'+b.step+'" class="tinp" id="f2-b'+b.n+'-inp" placeholder="число" style="width:140px"'+(solved?' value="'+b.ans+'" disabled':'')+'>'
|
||||
+'<button class="btn primary" id="f2-b'+b.n+'-go"'+(solved?' disabled':'')+'>Атаковать</button>'
|
||||
+'<button class="btn" id="f2-b'+b.n+'-hint">Подсказка</button>'
|
||||
+'</div>'
|
||||
+'<div class="boss-hint-txt" id="f2-b'+b.n+'-ht" style="margin-top:8px;padding:9px 13px;background:rgba(245,158,11,.12);border-left:3px solid #f59e0b;border-radius:6px;font-size:.86rem;display:none;line-height:1.5">'+b.hint+'</div>'
|
||||
+'<div class="feedback'+(solved?' ok':'')+'" id="f2-b'+b.n+'-fb" style="display:'+(solved?'block':'none')+'">'+(solved?'✓ Победа! +10 XP. Босс повержен.':'')+'</div>'
|
||||
+'</div>';
|
||||
});
|
||||
cont.innerHTML = html;
|
||||
BOSSES.forEach(b=>{
|
||||
const go = document.getElementById('f2-b'+b.n+'-go');
|
||||
const inp = document.getElementById('f2-b'+b.n+'-inp');
|
||||
const fb = document.getElementById('f2-b'+b.n+'-fb');
|
||||
const ht = document.getElementById('f2-b'+b.n+'-ht');
|
||||
const hintBtn = document.getElementById('f2-b'+b.n+'-hint');
|
||||
if(hintBtn) hintBtn.addEventListener('click', ()=>{ ht.style.display = ht.style.display==='block'?'none':'block'; });
|
||||
if(!go || go.disabled) return;
|
||||
go.addEventListener('click', ()=>{
|
||||
const v = parseFloat((inp.value || '').replace(',','.'));
|
||||
if(isNaN(v)){ fb.style.display='block'; fb.className='feedback fail'; fb.innerHTML='Введите число.'; return; }
|
||||
if(Math.abs(v - b.ans) < b.tol){
|
||||
fb.style.display='block'; fb.className='feedback ok'; fb.innerHTML='✓ Победа! +10 XP. '+b.hint;
|
||||
go.disabled = true; inp.disabled = true;
|
||||
document.getElementById('f2-boss-'+b.n).classList.add('solved');
|
||||
const s = loadState();
|
||||
if(!s[b.n]){ s[b.n]=true; saveState(s); addXp(10,'f2-boss-'+b.n); bumpProgress('final2', 12); }
|
||||
updateBar();
|
||||
renderMath(fb);
|
||||
} else {
|
||||
fb.style.display='block'; fb.className='feedback fail'; fb.innerHTML='✗ Не то. Перепроверь и попробуй снова.';
|
||||
}
|
||||
});
|
||||
inp.addEventListener('keydown', e=>{ if(e.key === 'Enter') go.click(); });
|
||||
});
|
||||
renderMath(cont);
|
||||
updateBar();
|
||||
}
|
||||
renderAll();
|
||||
}
|
||||
|
||||
function init(){
|
||||
loadProgress(); initTheme(); initSidebarToggle(); initSearch();
|
||||
buildParaSelector(); refreshProgressUI(); loadServerReadState(); goTo(PARAS[0].id);
|
||||
|
||||
Reference in New Issue
Block a user