Кнопка сброса прогресса с диалогом подтверждения
- 🗑️ в HUD: диалог «Сбросить прогресс?» (Отмена / Сбросить)
- сбрасывает монеты, снасти, коллекцию и статистику; настройка звука сохраняется
- возврат в главное меню, перезапись localStorage
- автотест: 4 новые проверки (30/30)
@@ -24,6 +24,7 @@
|
||||
- Приманки: частота клёва, дальность броска, шанс редких и крупных
|
||||
- Дневник рыбака — коллекция, максимальный улов по каждому виду, статистика
|
||||
- Прогресс и коллекция сохраняются в `localStorage` (старые сейвы мигрируются автоматически)
|
||||
- Сброс всего прогресса кнопкой 🗑️ в HUD — через диалог подтверждения (настройка звука при сбросе сохраняется)
|
||||
- Звуки на WebAudio, вибрация на телефоне
|
||||
- Вся графика нарисована на Canvas — внешних ресурсов нет
|
||||
|
||||
|
||||
@@ -81,6 +81,11 @@ button{font-family:inherit;cursor:pointer}
|
||||
@keyframes recpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.09)}}
|
||||
#card{animation:pop .3s ease}
|
||||
@keyframes pop{from{transform:scale(.75);opacity:0}to{transform:scale(1);opacity:1}}
|
||||
|
||||
.twobtns{display:flex;gap:10px;margin-top:16px}
|
||||
.twobtns .big{margin-top:0;width:auto;flex:1}
|
||||
.big.danger{background:linear-gradient(#ff8a7a,#e74c3c);box-shadow:0 4px 0 #96281b;color:#fff}
|
||||
.big.danger:active{box-shadow:0 2px 0 #96281b}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -90,6 +95,7 @@ button{font-family:inherit;cursor:pointer}
|
||||
<div id="coins">🪙 0</div>
|
||||
<div class="hudbtns">
|
||||
<button id="btnShop">🛒</button>
|
||||
<button id="btnReset" title="Сбросить прогресс">🗑️</button>
|
||||
<button id="btnMute">🔊</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -126,6 +132,18 @@ button{font-family:inherit;cursor:pointer}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Подтверждение сброса -->
|
||||
<div id="resetDlg" class="overlay hidden">
|
||||
<div class="panel">
|
||||
<div class="panelhead">🗑️ Сбросить прогресс?</div>
|
||||
<p style="margin-top:8px">Монеты, снасти и коллекция будут стёрты.<br>Это действие <b>нельзя отменить</b>.</p>
|
||||
<div class="twobtns">
|
||||
<button id="btnResetNo" class="big">Отмена</button>
|
||||
<button id="btnResetYes" class="big danger">Сбросить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Карточка улова -->
|
||||
<div id="card" class="overlay hidden">
|
||||
<div class="panel">
|
||||
@@ -900,6 +918,30 @@ $('btnMute').addEventListener('click',()=>{
|
||||
save.muted=!save.muted; persist(); updateHUD(); sfx('click');
|
||||
});
|
||||
$('btnRecall').addEventListener('click',()=>{ recall(); });
|
||||
$('btnReset').addEventListener('click',()=>{
|
||||
sfx('click');
|
||||
uiOpen=true; // пауза, пока идёт подтверждение
|
||||
$('resetDlg').classList.remove('hidden');
|
||||
});
|
||||
$('btnResetNo').addEventListener('click',()=>{
|
||||
sfx('click');
|
||||
$('resetDlg').classList.add('hidden');
|
||||
uiOpen=(state==='MENU');
|
||||
});
|
||||
$('btnResetYes').addEventListener('click',()=>{
|
||||
const muted=save.muted; // настройка звука — не игровые данные, оставляем
|
||||
save={coins:0,rod:0,lure:0,rods:[0],lures:[0],caught:{},muted:muted,casts:0,earned:0};
|
||||
persist();
|
||||
reel=null; biteFish=null;
|
||||
$('resetDlg').classList.add('hidden');
|
||||
$('shop').classList.add('hidden');
|
||||
$('card').classList.add('hidden');
|
||||
state='MENU'; uiOpen=true;
|
||||
$('menu').classList.remove('hidden');
|
||||
updateHUD(); renderShop();
|
||||
sfx('no'); vib(50);
|
||||
toast('Прогресс сброшен 🔄');
|
||||
});
|
||||
$('btnCardOk').addEventListener('click',()=>{
|
||||
sfx('click');
|
||||
$('card').classList.add('hidden');
|
||||
|
||||
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 262 KiB |
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 215 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 234 KiB After Width: | Height: | Size: 244 KiB |
|
After Width: | Height: | Size: 81 KiB |
@@ -180,7 +180,34 @@ const sleep = ms => new Promise(r => setTimeout(r, ms));
|
||||
const saved = await page.evaluate(() => ({ coins: save.coins, rod: save.rod, lure: save.lure, casts: save.casts }));
|
||||
ok('сохранение после reload', saved.coins === 9600 && saved.rod === 1 && saved.lure === 1 && saved.casts === 5, JSON.stringify(saved));
|
||||
|
||||
// --- 9. Ошибки консоли ---
|
||||
// --- 9. Сброс данных (играть сначала нужно зайти в игру) ---
|
||||
await page.click('#btnPlay');
|
||||
await sleep(150);
|
||||
await page.click('#btnReset');
|
||||
await sleep(150);
|
||||
ok('диалог сброса открыт', await page.$eval('#resetDlg', el => !el.classList.contains('hidden')));
|
||||
await page.screenshot({ path: 'shot-reset.png' });
|
||||
await page.click('#btnResetNo');
|
||||
ok('отмена: диалог закрыт, данные не тронуты',
|
||||
await page.$eval('#resetDlg', el => el.classList.contains('hidden'))
|
||||
&& (await page.evaluate(() => save.coins)) === 9600);
|
||||
await page.click('#btnReset');
|
||||
await sleep(100);
|
||||
await page.click('#btnResetYes');
|
||||
await sleep(150);
|
||||
const afterReset = await page.evaluate(() => ({
|
||||
coins: save.coins, rod: save.rod, lure: save.lure, casts: save.casts,
|
||||
caught: JSON.stringify(save.caught), state: state,
|
||||
menu: !document.getElementById('menu').classList.contains('hidden'),
|
||||
ls: localStorage.getItem('fishing-save-v1'),
|
||||
}));
|
||||
ok('сброс: данные обнулены, возврат в меню',
|
||||
afterReset.coins === 0 && afterReset.rod === 0 && afterReset.lure === 0
|
||||
&& afterReset.casts === 0 && afterReset.caught === '{}' && afterReset.state === 'MENU'
|
||||
&& afterReset.menu, JSON.stringify(afterReset));
|
||||
ok('сброс: localStorage перезаписан', afterReset.ls === null || JSON.parse(afterReset.ls).coins === 0);
|
||||
|
||||
// --- 10. Ошибки консоли ---
|
||||
ok('нет ошибок JS (pageerror)', pageErrors.length === 0, pageErrors.join(' | '));
|
||||
ok('нет ошибок консоли', consoleErrors.length === 0, consoleErrors.join(' | '));
|
||||
|
||||
|
||||