1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="UTF-8"> 5<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> 6<title>ARAKI EXTREME BASEBALL</title> 7<link rel="stylesheet" href="style.css"> 8</head> 9<body> 10<div id="app"> 11<div id="title" class="ov" style="display:flex"> 12 <div class="title-bottom"> 13 <p class="title-info" id="t-ms"></p> 14 <div class="title-stats"> 15 <span class="title-info" id="t-best"></span> 16 <span class="title-sep">â</span> 17 <span class="title-info" id="t-pts"></span> 18 </div> 19 <div class="btn-row" style="margin-bottom:.15rem"><button class="btn" id="btn-play">â¾ PLAY BALL</button></div> 20 <div class="btn-row" style="gap:.3rem"> 21 <button class="btn btn-s" id="btn-t-tree">ð SKILL TREE</button> 22 <button class="btn btn-s" id="btn-t-ach">ð å®ç¸¾</button> 23 </div> 24 <div class="btn-row" style="gap:.3rem;margin-top:.1rem"> 25 <button class="btn btn-s" id="btn-t-status">ð ã¹ãã¼ã¿ã¹</button> 26 <button class="btn btn-s" id="btn-t-balls" style="display:none">ð» ãã¼ã«ä¸è¦§</button> 27 </div> 28 <div class="btn-row" style="gap:.3rem;margin-top:.1rem"> 29 <button class="btn btn-s" id="btn-t-profile" style="display:none">ð¸ ãããã£ã¼ã«</button> 30 </div> 31 <div class="btn-row" style="gap:.3rem;margin-top:.1rem"> 32 <button class="btn btn-s" id="btn-t-sound">ð SOUND</button> 33 <button class="btn btn-danger" id="btn-t-reset">ð RESET</button> 34 </div> 35 </div> 36</div> 37<canvas id="gc"></canvas> 38<div id="hud"> 39 <div><div class="bc" id="hud-bc">1 / 10</div><div class="cb" id="hud-cb"></div></div> 40 <div style="text-align:right"><div class="sc" id="hud-sc">0</div><div class="tp" id="hud-tp"></div></div> 41 <button class="quit-btn" id="btn-quit">â</button> 42</div> 43<button class="snd-btn" id="snd-btn" style="display:flex">ð</button> 44<div class="ch-banner" id="ch-banner" style="display:none"></div> 45<div class="ev-announce" id="ev-announce" style="display:none"></div> 46<div id="result" class="ov"> 47 <h2>RESULT</h2> 48 <div class="r-sub" id="r-breakdown"></div> 49 <div class="r-total-label">EARNED pts</div> 50 <div class="fs" id="r-total">0</div> 51 <div class="nb" id="r-nb" style="display:none"></div> 52 <div class="sd" id="r-detail"></div> 53 <div class="r-ach-notify" id="r-ach-notify"></div> 54 <div class="btn-row"><button class="btn" id="btn-retry">RETRY</button></div> 55 <div class="btn-row" style="margin-top:.2rem"> 56 <button class="btn btn-s" id="btn-r-tree">SKILL TREE</button> 57 <button class="btn btn-s" id="btn-r-top">ð TOP</button> 58 </div> 59</div> 60<div id="tree" class="ov"> 61 <div class="tr-header"><div style="display:flex;align-items:center;justify-content:center;gap:.5rem"><h2>SKILL TREE</h2><button class="tr-btn unlock" id="tr-maxall" style="padding:.2rem .6rem;font-size:.55rem">å ¨ã¹ãã«æå¤§</button></div><div class="tr-pts" id="tr-pts"></div></div> 62 <div class="tr-tabs" id="tr-tabs"></div> 63 <div class="tr-list" id="tr-list"></div> 64 <div class="tr-foot"> 65 <button class="btn btn-s" id="tr-back" style="flex:1">BACK</button> 66 </div> 67</div> 68<div id="achieve" class="ov"> 69 <div class="tr-header"><h2>ACHIEVEMENTS</h2><div class="tr-pts" id="ach-count"></div></div> 70 <div class="tr-list" id="ach-list"></div> 71 <div class="tr-foot"><button class="btn btn-s" id="ach-back" style="flex:1">BACK</button></div> 72</div> 73<div id="status" class="ov"> 74 <div class="tr-header"><h2>STATUS</h2></div> 75 <div class="tr-list" id="stat-list"></div> 76 <div class="tr-foot"><button class="btn btn-s" id="stat-back" style="flex:1">BACK</button></div> 77</div> 78<div id="balllist" class="ov" style="display:none"> 79 <div class="tr-header"><h2>BALL LIST</h2></div> 80 <div class="tr-list" id="bl-list"></div> 81 <div class="tr-foot"><button class="btn btn-s" id="bl-back" style="flex:1">BACK</button></div> 82</div> 83<div id="profile" class="ov" style="display:none"> 84 <div class="tr-header"><h2>PROFILE CARD</h2><div class="pf-sub">SNSã§èªæ ¢ãããï¼</div></div> 85 <div class="pf-body"> 86 <div class="pf-name-row"> 87 <label class="pf-label">PLAYER NAME</label> 88 <input type="text" class="pf-input" id="pf-name" maxlength="16" placeholder="ååãå ¥å..."> 89 </div>
90 <canvas id="pf-canvas" width="1080" height="1920"></canvas> 91 <div class="btn-row" style="gap:.4rem;margin-top:.5rem"> 92 <button class="btn" id="pf-dl" style="font-size:.85rem;padding:.6rem 1.8rem">ð å ¨ç»é¢è¡¨ç¤º</button> 93 </div> 94 <div class="pf-hint">å ¨ç»é¢è¡¨ç¤ºãã¦ã¹ã¯ã·ã§ã§ä¿åãããï¼</div> 95 </div> 96 <div class="tr-foot"><button class="btn btn-s" id="pf-back" style="flex:1">BACK</button></div> 97</div> 98<div id="story" class="ov"> 99 <div class="st-bg" id="st-bg"></div> 100 <img class="st-chara" id="st-chara"> 101 <div class="st-bottom"> 102 <div class="st-text" id="st-text"></div> 103 <div class="st-skip" id="st-skip">TAP TO START</div> 104 </div> 105</div> 106<div id="ending" class="ov"> 107 <div class="end-bg" id="end-bg"></div> 108 <div class="end-content"> 109 <div class="end-text" id="end-text"></div> 110 <div class="end-title" id="end-title">GAME CLEAR</div> 111 <div class="end-skip" id="end-skip">TAP TO CLOSE</div> 112 </div> 113</div> 114<div id="confirm" class="ov"> 115 <div class="cf-box"> 116 <h3>DATA RESET</h3> 117 <p>å ¨ã¦ã®é²æã»ã¹ãã«ã»ãã¤ã³ã<br>å®ç¸¾ã»ã¹ãã¼ã¿ã¹ããªã»ããããã¾ãã<br>å ã«æ»ãã¾ããã</p> 118 <div class="btn-row"> 119 <button class="btn btn-danger" id="cf-yes" style="font-size:.85rem;padding:.7rem 1.5rem">RESET</button> 120 <button class="btn btn-s" id="cf-no" style="font-size:.85rem;padding:.7rem 1.5rem">CANCEL</button> 121 </div> 122 </div> 123</div> 124 125<div id="sound-settings" class="ov"> 126 <div class="ss-box"> 127 <h3>ð SOUND</h3> 128 <div class="ss-row"> 129 <div class="ss-label"><span>ðµ BGM</span><span class="ss-val" id="ss-bgm-val">100%</span></div> 130 <input type="range" class="ss-slider" id="ss-bgm" min="0" max="100" value="100"> 131 </div> 132 <div class="ss-row"> 133 <div class="ss-label"><span>ð 广é³</span><span class="ss-val" id="ss-sfx-val">100%</span></div> 134 <input type="range" class="ss-slider" id="ss-sfx" min="0" max="100" value="100"> 135 </div> 136 <div class="btn-row" style="margin-top:.5rem"> 137 <button class="btn btn-s" id="ss-close" style="flex:1">CLOSE</button> 138 </div> 139 </div> 140</div> 141
142<script src="skills.js?v=23"></script>
vendor: 1 bytes, line 142
142
143<script> 144(()=>{ 145// ============ Audio ============ 146const AC=window.AudioContext||window.webkitAudioContext;let ac; 147let sfxVol=0.7,bgmVol=0.1; 148// mp3鳿º 149const sfxBatting=new Audio('batting.mp3'); 150const sfxCatch=new Audio('catch.mp3'); 151const sfxMotion=new Audio('Motion.mp3'); 152const sfxEvent=new Audio('event.mp3'); 153const sfxFoul=new Audio('foul.mp3'); 154const sfxBtn=new Audio('btn.mp3'); 155const sfxCharge=new Audio('charge.mp3'); 156const bgmClear=new Audio('clear.mp3'); 157// BGM 158const bgmOp=new Audio('op.mp3');bgmOp.loop=true; 159const bgmBattle=new Audio('bgm.mp3');bgmBattle.loop=true; 160let curBgm=null; 161function playBgm(bgm){ 162 if(curBgm===bgm)return; 163 if(curBgm){curBgm.pause();curBgm.currentTime=0} 164 curBgm=bgm;curBgm.volume=bgmVol;curBgm.play().catch(()=>{}); 165} 166function stopBgm(){if(curBgm){curBgm.pause();curBgm.currentTime=0;curBgm=null}} 167function updateBgmVol(){if(curBgm)curBgm.volume=bgmVol} 168function ea(){if(!ac)ac=new AC();if(ac.state==='suspended')ac.resume();if(curBgm&&curBgm.paused)curBgm.play().catch(()=>{})} 169function playSfx(audio){if(sfxVol<=0)return;try{const a=audio.cloneNode();a.volume=sfxVol;a.play().catch(()=>{})}catch(e){audio.currentTime=0;audio.volume=sfxVol;audio.play().catch(()=>{})}} 170function snd(t){if(sfxVol<=0)return; 171if(t==='homerun'||t==='hit'){playSfx(sfxBatting)} 172else if(t==='miss'){playSfx(sfxCatch)} 173else if(t==='foul'){playSfx(sfxFoul)} 174else if(t==='pitch'){playSfx(sfxMotion)} 175else if(t==='buy'){playSfx(sfxBtn)} 176else if(t==='charge'){playSfx(sfxCharge)}} 177 178// sound settings 179const sndBtn=document.getElementById('snd-btn'); 180sndBtn.onclick=()=>{document.getElementById('sound-settings').style.display='flex'}; 181// restore saved volumes 182try{const sv=JSON.parse(localStorage.getItem('aeb_sound')||'{}');if(sv.sfx!==undefined)sfxVol=sv.sfx;if(sv.bgm!==undefined)bgmVol=sv.bgm}catch(e){} 183const ssBgm=document.getElementById('ss-bgm'); 184const ssSfx=document.getElementById('ss-sfx'); 185ssBgm.value=Math.round(bgmVol*100);ssSfx.value=Math.round(sfxVol*100); 186document.getElementById('ss-bgm-val').textContent=ssBgm.value+'%'; 187document.getElementById('ss-sfx-val').textContent=ssSfx.value+'%'; 188ssBgm.oninput=()=>{bgmVol=ssBgm.value/100;document.getElementById('ss-bgm-val').textContent=ssBgm.value+'%';updateBgmVol();localStorage.setItem('aeb_sound',JSON.stringify({sfx:sfxVol,bgm:bgmVol}))}; 189ssSfx.oninput=()=>{sfxVol=ssSfx.value/100;document.getElementById('ss-sfx-val').textContent=ssSfx.value+'%';localStorage.setItem('aeb_sound',JSON.stringify({sfx:sfxVol,bgm:bgmVol}))}; 190document.getElementById('ss-close').onclick=()=>{document.getElementById('sound-settings').style.display='none'}; 191 192// ============ Event Announce ============ 193function showEventAnnounce(ev){ 194 const el=document.getElementById('ev-announce'); 195 el.innerHTML=`<span class="ev-icon">${ev.icon}</span><div class="ev-name" style="color:${ev.color}">${ev.name}</div><div class="ev-desc">${ev.desc}</div>`; 196 el.style.display='block';el.style.animation='none';el.offsetHeight;el.style.animation='evIn .5s ease-out'; 197 setTimeout(()=>{el.style.display='none'}
197,1200); 198 playSfx(sfxEvent); 199} 200 201// ============ Images ============ 202const imgs={};let imgLoaded=0;const imgTotal=18; 203function loadImg(k,src){const i=new Image();i.onload=()=>{imgs[k]=i;imgLoaded++};i.src=src} 204loadImg('top','TOP.png');loadImg('ball','ball.png');loadImg('bat','bat.png');loadImg('bomb','bomb.png');loadImg('stage','stage.png'); 205loadImg('throw1','throw1.png');loadImg('throw2','throw2.png');loadImg('throw3','throw3.png');loadImg('throw4','throw4.png');loadImg('throw5','throw5.png');loadImg('throw6','throw6.png'); 206loadImg('golden','Golden.png');loadImg('fire','fire.png');loadImg('diamond','diamond.png');loadImg('rainbow','rainbow.png'); 207loadImg('ghost','ghost.png');loadImg('clear','clear.png');loadImg('profile','Profile.png'); 208 209// ============ Constants ============ 210const BASE_BALLS=10; 211const RES={ 212 homerun:{pt:10000,label:'HOME RUN!!',color:'#FFD700',sz:3.0}, 213 triple: {pt:7500, label:'TRIPLE!', color:'#F472B6',sz:2.6}, 214 double: {pt:5000, label:'DOUBLE!', color:'#4ADE80',sz:2.4}, 215 hit: {pt:3000, label:'HIT!', color:'#60A5FA',sz:1.9}, 216 foul: {pt:500, label:'FOUL', color:'#9CA3AF',sz:1.5}, 217 miss: {pt:0, label:'MISS...', color:'#EF4444',sz:1.5}, 218}; 219const PITCH=[ 220 {name:'Straight',speed:[.014,.020],curveX:0,weight:50}, 221 {name:'Changeup',speed:[.005,.008],curveX:0,weight:25}, 222 {name:'Slider', speed:[.009,.013],curveX:.6,weight:25}, 223]; 224 225// ============ Canvas ============ 226const cv=document.getElementById('gc'),cx=cv.getContext('2d'); 227const app=document.getElementById('app'); 228let W,H;function rz(){W=cv.width=app.clientWidth;H=cv.height=app.clientHeight}addEventListener('resize',rz);rz(); 229 230// ============ Save ============ 231function ld(){ 232 try{ 233 const d=JSON.parse(localStorage.getItem('aeb_save')||'{}'); 234 if(!d.ver||d.ver<2)return{best:d.best||0,pts:d.pts||0,skills:{},togOff:{},stats:{},ver:3}; 235 return{best:d.best||0,pts:d.pts||0,skills:d.skills||{},togOff:d.togOff||{},stats:d.stats||{},ver:3}; 236 }catch{return{best:0,pts:0,skills:{},togOff:{},stats:{},ver:3}} 237} 238function sv(s){localStorage.setItem('aeb_save',JSON.stringify(s))} 239let S=ld(); 240 241// ============ Skill helpers (v3: effectFn/costFn/descFn) ============ 242function skillData(id){return SKILL_TREE.find(s=>s.id===id)} 243function skillLv(id){return S.skills[id]||0} 244function active(id){ 245 if(skillLv(id)<1)return false; 246 const sk=skillData(id); 247 if(sk&&sk.toggleable&&S.togOff[id])return false; 248 return true; 249} 250// effectFnã§å¹æãåå¾ 251function skillVal(id){ 252 const sk=skillData(id);if(!sk)return null; 253 const lv=skillLv(id);if(lv<1)return null; 254 return sk.effectFn(lv); 255} 256// effective max level: hyperScale=trueã®ã¿ãã¤ãã¼ãã¼ãã¹ 257function effectiveMaxLv(sk){ 258 if(!sk.hyperScale)return sk.maxLv; 259 return sk.maxLv+getHyperLvBonus(S); 260} 261// å ¨ã¹ãã«ã®å¹æãéç´ 262function getEffect(type,def){ 263 let val=def; 264 SKILL_TREE.forEach(sk=>{ 265 const lv=skillLv(sk.id);if(lv<1)return; 266 if(sk.toggleable&&S.togOff[sk.id])return; 267 const e=sk.effectFn(lv);if(!e)return; 268 if(e.type==='legend'){ 269 if(type==='score_mult')val+=e.score_mult; 270 else if(type==='spot_add')val+=e.spot_add; 271 else if(type==='speed_mult')val*=e.speed_mult; 272 return; 273 } 274 if(e.type==='ultimate'){ 275 if(type==='score_mult')val+=e.score_mult; 276 else if(type==='spot_add')val+=e.spot_add; 277 else if(type==='speed_up')val*=e.speed_up; 278 return; 279 } 280 if(e.type==='hyper')return; 281 if(e.type==='chaos'){ 282 if(type==='score_mult')val+=e.score_mult; 283 if(type==='speed_up')val*=e.speed_up; 284 return; 285 } 286 if(e.type===type){ 287 if(type==='score_mult'||type==='combo_add'||type==='spot_add')val+=e.value; 288 else if(type==='speed_mult')val*=e.value; 289 else if(type==='pts_mult')val=e.value; 290 else val=e.value; 291 } 292 if(type==='spot_add'&&e.type==='giant_spot')val+=e.value; 293 }); 294 return val; 295} 296// costFnã§ã³ã¹ãåå¾ 297function getSkillCost(id){ 298 const sk=skillData(id);if(!sk)return Infinity; 299 const lv=skillLv(id); 300 if(lv>=effectiveMaxLv(sk))return Infinity; 301 return sk.costFn(lv+1); 302} 303function calcMultiCost(id,count){ 304 const sk=skillData(id);if(!sk)return Infinity; 305 let lv=skillLv(id),total=0; 306 for(let i=0;i<count;i++){if(lv+i+1>effectiveMaxLv(sk))return Infinity;total+=sk.costFn(lv+i+1)} 307 return total; 308} 309function canUnlock(id){ 310 const sk=skillData(id);if(!sk)return false;
311 const lv=skillLv(id); 312 if(lv>=effectiveMaxLv(sk))return false; 313 if(S.pts<getSkillCost(id))return false; 314 if(sk.unlock)return sk.unlock(S); 315 if(sk.ring<=1)return true; 316 const prev=SKILL_TREE.find(s=>s.branch===sk.branch&&s.ring===sk.ring-1); 317 if(!prev)return true; 318 return skillLv(prev.id)>=prev.maxLv; 319} 320function unlockSkill(id){ 321 if(!canUnlock(id))return false; 322 const cost=getSkillCost(id); 323 S.pts-=cost; 324 S.skills[id]=(S.skills[id]||0)+1; 325 sv(S);return true; 326} 327function isSkillAvailable(id){ 328 const sk=skillData(id);if(!sk)return false; 329 if(sk.unlock)return sk.unlock(S); 330 if(sk.ring<=1)return true; 331 const prev=SKILL_TREE.find(s=>s.branch===sk.branch&&s.ring===sk.ring-1); 332 if(!prev)return true; 333 return skillLv(prev.id)>=prev.maxLv; 334} 335 336// ============ State ============ 337let st='title',maxB=BASE_BALLS,curB=0,totSc=0,dspSc=0,combo=0,resList=[]; 338let ballT=0,ballSpd=0,ballCX=0,pWait=0,curPitch=null,ballWX=0; 339let isBomb=false; 340let lastWasHR=false; 341let isCritical=false; 342let curEvent=null; // ç¾å¨ã®ãããã¤ãã³ã 343let curChallenge=null; // ç¾å¨ã®ãã£ã¬ã³ã¸ 344let maxCombo=0; // ã²ã¼ã ä¸ã®æå¤§ã³ã³ã 345let eventBonusPts=0; // ã¤ãã³ãã§ç¨¼ãã ãã¼ãã¹pt 346let challengeCleared=false; 347let milestoneJustReached=null; // ã²ã¼ã ä¸ã«å°éãããã¤ã«ã¹ãã¼ã³ 348let spotX,spotY,spotR,hrZoneR=0; 349let particles=[],shake=0,flash=0,flashColor='255,255,255'; 350let rLabel=null,batSw=0,hitBall=null,sPops=[],comText=null; 351let pitcherFrame=0,pitcherTimer=0,windupId=0; 352let pitcherDown=false,pitcherDownTimer=0,pitcherDownHR=false; 353let eventPreview=null,eventPreviewTimer=0; // ã¤ãã³ãäºå 354let jaganSlow=0,jaganUsed=false,jaganFreezeT=0; // éªç¼ããªã¼ãº 355// éçã¨ãæ¯ãã¢ã¼ã 356let ghostMode=false; 357let ghostType=''; // 'pinball' or 'vanish' 358let ghostBounces=[]; // ãã³ãã¼ã«ç¨: [{x,y},...] çµç±ç¹ 359let ghostVisible=true; // æ¶ããéçç¨ 360 361function updSpot(){ 362 spotX=W/2;spotY=H*.72;spotR=Math.min(W,H)*.07; 363 const add=getEffect('spot_add',0); 364 spotR*=(1+add); 365 const giantEff=skillVal('giant_bat'); 366 const hrExtra=giantEff?giantEff.hrZone:0; 367 const goubakuEff=active('goubaku')?skillVal('goubaku'):null; 368 const goubakuAdd=goubakuEff?goubakuEff.hrZoneAdd:0; 369 // æé¡æ¢æ°´: ãã¼ãã¨ãªã¢ç¸®å° 370 const meikyoEff=active('meikyo')?skillVal('meikyo'):null; 371 if(meikyoEff)spotR*=meikyoEff.spotScale; 372 hrZoneR=spotR*(HR_ZONE_BASE_RATIO+hrExtra+goubakuAdd); 373} 374 375// ============ Particles ============ 376function spawn(x,y,n,c,sp){for(let i=0;i<n;i++){const a=Math.random()*Math.PI*2,v=sp*(.5+Math.random());particles.push({x,y,vx:Math.cos(a)*v,vy:Math.sin(a)*v-sp*.3,life:1,decay:.015+Math.random()*.02,size:2+Math.random()*4,color:c})}} 377 378// ============ Pitch ============ 379function pickPitch(){ 380 let t=PITCH.map(p=>({...p})); 381 const slEff=skillVal('slow_rate'); 382 if(slEff)t[1].weight+=slEff.value; 383 if(active('no_slider'))t[2].weight=0; 384 if(active('straight_only')){t[1].weight=0;t[2].weight=0;t[0].weight=100} 385 const tot=t.reduce((s,p)=>s+p.weight,0);let r=Math.random()*tot; 386 for(const p of t){r-=p.weight;if(r<=0)return p}return t[0]; 387} 388 389function getBallSpeed(base){ 390 let s=base; 391 const ahEff=skillVal('arm_heavy'); 392 if(ahEff)s*=ahEff.value; 393 const legendEff=skillVal('legend'); 394 if(legendEff)s*=legendEff.speed_mult; 395 const ultEff=skillVal('ultimate'); 396 if(ultEff)s*=ultEff.speed_up; 397 const chaosEff=skillVal('chaos'); 398 if(chaosEff)s*=chaosEff.speed_up; 399 return s; 400} 401 402// ============ Ball pos ============ 403function bpos(){ 404 const cxp=W/2,sY=H*.37,eY=H*.85,t=ballT,et=t*t; 405 let by,bx; 406 // ãã³ãã¼ã«è»é 407 if(ghostMode&&ghostType==='pinball'&&ghostBounces.length>1){ 408 const seg=ghostBounces.length-1; 409 // ballTã¯é常éãé²ãã1.0å°éæã«ãã¼ãã¨ãªã¢ã«å±ãããã«ãã 410 const progress=Math.min(t,1); 411 const idx=progress*seg; 412 const i=Math.min(Math.floor(idx),seg-1); 413 const frac=idx-i; 414 const p0=ghostBounces[i],p1=ghostBounces[i+1]; 415 bx=p0.x+(p1.x-p0.x)*frac; 416 by=p0.y+(p1.y-p0.y)*frac; 417 }else{ 418 by=sY+(eY-sY)*et; 419 bx=cxp+ballWX*et*W*.15; 420 } 421 // ãµã¤ãº: ãã³ãã¼ã«ã¯progressãã¼ã¹ã§è¨ç® 422 let sz; 423 if(ghostMode&&ghostType==='pinball'){ 424 const p=Math.min(t,1);sz=3+20*p*p; 425 }else{sz=3+20*et} 426 const masaiEff=active('masai')?skillVal('masai'):null; 427 if(masaiEff)sz*=masaiEff.ballScale; 428 return{x:bx,y:by,size:sz}; 429} 430// ã´ã¼ã¹ããã¼ã«çµç±ç¹çæ 431function generateGhostBounces(){ 432 const pts=[]; 433 const startX=W/2,startY=H*.37; 434 const endX=spotX,endY=spotY; 435 const bounceCount=3+Math.floor(Math.random()*3); // 3~5åè·³ãè¿ã 436 pts.push({x:startX,y:startY}); 437 for(let i=0;i<bounceCount;i++){ 438 const t=(i+1)/(bounceCount+1); 439 const midY=startY+(endY-startY)*t; 440 // å·¦å³ã®ç»é¢ç«¯ã«ã©ã³ãã ã«è·³ãè¿ã 441 const side=Math.random()>.5?1:-1; 442 const margin=W*0.05; 443 const bx=side>0?W-margin:margin; 444 pts.push({x:bx,y:midY}); 445 } 446 pts.push({x:endX,y:endY}); 447 return pts; 448} 449 450// ============ Judge ============ 451function judge(){ 452 const b=bpos(),dx=b.x-spotX,dy=b.y-spotY,d=Math.sqrt(dx*dx+dy*dy),r=spotR; 453 let res; 454 if(d<hrZoneR)res='homerun'; 455 else if(d<r*.35)res='homerun'; 456 else if(d<r*.65)res=active('triple_hit')?'triple':'double'; 457 else if(d<r*1.0)res='hit'; 458 else if(d<r*1.5)res='foul'; 459 else res='miss';
460 // ã¬ã¤ã³ãã¼ãã¼ã«: ãã¹ã»ãã¡ã¦ã«ä»¥å¤ã¯å ¨é¨HR 461 if(curEvent&&curEvent.allHR&&res!=='miss'&&res!=='foul')res='homerun'; 462 return res; 463} 464 465// ============ Score calc ============ 466function calcPts(type){ 467 let base=RES[type].pt; 468 let cm=combo>1?combo:1; 469 const comboAdd=getEffect('combo_add',0); 470 if(comboAdd>0&&combo>1)cm+=comboAdd; 471 let pts=Math.floor(base*cm); 472 const scoreMult=getEffect('score_mult',0); 473 if(scoreMult>0)pts=Math.floor(pts*(1+scoreMult)); 474 if(type==='homerun'){ 475 const gsEff=skillVal('grand_slam'); 476 if(gsEff)pts=Math.floor(pts*gsEff.value); 477 } 478 if(active('diamond_bat')){const dbEff=skillVal('diamond_bat');pts=Math.floor(pts*(dbEff?dbEff.value:2))} 479 if(lastWasHR&&active('chain_lightning')){ 480 const clEff=skillVal('chain_lightning'); 481 if(clEff)pts=Math.floor(pts*(1+clEff.value)); 482 } 483 if(isCritical)pts=Math.floor(pts*2); 484 if(active('one_shot')){ 485 const osEff=skillVal('one_shot'); 486 if(osEff)pts=Math.floor(pts*osEff.value); 487 } 488 // ã«ãªã¹ã¢ã¼ãã®ã¹ã³ã¢åç 489 const chaosEff=skillVal('chaos'); 490 if(chaosEff)pts=Math.floor(pts*(1+chaosEff.score_mult)); 491 // æé¡æ¢æ°´ã®ã¹ã³ã¢åç 492 const meikyoEff=active('meikyo')?skillVal('meikyo'):null; 493 if(meikyoEff)pts=Math.floor(pts*meikyoEff.scoreMult); 494 // ã©ã³ãã ã¤ãã³ãã®ã¹ã³ã¢åç 495 if(curEvent&&curEvent.scoreMult&&type!=='miss')pts=Math.floor(pts*curEvent.scoreMult); 496 // EXTREME BASEBALL: ç´¯è¨è©¦åæ°%åã¹ã³ã¢UP 497 if(active('extreme_bb')){const games=S.stats&&S.stats.games?S.stats.games:0;if(games>0)pts=Math.floor(pts*(1+games*0.01))} 498 // éçã¨ãæ¯ãã¢ã¼ã: ã¹ã³ã¢10000å 499 if(ghostMode&&type!=='miss')pts=Math.floor(pts*10000); 500 return pts; 501} 502 503// ============ Draw ============ 504function draw(){ 505 cx.save(); 506 if(shake>0){cx.translate((Math.random()-.5)*shake,(Math.random()-.5)*shake)} 507 drawBg(); 508 // ãã¼ã«è»éä»è¿ãå°ãæããã¦è¦èªæ§UPï¼ãããã£ã¼è¶³å ããéå§ãä¸ç«¯ã¼ããï¼ 509 if(st==='pitching'||st==='waiting'||st==='event_preview'||st==='windup'||st==='result_wait'){ 510 const trkTop=H*.45,trkBot=H*.9,trkW=60,fadeH=H*.08; 511 cx.save(); 512 // 横æ¹åã°ã©ãã¼ã·ã§ã³ï¼å¸¯ã®æ¬ä½ï¼ 513 const gd=cx.createLinearGradient(W/2-trkW,0,W/2+trkW,0); 514 gd.addColorStop(0,'rgba(0,0,0,0)');gd.addColorStop(.25,'rgba(0,0,0,.18)');gd.addColorStop(.5,'rgba(0,0,0,.22)');gd.addColorStop(.75,'rgba(0,0,0,.18)');gd.addColorStop(1,'rgba(0,0,0,0)'); 515 // ä¸ç«¯ãã§ã¼ãã¤ã³ï¼ç¸¦æ¹åalphaãã¹ã¯ 516 const am=cx.createLinearGradient(0,trkTop,0,trkTop+fadeH); 517 am.addColorStop(0,'rgba(0,0,0,0)');am.addColorStop(1,'rgba(0,0,0,1)'); 518 // ãã§ã¼ãé¨å 519 cx.fillStyle=gd;cx.globalAlpha=1; 520 // ã¾ãä¸ç«¯fadeHã®é¨åãæ®µéæç» 521 const steps=8; 522 for(let i=0;i<steps;i++){ 523 const t0=i/steps,t1=(i+1)/steps; 524 const y0=trkTop+fadeH*t0,y1=trkTop+fadeH*t1; 525 cx.globalAlpha=t0; 526 cx.fillRect(W/2-trkW,y0,trkW*2,y1-y0); 527 } 528 // æ¬ä½é¨åï¼ãã§ã¼ãå¾ãä¸ç«¯ï¼ 529 cx.globalAlpha=1; 530 cx.fillRect(W/2-trkW,trkTop+fadeH,trkW*2,trkBot-trkTop-fadeH); 531 cx.restore(); 532 } 533 drawPitcherImg();drawEventPreview();drawZone();drawSpot(); 534 if(st==='pitching'){if(active('clairvoyance'))drawTrajectory();drawBallImg()} 535 if(batSw>0)drawSwing(); 536 if(hitBall)drawHitBall(); 537 drawParts();drawLabel();drawPops(); 538 cx.restore(); 539 if(flash>0){cx.fillStyle=`rgba(${flashColor},${flash})`;cx.fillRect(0,0,W,H)} 540} 541function drawBg(){ 542 if(imgs.stage){ 543 // coveræ¹å¼: ç»é¢å ¨ä½ãåãã 544 const img=imgs.stage,iw=img.width,ih=img.height; 545 const scale=Math.max(W/iw,H/ih); 546 const dw=iw*scale,dh=ih*scale; 547 cx.drawImage(img,(W-dw)/2,(H-dh)/2,dw,dh); 548 }else{ 549 // ãã©ã¼ã«ããã¯ï¼ç»åæªãã¼ãæï¼ 550 const g=cx.createLinearGradient(0,0,0,H);g.addColorStop(0,'#060618');g.addColorStop(.4,'#1a0a2a');g.addColorStop(1,'#0a0a0a'); 551 cx.fillStyle=g;cx.fillRect(0,0,W,H); 552 } 553} 554function drawPitcherImg(){ 555 const drawH=H*.18,py=H*.33-drawH*.3; 556 // HRâthrow6, ãã以å¤ã®çµæâthrow5 557 if(pitcherDown){ 558 const img=pitcherDownHR?imgs.throw6:imgs.throw5; 559 if(!img)return; 560 const drawW=drawH*(img.width/img.height); 561 cx.drawImage(img,W/2-drawW/2,py,drawW,drawH); 562 return; 563 } 564 const frameKey='throw'+(pitcherFrame+1); 565 const img=imgs[frameKey];if(!img)return; 566 const drawW=drawH*(img.width/img.height); 567 cx.drawImage(img,W/2-drawW/2,py,drawW,drawH); 568} 569function drawEventPreview(){ 570 if(!eventPreview||st!=='event_preview')return; 571 const al=Math.min(1,eventPreviewTimer/20);
572 const bounce=Math.sin(Date.now()*.008)*3; 573 const py=H*.33-H*.18*.3-20+bounce; // ãããã£ã¼é ä¸ 574 cx.save();cx.globalAlpha=al;cx.textAlign='center'; 575 cx.font='1.5rem sans-serif';cx.fillText(eventPreview.icon,W/2,py); 576 cx.font='bold .65rem sans-serif';cx.fillStyle=eventPreview.color; 577 cx.fillText(eventPreview.name,W/2,py+22); 578 cx.restore(); 579} 580function drawZone(){ 581 if(st!=='pitching'&&st!=='waiting'&&st!=='event_preview'&&st!=='windup'&&st!=='result_wait')return; 582 const zw=100,zh=120;cx.strokeStyle='rgba(255,255,255,.08)';cx.lineWidth=1.5;cx.setLineDash([5,5]); 583 cx.strokeRect(spotX-zw/2,spotY-zh/2,zw,zh);cx.setLineDash([]); 584} 585function drawSpot(){ 586 if(st!=='pitching'&&st!=='waiting'&&st!=='event_preview'&&st!=='windup'&&st!=='result_wait')return; 587 const p=1+Math.sin(Date.now()*.005)*.08,r=spotR*p; 588 const g=cx.createRadialGradient(spotX,spotY,r*.3,spotX,spotY,r*1.2); 589 g.addColorStop(0,'rgba(255,215,0,.25)');g.addColorStop(.6,'rgba(255,215,0,.08)');g.addColorStop(1,'rgba(255,215,0,0)'); 590 cx.fillStyle=g;cx.beginPath();cx.arc(spotX,spotY,r*1.2,0,Math.PI*2);cx.fill(); 591 cx.strokeStyle=`rgba(255,215,0,${.5+Math.sin(Date.now()*.004)*.15})`;cx.lineWidth=2.5; 592 cx.beginPath();cx.arc(spotX,spotY,r,0,Math.PI*2);cx.stroke(); 593 cx.strokeStyle='rgba(255,215,0,.2)';cx.lineWidth=1; 594 cx.beginPath();cx.moveTo(spotX-r,spotY);cx.lineTo(spotX+r,spotY);cx.stroke(); 595 cx.beginPath();cx.moveTo(spotX,spotY-r);cx.lineTo(spotX,spotY+r);cx.stroke(); 596 cx.fillStyle='rgba(255,215,0,.5)';cx.beginPath();cx.arc(spotX,spotY,3,0,Math.PI*2);cx.fill(); 597 if(hrZoneR>3){ 598 const hr=hrZoneR*p; 599 cx.strokeStyle=`rgba(239,68,68,${.4+Math.sin(Date.now()*.006)*.15})`;cx.lineWidth=2; 600 cx.beginPath();cx.arc(spotX,spotY,hr,0,Math.PI*2);cx.stroke(); 601 const hg=cx.createRadialGradient(spotX,spotY,0,spotX,spotY,hr); 602 hg.addColorStop(0,'rgba(239,68,68,.15)');hg.addColorStop(1,'rgba(239,68,68,.02)'); 603 cx.fillStyle=hg;cx.beginPath();cx.arc(spotX,spotY,hr,0,Math.PI*2);cx.fill(); 604 } 605} 606function drawTrajectory(){ 607 if(ghostMode)return; // ã´ã¼ã¹ãã¢ã¼ãã§ã¯è»éé表示 608 const steps=20;cx.strokeStyle='rgba(255,215,0,.1)';cx.lineWidth=1;cx.setLineDash([3,6]);cx.beginPath(); 609 for(let i=0;i<=steps;i++){const t=i/steps,et=t*t;const sY=H*.37,eY=H*.85;const by=sY+(eY-sY)*et;const bx=W/2+ballWX*et*W*.15; 610 if(i===0)cx.moveTo(bx,by);else cx.lineTo(bx,by)} 611 cx.stroke();cx.setLineDash([]); 612 if(curPitch){cx.fillStyle='rgba(255,215,0,.4)';cx.font='600 .6rem sans-serif';cx.textAlign='center';
613 const label=curPitch.name==='Straight'?'é':curPitch.name==='Changeup'?'é ':'å¤';cx.fillText(label,W/2,H*.34)} 614} 615function drawBallImg(){ 616 if(ballT<0)return;let{x,y,size}=bpos(); 617 // æ¶ããéç: æ¶ãã¦ãéã¯æç»ããªãï¼vanishã¿ã¤ãã®ã¿ï¼ 618 if(ghostMode&&ghostType==='vanish'&&!ghostVisible&&jaganSlow<=0){return} 619 // éªç¼ããªã¼ãºä¸ã¯ã°ãã¼è¡¨ç¤º 620 if(jaganSlow>0){cx.save();cx.globalAlpha=.4+Math.sin(Date.now()*.02)*.2;const sg=cx.createRadialGradient(x,y,size*.5,x,y,size*3.5);sg.addColorStop(0,'rgba(128,0,255,.6)');sg.addColorStop(1,'rgba(0,0,0,0)');cx.fillStyle=sg;cx.beginPath();cx.arc(x,y,size*3.5,0,Math.PI*2);cx.fill();cx.restore()} 621 drawBallCore(x,y,size); 622 // ã¤ãã³ããã¼ã«ã®ã°ãã¼ 623 if(curEvent&&!isBomb){ 624 cx.save();cx.globalAlpha=.3+Math.sin(Date.now()*.01)*.15; 625 const glow=cx.createRadialGradient(x,y,size*.5,x,y,size*3); 626 glow.addColorStop(0,curEvent.glowColor||'rgba(255,255,255,.3)');glow.addColorStop(1,'rgba(0,0,0,0)'); 627 cx.fillStyle=glow;cx.beginPath();cx.arc(x,y,size*3,0,Math.PI*2);cx.fill();cx.restore(); 628 } 629} 630function drawBallCore(x,y,size){ 631 // ã¤ãã³ãçã®ç»åã鏿 632 let img; 633 if(ghostMode){img=imgs.ghost} 634 else if(isBomb){img=imgs.bomb} 635 else if(curEvent&&imgs[curEvent.id]){img=imgs[curEvent.id]} 636 else{img=imgs.ball} 637 if(img){const sz=size*2;cx.save(); 638 // ã´ã¼ã¹ãã¢ã¼ã: åéæ+ç´«ã°ãã¼ 639 if(ghostMode){ 640 cx.globalAlpha=0.5+Math.sin(Date.now()*.005)*.2; 641 cx.shadowColor='rgba(128,0,255,.8)';cx.shadowBlur=30+size*2; 642 } 643 else if(curEvent&&!isBomb){cx.shadowColor=curEvent.glowColor||'rgba(255,255,255,.8)';cx.shadowBlur=25+size*1.5} 644 else if(!isBomb){cx.shadowColor='rgba(255,255,255,.9)';cx.shadowBlur=15+size*1.5} 645 else{cx.shadowColor='rgba(255,50,0,.8)';cx.shadowBlur=20+size} 646 cx.drawImage(img,x-sz/2,y-sz/2,sz,sz); 647 // æåº¦ãã¼ã¹ã 648 if(!isBomb&&!ghostMode){cx.globalCompositeOperation='lighter';cx.globalAlpha=.25;cx.drawImage(img,x-sz/2,y-sz/2,sz,sz);cx.globalAlpha=1;cx.globalCompositeOperation='source-over'} 649 cx.shadowBlur=0;cx.restore(); 650 }else{cx.fillStyle='#fff';cx.beginPath();cx.arc(x,y,size,0,Math.PI*2);cx.fill()} 651 if(ballT>.15&&!ghostMode){cx.strokeStyle=`rgba(255,255,255,${.15*ballT})`;cx.lineWidth=1.5; 652 for(let i=0;i<3;i++){const ly=y-size-4-i*10,lx=x+(i-1)*3;cx.beginPath();cx.moveTo(lx,ly);cx.lineTo(lx,ly-20*ballT);cx.stroke()}} 653} 654function drawSwing(){ 655 const prog=Math.min(batSw*3.5,1);const startA=Math.PI*1.2,endA=Math.PI*.1,curA=startA+(endA-startA)*prog; 656 const px=spotX+20,py=spotY+30; 657 if(imgs.bat){cx.save();cx.globalAlpha=.7*(1-batSw);cx.translate(px,py);cx.rotate(curA-Math.PI*.5); 658 const bLen=70;cx.drawImage(imgs.bat,-8,-bLen*.1,16,bLen);cx.restore()} 659 cx.strokeStyle=`rgba(255,215,0,${.4*(1-batSw)})`;cx.lineWidth=4;cx.lineCap='round'; 660 cx.beginPath();cx.arc(px,py,55,startA,curA,true);cx.stroke(); 661} 662function drawHitBall(){ 663 if(!hitBall)return;const a=hitBall,sz=3+(1-a.t/a.mt)*3; 664 cx.strokeStyle=`rgba(255,255,255,${a.t/a.mt*.25})`;cx.lineWidth=1.5;cx.setLineDash([3,3]); 665 cx.beginPath();cx.moveTo(spotX,spotY);cx.lineTo(a.x,a.y);cx.stroke();cx.setLineDash([]); 666 if(imgs.ball){const s=sz*2.5;cx.drawImage(imgs.ball,a.x-s/2,a.y-s/2,s,s)} 667 else{cx.fillStyle='#fff';cx.beginPath();cx.arc(a.x,a.y,sz,0,Math.PI*2);cx.fill()} 668} 669function drawParts(){particles.forEach(p=>{cx.globalAlpha=p.life;cx.fillStyle=p.color;cx.beginPath();cx.arc(p.x,p.y,p.size*p.life,0,Math.PI*2);cx.fill()});cx.globalAlpha=1} 670function drawLabel(){ 671 if(!rLabel||rLabel.t<=0)return;const r=rLabel,pg=1-r.t/r.mt; 672 const sc=pg<.12?(pg/.12)*1.4:(pg<.22?1.4-(pg-.12)/.1*.4:1);const al=pg>.65?1-(pg-.65)/.35:1; 673 cx.save();cx.translate(W/2,r.y);cx.scale(sc,sc);cx.globalAlpha=al; 674 cx.font=`900 ${r.sz}rem 'Helvetica Neue',Arial,sans-serif`;cx.textAlign='center'; 675 cx.fillStyle='rgba(0,0,0,.5)';cx.fillText(r.tx,2,2);cx.fillStyle=r.c;cx.fillText(r.tx,0,0); 676 cx.restore();cx.globalAlpha=1; 677} 678function drawPops(){sPops.forEach(p=>{const pg=1-p.t/p.mt,al=pg>.6?1-(pg-.6)/.4:1,y=p.y-pg*50; 679 cx.globalAlpha=al;cx.fillStyle='#FFD700';cx.font='800 1.2rem sans-serif';cx.textAlign='center';cx.fillText(p.tx,p.x,y)});cx.globalAlpha=1} 680 681// ============ Effects ============ 682function fx(type){ 683 const hx=spotX,hy=spotY; 684 if(type==='homerun'){shake=22;flash=.6;flashColor='255,255,255';spawn(hx,hy,45,'#FFD700',9);spawn(hx,hy,20,'#FF6B35',7);snd('homerun'); 685 hitBall={x:hx,y:hy,vx:(Math.random()-.5)*3,vy:-13,t:85,mt:85};if(navigator.vibrate)navigator.vibrate([50,30,100]); 686 pitcherDown=true;pitcherDownHR=true;pitcherDownTimer=80; 687 }else if(type==='triple'){shake=16;flash=.4;flashColor='244,114,182';spawn(hx,hy,35,'#F472B6',7);snd('hit');hitBall={x:hx,y:hy,vx:(Math.random()>.5?1:-1)*5,vy:-11,t:70,mt:70};if(navigator.vibrate)navigator.vibrate(50);pitcherDown=true;pitcherDownHR=false;pitcherDownTimer=55} 688 else if(type==='double'){shake=13;flash=.3;flashColor='255,255,255';spawn(hx,hy,28,'#4ADE80',6);snd('hit');hitBall={x:hx,y:hy,vx:(Math.random()>.5?1:-1)*4,vy:-9,t:65,mt:65};if(navigator.vibrate)navigator.vibrate(40);pitcherDown=true;pitcherDownHR=false;pitcherDownTimer=55} 689 else if(type==='hit'){shake=7;flash=.15;flashColor='255,255,255';spawn(hx,hy,16,'#60A5FA',4);snd('hit');hitBall={x:hx,y:hy,vx:(Math.random()-.5)*6,vy:-5,t:45,mt:45};if(navigator.vibrate)navigator.vibrate(20);pitcherDown=true;pitcherDownHR=false;pitcherDownTimer=45} 690 else if(type==='foul'){shake=3;spawn(hx,hy,8,'#9CA3AF',3);snd('foul');hitBall={x:hx,y:hy,vx:(Math.random()>.5?9:-9),vy:-3,t:30,mt:30};pitcherDown=true;pitcherDownHR=false;pitcherDownTimer=30} 691 else{snd('miss');pitcherDown=true;pitcherDownHR=false;pitcherDownTimer=40} 692 if(isCritical&&type!=='miss'&&type!=='foul'){flash=.4;flashColor='200,100,255';spawn(hx,hy,15,'#C084FC',6)} 693 if(lastWasHR&&active('chain_lightning')&&type!=='miss'){for(let i=0;i<4;i++){const lx=hx+(Math.random()-.5)*80;spawn(lx,hy-20-Math.random()*50,4,'#87CEEB',4)}} 694 const info=RES[type];rLabel={tx:info.label,c:info.color,sz:info.sz,t:75,mt:75,y:H*.46};batSw=.01; 695} 696 697// ============ Main Loop ============ 698let lastFrameTime=0; 699let dtScale=1; // 60fpsåºæºã®ãã¬ã¼ã è£æ£åç 700function upd(now){ 701 try{ 702 if(!now)now=performance.now(); 703 if(lastFrameTime){const dt=now-lastFrameTime;dtScale=dt/(1000/60)} 704 lastFrameTime=now; 705 if(dtScale>3)dtScale=3; // 極端ãªé å»¶ã鲿¢ 706 if(dspSc<totSc){dspSc+=Math.ceil((totSc-dspSc)*.15);if(dspSc>totSc)dspSc=totSc;document.getElementById('hud-sc').textContent=fmtS(dspSc)}
707 if(shake>0)shake*=.84;if(shake<.5)shake=0; 708 if(flash>0)flash*=.87;if(flash<.01)flash=0; 709 if(batSw>0){batSw+=.045*dtScale;if(batSw>1)batSw=0} 710 particles.forEach(p=>{p.x+=p.vx*dtScale;p.y+=p.vy*dtScale;p.vy+=.15*dtScale;p.life-=p.decay*dtScale});particles=particles.filter(p=>p.life>0); 711 if(hitBall){hitBall.x+=hitBall.vx*dtScale;hitBall.y+=hitBall.vy*dtScale;hitBall.vy+=.07*dtScale;hitBall.t-=dtScale;if(hitBall.t<=0)hitBall=null} 712 if(rLabel){rLabel.t-=dtScale;if(rLabel.t<=0)rLabel=null} 713 sPops.forEach(p=>p.t-=dtScale);sPops=sPops.filter(p=>p.t>0); 714 if(pitcherTimer>0){pitcherTimer-=dtScale} 715 if(pitcherDownTimer>0){pitcherDownTimer-=dtScale;if(pitcherDownTimer<=0){pitcherDown=false;pitcherFrame=0}} 716 if(st==='waiting'){pWait-=dtScale;if(pWait<=0){ 717 curPitch=pickPitch(); 718 const sp=curPitch.speed;ballSpd=getBallSpeed(sp[0]+Math.random()*(sp[1]-sp[0])); 719 ballCX=curPitch.curveX*(Math.random()>.5?1:-1);ballWX=ballCX; 720 // éçã¨ãæ¯ãã¢ã¼ãå¤å® 721 ghostMode=active('otawamure'); 722 ghostVisible=true;ghostType=''; 723 if(ghostMode){ 724 ghostType=Math.random()<0.3?'pinball':'vanish'; 725 ballSpd*=(0.1+Math.random()*0.1); // -80%ï½-90%ã©ã³ãã 726 if(ghostType==='pinball'){ 727 ghostBounces=generateGhostBounces(); 728 }else{ 729 ghostBounces=[]; 730 } 731 }else{ghostBounces=[]} 732 // ã¤ãã³ãå¤å®ãå ã«ããï¼çå¼¾ã¨ç¬ç«ï¼ 733 curEvent=null; 734 if(!ghostMode){ 735 const ultLv=skillLv('ultimate'); 736 const chaosEff=skillVal('chaos'); 737 curEvent=rollPitchEvent(ultLv); 738 if(!curEvent&&chaosEff&&chaosEff.allEvent){ 739 // ã«ãªã¹ã¢ã¼ã: ãã¡ã¤ã¤ã¼ãã¼ã«åºç¾çå¤§å¹ UP(40%) 740 if(Math.random()<0.4){curEvent=PITCH_EVENTS.find(e=>e.id==='fire')} 741 else{curEvent=PITCH_EVENTS[Math.floor(Math.random()*PITCH_EVENTS.length)]} 742 } 743 } 744 const bombEff=skillVal('bomb_ball'); 745 isBomb=!curEvent&&!ghostMode&&bombEff&&Math.random()<bombEff.value; 746 if(curEvent){ 747 if(curEvent.speedMult)ballSpd*=curEvent.speedMult; 748 // ã¤ãã³ãäºå表示 â å°ãå¾ ã£ã¦ããæç 749 eventPreview=curEvent;eventPreviewTimer=70; 750 showEventAnnounce(curEvent); 751 st='event_preview'; 752 }else{ 753 // é常æç - ã¾ãæ¯ããã¶ãã¢ã¼ã·ã§ã³ 754 st='windup'; 755 pitcherFrame=0;pitcherTimer=0;const wid=++windupId; 756 setTimeout(()=>{if(windupId!==wid||st!=='windup')return;pitcherFrame=1},500); 757 setTimeout(()=>{if(windupId!==wid||st!=='windup')return;pitcherFrame=2;snd('charge')},800); 758 setTimeout(()=>{if(windupId!==wid)return;pitcherFrame=3;st='pitching';ballT=0;jaganUsed=false;jaganSlow=0;snd('pitch')},2300); 759 } 760 }} 761 if(st==='event_preview'){eventPreviewTimer-=dtScale;if(eventPreviewTimer<=0){ 762 eventPreview=null;st='windup'; 763 pitcherFrame=0;pitcherTimer=0;const wid2=++windupId; 764 setTimeout(()=>{if(windupId!==wid2||st!=='windup')return;pitcherFrame=1},500); 765 setTimeout(()=>{if(windupId!==wid2||st!=='windup')return;pitcherFrame=2;snd('charge')},800); 766 setTimeout(()=>{if(windupId!==wid2)return;pitcherFrame=3;st='pitching';ballT=0;jaganUsed=false;jaganSlow=0;snd('pitch')},2300); 767 }} 768 if(st==='pitching'){ 769 // æ¶ããéç: ã©ã³ãã ç¹æ» ï¼vanishã®ã¿ï¼ 770 if(ghostMode&&ghostType==='vanish'){ 771 if(Math.random()<0.08)ghostVisible=!ghostVisible; 772 } 773 // éªç¼è§£æ¾: ãã¼ãã¨ãªã¢ä¸å¿ã§ãã¼ã«å®å ¨åæ¢ï¼ã´ã¼ã¹ãã¢ã¼ãä¸ã¯ç¡å¹ï¼ 774 if(jaganSlow>0){jaganSlow-=dtScale;ballT=jaganFreezeT} else { 775 ballT+=ballSpd*dtScale; 776 if(!ghostMode&&!jaganUsed&&active('jagan')){ 777 const tTarget=Math.sqrt((spotY-H*.37)/(H*.85-H*.37)); 778 if(ballT>=tTarget){ 779 const jEff=skillVal('jagan'); 780 const freezeTime=jEff?jEff.freezeTime:0.1; 781 jaganFreezeT=tTarget;ballT=tTarget; 782 jaganSlow=Math.round(Math.min(freezeTime,1.0)*60);jaganUsed=true; 783 } 784 }} 785 if(ballT>=1.1){ 786 if(isBomb){const bombEff=skillVal('bomb_ball');const pen=bombEff?bombEff.penalty:0.05;const lost=Math.floor(S.pts*pen);S.pts=Math.max(0,S.pts-lost);sv(S);if(lost>0)sPops.push({tx:`-${fmtS(lost)} pts`,x:W/2,y:H*.35,t:60,mt:60})} 787 lastWasHR=false;regResult('miss'); 788 }} 789 if(st==='result_wait'){pWait-=dtScale;if(pWait<=0)nextB()} 790 draw(); 791 }catch(err){console.error('upd error:',err)} 792 requestAnimationFrame(upd); 793} 794 795// ============ Story ============ 796let storyShown=false; 797function showStory(){ 798 ea(); 799 const stEl=document.getElementById('story'); 800 document.getElementById('st-bg').style.backgroundImage="url('stage.png')"; 801 document.getElementById('st-chara').src='throw2.png'; 802 const lines=[ 803 'ä¸çã¯éç<em>ãã¼ã¯ã»ã¹ãã©ã¤ã¯ã¹</em>ã«æ¯é ããã', 804 '', 805 '叿ã¯ããã¯ãã²ã¨ã¤', 806 'ä¼èª¬ã®æè ã¨ãªãã<em>ãã«ã¹ã¿ã¸ã¢ã </em>ã¸åãã', 807 '', 808 'éå½ã®ãã¬ã¤ãã¼ã«ãããã¾å§ã¾ã' 809 ]; 810 document.getElementById('st-text').innerHTML=lines.join('<br>'); 811 document.getElementById('title').style.display='none'; 812 stEl.style.display='flex'; 813 const skip=()=>{stEl.removeEventListener('click',skip);stEl.style.display='none';storyShown=true;realStartGame()}; 814 stEl.addEventListener('click',skip); 815} 816// ============ Ending ============ 817function showEnding(){ 818 ea(); 819 stopBgm(); 820 // ãã¯ã¤ãã¢ã¦ãç¨ãªã¼ãã¼ã¬ã¤
821 const endEl=document.getElementById('ending'); 822 const endBg=document.getElementById('end-bg'); 823 const endText=document.getElementById('end-text'); 824 const endTitle=document.getElementById('end-title'); 825 const endSkip=document.getElementById('end-skip'); 826 endBg.style.backgroundImage="url('clear.png')"; 827 endBg.style.opacity='0'; 828 endText.className='end-text'; 829 endTitle.className='end-title'; 830 endSkip.className='end-skip'; 831 const lines=[ 832 'éç<em>ãã¼ã¯ã»ã¹ãã©ã¤ã¯ã¹</em>ã¯æãã', 833 '<em>ãã«ã¹ã¿ã¸ã¢ã </em>ã«é¿ãã¦ããæ¯é ã®æå£°ã¯æ¶ã', 834 'é·ãç¶ããéçã®æä»£ã¯ããã¾çµãããåãã', 835 '', 836 'åæã§ãã¹ã¦ã決ã¾ãä¸çã¯å´©ãå»ã', 837 '人ã ã¯ãããããæ¬å½ã®ç©ºãè¦ä¸ãã', 838 'éçã¯å¥ªãåããã®ã§ã¯ãªã', 839 'ç¬ãåãããã®ãã®ã¸ã¨æ»ã£ã¦ãã', 840 '', 841 'ã¹ã¿ã¸ã¢ã ã«ã¯æå£°ãæ»ã', 842 'åã©ããã¡ã¯èªç±ã«ãã¼ã«ã追ã', 843 '誰ãã好ããªããã«ããããæ¯ãããä¸çã帰ã£ã¦ãã', 844 '', 845 'ãã¾ãéçã¯', 846 'æ¯é ã®ããã§ã¯ãªã', 847 '楽ããããã«ãã', 848 '', 849 'ãã¹ã¦ã¯ããã¿ã®ä¸æ¯ãããå§ã¾ã£ã', 850 'ããã¦ãã®ä¼èª¬ã¯', 851 'ãããããèªãç¶ããã¦ãã', 852 '', 853 'ãããã¨ãã忢ãªãæè ã', 854 ]; 855 endText.innerHTML=lines.join('<br>'); 856 // å ¨ç»é¢ç½âãã§ã¼ãã¤ã³ 857 endEl.style.display='flex';endEl.style.background='#fff'; 858 // clear.mp3ãåç 859 const clearAudio=bgmClear.cloneNode();clearAudio.volume=bgmVol>0?Math.max(bgmVol,0.3):0.3;clearAudio.play().catch(()=>{}); 860 setTimeout(()=>{endEl.style.transition='background 3s';endEl.style.background='#000'},500); 861 setTimeout(()=>{endBg.style.opacity='.4'},2000); 862 setTimeout(()=>{endText.classList.add('show')},3000); 863 setTimeout(()=>{endTitle.classList.add('show')},5000); 864 setTimeout(()=>{endSkip.classList.add('show')},7000); 865 // ã¨ã³ãã£ã³ã°ãè¦ããã©ã° 866 S.stats.endingSeen=true;sv(S); 867 const close=()=>{endEl.removeEventListener('click',close); 868 endEl.style.display='none';endEl.style.transition='';endEl.style.background='#000'; 869 clearAudio.pause();clearAudio.currentTime=0; 870 playBgm(bgmOp);showTitle();document.getElementById('title').style.display='flex'}; 871 // 7ç§å¾ããã¿ããå¯è½ 872 setTimeout(()=>{endEl.addEventListener('click',close)},7000); 873} 874 875function startGame(){ 876 // ååã®ã¿ã¹ãã¼ãªã¼è¡¨ç¤ºï¼ä¸åº¦ãã²ã¼ã ããã¬ã¤ãã¦ããªã=stats.gamesã0ï¼ 877 const s=ld(); 878 if(!storyShown&&(!s.stats||!s.stats.games||s.stats.games===0)){showStory();return} 879 realStartGame(); 880} 881 882// ============ Game ============ 883function realStartGame(){ 884 ea();updSpot();playBgm(bgmBattle); 885 document.getElementById('title').style.display='none'; 886 document.getElementById('result').style.display='none'; 887 document.getElementById('tree').style.display='none'; 888 document.getElementById('hud').style.display='flex'; 889 if(active('one_shot'))maxB=3; else maxB=BASE_BALLS; 890 curB=0;totSc=0;dspSc=0;combo=0;maxCombo=0;resList=[];particles=[];sPops=[];rLabel=null;hitBall=null;comText=null; 891 lastWasHR=false;isCritical=false;curEvent=null;eventBonusPts=0;challengeCleared=false;milestoneJustReached=null; 892 pitcherDown=false;pitcherDownTimer=0;pitcherDownHR=false;jaganSlow=0;jaganUsed=false;pitcherFrame=0; 893 ghostMode=false;ghostType='';ghostBounces=[];ghostVisible=true; 894 // ãã£ã¬ã³ã¸é¸åºï¼ã¢ã«ãã£ã¡ããã¢ã¼ã以éã®ã¿ï¼ 895 if(skillLv('ultimate')>=1){ 896 curChallenge=pickChallenge(); 897 const chEl=document.getElementById('ch-banner'); 898 chEl.innerHTML=`<span class="ch-icon">${curChallenge.icon}</span><span class="ch-name">CHALLENGE: ${curChallenge.name}</span><span class="ch-desc"> - ${curChallenge.desc}</span>`; 899 chEl.style.display='block';chEl.style.opacity='1'; 900 }else{ 901 curChallenge=null; 902 document.getElementById('ch-banner').style.display='none'; 903 } 904 document.getElementById('hud-sc').textContent='0';document.getElementById('hud-cb').textContent=''; 905 document.getElementById('hud-tp').textContent=fmtS(S.pts)+' pts'; 906 updHUD();nextB(); 907} 908function nextB(){if(curB>=maxB){showResult();return}st='waiting';pitcherFrame=0;pitcherDown=false;pitcherDownHR=false;++windupId;ballT=0;flash=0;flashColor='255,255,255';shake=0;ghostMode=false;ghostType='';ghostBounces=[];ghostVisible=true;pWait=30+Math.floor(Math.random()*40);updHUD()} 909function regResult(type){ 910 if(type==='homerun'||type==='triple'||type==='double'||type==='hit'){combo++;
910if(combo>maxCombo)maxCombo=combo}else{ 911 // ãã£ã¨ä¿ºã®ã¿ã¼ã³: ãã¹æã«ã³ã³ãç¶ç¶å¤å® 912 const mtEff=skillVal('my_turn'); 913 if(mtEff&&Math.random()<mtEff.chance){sPops.push({tx:'俺ã®ã¿ã¼ã³ï¼',x:W/2,y:H*.48,t:40,mt:40})} 914 else{combo=0} 915 } 916 isCritical=false; 917 if(active('critical')&&type!=='miss'&&type!=='foul'){const critEff=skillVal('critical');if(critEff&&Math.random()<critEff.value)isCritical=true} 918 let pts=calcPts(type); 919 if(isBomb&&type!=='miss'){totSc=Math.floor(totSc*2)} 920 totSc+=pts;const resEntry={type,pts};if(curEvent){resEntry.eventId=curEvent.id;if(curEvent.diamondPtsMult&&type==='homerun')resEntry.diamondPtsMult=curEvent.diamondPtsMult}resList.push(resEntry);curB++; 921 // âªã¹ã³ã¢è¡¨ç¤º: Ãã³ã³ããå ã«è¡¨ç¤º 922 if(pts>0){let tx='';if(combo>1)tx+=`Ã${combo} `;tx+=`+${fmtS(pts)}`;if(isCritical)tx+=' CRIT!';if(curEvent&&type!=='miss')tx+=` ${curEvent.icon}`;sPops.push({tx,x:W/2,y:H*.56,t:50,mt:50})} 923 lastWasHR=(type==='homerun');fx(type);updHUD(); 924 st='result_wait';pWait=(type==='homerun'?85:55)+60; 925} 926function updHUD(){ 927 document.getElementById('hud-bc').textContent=`${Math.min(curB+1,maxB)} / ${maxB}`; 928 document.getElementById('hud-cb').textContent=combo>1?`${combo} COMBO!`:''; 929} 930function showResult(){ 931 st='finished';document.getElementById('hud').style.display='none'; 932 playBgm(bgmOp); 933 document.getElementById('ch-banner').style.display='none'; 934 let earnPts=totSc;let ptsMult=getEffect('pts_mult',1); 935 // EXTREME BASEBALL: ç´¯è¨HR/10ãptåçã«å ç® 936 if(active('extreme_bb')){const totalHR=S.stats&&S.stats.totalHR?S.stats.totalHR:0;ptsMult+=totalHR/10} 937 earnPts=Math.floor(earnPts*ptsMult); 938 939 // ãã£ã¬ã³ã¸å¤å® 940 challengeCleared=false; 941 let challengeBonus=0; 942 if(curChallenge){ 943 const stats={maxCombo:maxCombo}; 944 challengeCleared=curChallenge.check(resList,stats); 945 if(challengeCleared){challengeBonus=Math.floor(earnPts*(curChallenge.bonus-1));earnPts+=challengeBonus} 946 } 947 948 // ãã¤ã¤ã¢ã³ããã¼ã«: HRæã«æçµç²å¾ptã«ä¹ç® 949 let hasDiamondHR=false; 950 resList.forEach(r=>{if(r.diamondPtsMult)hasDiamondHR=true}); 951 if(hasDiamondHR){ptsMult*=3;earnPts=Math.floor(earnPts*3)} 952 953 // statsæ´æ° 954 if(!S.stats)S.stats={}; 955 S.stats.games=(S.stats.games||0)+1; 956 S.stats.totalBalls=(S.stats.totalBalls||0)+resList.length; 957 S.stats.totalScore=(S.stats.totalScore||0)+totSc; 958 const hrCount=resList.filter(r=>r.type==='homerun').length; 959 const hitCount=resList.filter(r=>r.type!=='miss'&&r.type!=='foul').length; 960 S.stats.totalHR=(S.stats.totalHR||0)+hrCount; 961 S.stats.totalHits=(S.stats.totalHits||0)+hitCount; 962 S.stats.totalTriple=(S.stats.totalTriple||0)+resList.filter(r=>r.type==='triple').length; 963 S.stats.totalDouble=(S.stats.totalDouble||0)+resList.filter(r=>r.type==='double').length; 964 S.stats.totalSingle=(S.stats.totalSingle||0)+resList.filter(r=>r.type==='hit').length; 965 S.stats.totalFoul=(S.stats.totalFoul||0)+resList.filter(r=>r.type==='foul').length; 966 S.stats.totalMiss=(S.stats.totalMiss||0)+resList.filter(r=>r.type==='miss').length; 967 if(maxCombo>(S.stats.bestCombo||0))S.stats.bestCombo=maxCombo; 968 if(hrCount===maxB&&maxB>=3)S.stats.perfectGame=true; 969 if(hrCount===maxB&&maxB===3&&skillLv('chaos')>=9999&&active('one_shot'))S.stats.chaosMaxPerfect=true; 970 // äº¡éæ®ºã: å ¨ã¹ãã«MAX+ON + ãæ¯ãã¢ã¼ã + å ¨çHR 971 if(hrCount===maxB&&active('otawamure')){ 972 let allMax=true;SKILL_TREE.forEach(sk=>{ 973 if(sk.id==='profile_card')return; 974 if(skillLv(sk.id)<(sk.hyperScale?effectiveMaxLv(sk):sk.maxLv))allMax=false; 975 if(sk.toggleable&&S.togOff[sk.id])allMax=false; 976 });if(allMax)S.stats.ghostPerfect=true; 977 } 978 if(challengeCleared)S.stats.challengeClears=(S.stats.challengeClears||0)+1; 979 // ã¤ãã³ãå®ç¸¾ 980 resList.forEach(r=>{ 981 if(r.eventId==='rainbow'&&r.type!=='miss')S.stats.rainbowHit=true; 982 if(r.eventId==='fire'&&r.type!=='miss')S.stats.fireHit=true; 983 }); 984 // å®ç¸¾: è§£é¤åã®ç¶æ ãè¨é² 985 const prevAch={};ACHIEVEMENTS.forEach(a=>{prevAch[a.id]=a.check(S)}); 986 // ãã¤ã«ã¹ãã¼ã³ãã§ãã¯ï¼ã¬ãã«ã¢ããåã®ãè¨é²ï¼ 987 const prevMs=getMilestone(S); 988 S.pts+=earnPts;if(totSc>S.best)S.best=totSc;sv(S); 989 const newMs=getMilestone(S); 990 milestoneJustReached=(newMs&&(!prevMs||newMs.lv>prevMs.lv))?newMs:null; 991 992 // 䏿®µ: ã¹ã³ã¢ã¨åçãå°ãã表示 993 let bkText=`${fmtS(totSc)}`; 994 if(Math.floor(ptsMult)>1)bkText+=` Ã${Math.floor(ptsMult)}`; 995 document.getElementById('r-breakdown').textContent=bkText; 996 // æçµç²å¾ptããã«ãã«è¡¨ç¤º 997 document.getElementById('r-total').textContent=`+${fmtS(earnPts)}`; 998 const c={homerun:0,triple:0,double:0,hit:0,foul:0,miss:0};resList.forEach(r=>c[r.type]++); 999 let d='';if(c.homerun)d+=`HOME RUN x${c.homerun}\n`;if(c.triple)d+=`TRIPLE x${c.triple}\n`;if(c.double)d+=`DOUBLE x${c.double}\n`;if(c.hit)d+=`HIT x${c.hit}\n`;if(c.foul)d+=`FOUL x${c.foul}\n`;if(c.miss)d+=`MISS x${c.miss}\n`; 1000 if(maxCombo>1)d+=`MAX COMBO x${maxCombo}\n`; 1001 // ãã£ã¬ã³ã¸çµæ 1002 if(curChallenge){ 1003 if(challengeCleared)d+=`\n${curChallenge.icon} CHALLENGE CLEAR! +${fmtS(challengeBonus)} pts\n`; 1004 else d+=`\n${curChallenge.icon} CHALLENGE FAILED...\n`; 1005 } 1006 // ãã¤ã«ã¹ãã¼ã³å°é 1007 if(milestoneJustReached)d+=`\n${milestoneJustReached.icon} ${milestoneJustReached.title} å°éï¼\n`; 1008 document.getElementById('r-detail').textContent=d; 1009 if(totSc>=S.best){document.getElementById('r-nb').textContent='NEW BEST!';document.getElementById('r-nb').style.display='block'}else{document.getElementById('r-nb').style.display='none'} 1010 // ⦠å®ç¸¾è§£é¤éç¥ 1011 const achEl=document.getElementById('r-ach-notify');achEl.innerHTML='';
1012 const newAchs=[];ACHIEVEMENTS.forEach(a=>{if(!prevAch[a.id]&&a.check(S))newAchs.push(a)}); 1013 newAchs.forEach(a=>{ 1014 const div=document.createElement('div');div.className='r-ach-item'; 1015 div.textContent=`ð ${a.icon} ${a.name} ã®å®ç¸¾ãã¯ãªã¢ï¼`; 1016 if(a.id==='chaos_perfect'){div.textContent+=' ðå®ç¸¾ç»é¢ã§ã¿ããï¼';div.style.cursor='pointer'; 1017 div.onclick=()=>{document.getElementById('result').style.display='none';openAch()}} 1018 achEl.appendChild(div); 1019 }); 1020 document.getElementById('result').style.display='flex'; 1021} 1022 1023// ============ Tap ============ 1024function onTap(){ea();if(st==='pitching'){const type=judge(); 1025 // å¿ç¼: ãã¡ã¦ã«æããç´ãï¼ãã¼ã«ã¦ã³ãï¼ 1026 if(type==='foul'&&active('shingan')){ 1027 snd('miss');sPops.push({tx:'å¿ç¼ï¼',x:W/2,y:H*.48,t:40,mt:40}); 1028 st='waiting';pWait=30+Math.floor(Math.random()*20);return} 1029 regResult(type)}} 1030cv.addEventListener('touchstart',e=>{e.preventDefault();onTap()},{passive:false}); 1031cv.addEventListener('mousedown',onTap); 1032 1033// ============ Skill Tree UI ============ 1034let treeBranch='power';let treeFrom='title'; 1035function openTree(from){treeFrom=from;renderTree();document.getElementById('tree').style.display='flex'} 1036document.getElementById('tr-maxall').onclick=()=>{ 1037 let bought=0,changed=true; 1038 while(changed){changed=false;SKILL_TREE.forEach(sk=>{ 1039 if(canUnlock(sk.id)){if(unlockSkill(sk.id)){bought++;changed=true}} 1040 })} 1041 if(bought>0){snd('buy');renderTree();updSpot()} 1042}; 1043function closeTree(){ 1044 document.getElementById('tree').style.display='none'; 1045 if(treeFrom==='result')document.getElementById('result').style.display='flex'; 1046 else{showTitle();document.getElementById('title').style.display='flex'} 1047} 1048function renderTree(){ 1049 document.getElementById('tr-pts').textContent=fmtS(S.pts)+' pts'; 1050 const tabEl=document.getElementById('tr-tabs');tabEl.innerHTML=''; 1051 ['power','technique','wild','center'].forEach(bk=>{ 1052 const b=BRANCHES[bk];const tab=document.createElement('div'); 1053 tab.className='tr-tab'+(bk===treeBranch?' active':''); 1054 if(bk===treeBranch){tab.style.borderColor=b.color;tab.style.color=b.color;tab.style.background=b.bg} 1055 tab.textContent=b.icon+' '+b.name;tab.onclick=()=>{treeBranch=bk;renderTree()};tabEl.appendChild(tab); 1056 }); 1057 const listEl=document.getElementById('tr-list');listEl.innerHTML=''; 1058 const allSkills=SKILL_TREE.filter(s=>s.branch===treeBranch).sort((a,b)=>a.ring-b.ring); 1059 // ã«ãªã¹è§£æ¾åã®ã¹ãã«ã¯é表示ï¼unlockæ¡ä»¶ãã«ãªã¹ä¾åãã¤Lv0ï¼ 1060 const skills=allSkills.filter(sk=>{ 1061 if(skillLv(sk.id)>=1)return true; // æ¢ã«å徿¸ã¿ãªã常ã«è¡¨ç¤º 1062 if(!sk.unlock)return true; // unlockæ¡ä»¶ããªããã°å¸¸ã«è¡¨ç¤º 1063 return sk.unlock(S); // è§£æ¾æ¡ä»¶ãæºããã¦ããã°è¡¨ç¤º 1064 }); 1065 const branchColor=BRANCHES[treeBranch].color; 1066 const hyperBonus=getHyperLvBonus(S); 1067 1068 skills.forEach((sk,idx)=>{ 1069 if(idx>0){ 1070 const conn=document.createElement('div');conn.className='tr-conn'; 1071 const prevSk=skills[idx-1]; 1072 const prevMax=skillLv(prevSk.id)>=prevSk.maxLv; 1073 conn.style.background=prevMax?branchColor:'rgba(255,255,255,.1)';listEl.appendChild(conn); 1074 } 1075 const lv=skillLv(sk.id); 1076 const effMax=effectiveMaxLv(sk); 1077 const isMax=lv>=effMax; 1078 const avail=isSkillAvailable(sk.id); 1079 const canBuy=canUnlock(sk.id); 1080 const locked=lv===0&&!avail; 1081 1082 const node=document.createElement('div'); 1083 node.className='tr-node'+(locked?' locked':'')+(isMax?' maxed':''); 1084 node.style.background=locked?'rgba(255,255,255,.02)':BRANCHES[treeBranch].bg; 1085 1086 const icon=document.createElement('div');icon.className='tr-icon'; 1087 icon.style.borderColor=locked?'rgba(255,255,255,.1)':branchColor; 1088 if(isMax){icon.style.background='rgba(255,215,0,.2)';icon.style.borderColor='#FFD700';icon.textContent='ð'} 1089 else if(lv>0){icon.style.background=BRANCHES[treeBranch].bg;icon.textContent=BRANCHES[treeBranch].icon} 1090 else if(avail){icon.textContent=BRANCHES[treeBranch].icon} 1091 else{icon.textContent='ð'} 1092 node.appendChild(icon); 1093 1094 const info=document.createElement('div');info.className='tr-info'; 1095 const nameRow=document.createElement('div');nameRow.className='tr-name';nameRow.textContent=sk.name; 1096 // level badge 1097 if(effMax>1){ 1098 const lvBadge=document.createElement('span');lvBadge.className='tr-lv'; 1099 if(sk.hyperScale&&hyperBonus>0)lvBadge.textContent=`Lv ${lv}/${effMax}(+${hyperBonus})`; 1100 else lvBadge.textContent=`Lv ${lv}/${effMax}`; 1101 if(isMax){lvBadge.style.background='rgba(255,215,0,.2)';lvBadge.style.color='#FFD700'} 1102 nameRow.appendChild(lvBadge); 1103 } 1104 info.appendChild(nameRow); 1105 1106 // desc â å ¨ã¦descFnã§åççæ 1107 const desc=document.createElement('div');desc.className='tr-desc'; 1108 if(locked){desc.textContent='???'} 1109 else if(lv>0&&lv<effMax){ 1110 desc.textContent=sk.descFn(lv)+' â æ¬¡: '+sk.descFn(lv+1); 1111 }else if(lv===0){ 1112 desc.textContent=sk.descFn(1); 1113 }else{ 1114 desc.textContent=sk.descFn(lv); 1115 } 1116 info.appendChild(desc); 1117 1118 // toggle for one_shot 1119 if(sk.toggleable&&lv>0){ 1120 const togDiv=document.createElement('div');togDiv.className='tr-toggle'; 1121 const togLabel=document.createElement('span');togLabel.className='tr-toggle-label';togLabel.textContent=S.togOff[sk.id]?'OFF':'ON'; 1122 const togWrap=document.createElement('label');togWrap.className='tr-sw'; 1123 togWrap.innerHTML=`<input type="checkbox" ${S.togOff[sk.id]?'':'checked'}><span class="sl"></span>`;
1124 togWrap.querySelector('input').onchange=e=>{ 1125 if(e.target.checked){delete S.togOff[sk.id]}else{S.togOff[sk.id]=true} 1126 sv(S);renderTree(); 1127 }; 1128 togDiv.appendChild(togLabel);togDiv.appendChild(togWrap);info.appendChild(togDiv); 1129 } 1130 1131 // cost 1132 if(!isMax&&!locked){ 1133 const costDiv=document.createElement('div');costDiv.className='tr-cost'; 1134 const c=getSkillCost(sk.id);costDiv.textContent=fmtS(c)+' pt'; 1135 if(S.pts<c)costDiv.style.color='#EF4444';info.appendChild(costDiv); 1136 } 1137 node.appendChild(info); 1138 1139 // ãã¿ã³å 1140 const btnCol=document.createElement('div');btnCol.style.cssText='display:flex;gap:4px;flex-shrink:0;flex-direction:column;align-items:center'; 1141 // åçè³¼å ¥ï¼ultimate/legendç¨ï¼ 1142 if((sk.id==='ultimate'||sk.id==='legend'||sk.id==='chaos')&&lv>0&&!isMax){ 1143 const mults=sk.id==='chaos'?[1,10,100]:[1,5,10]; 1144 mults.forEach(m=>{ 1145 const mb=document.createElement('button');mb.className='tr-btn'; 1146 const totalCost=calcMultiCost(sk.id,m); 1147 const canAfford=S.pts>=totalCost&&(lv+m<=effectiveMaxLv(sk)); 1148 const actualM=Math.min(m,effectiveMaxLv(sk)-lv); 1149 if(canAfford&&actualM>0){ 1150 mb.className+=' unlock';mb.textContent=`Ã${m}`;mb.style.cssText='padding:.25rem .5rem;font-size:.6rem;min-width:40px'; 1151 mb.addEventListener('click',e=>{e.preventDefault();for(let i=0;i<actualM;i++){if(!unlockSkill(sk.id))break}snd('buy');renderTree();updSpot()}); 1152 }else{ 1153 mb.disabled=true;mb.textContent=`Ã${m}`;mb.style.cssText='padding:.25rem .5rem;font-size:.6rem;min-width:40px'; 1154 } 1155 btnCol.appendChild(mb); 1156 }); 1157 }else{ 1158 const btn=document.createElement('button');btn.className='tr-btn'; 1159 if(isMax){btn.className+=' maxed';btn.textContent='MAX';btn.disabled=true} 1160 else if(canBuy){btn.className+=' unlock';btn.textContent=lv>0?'LV UP':'UNLOCK'; 1161 btn.addEventListener('click',e=>{e.preventDefault();if(unlockSkill(sk.id)){snd('buy');renderTree();updSpot()}}); 1162 }else{btn.disabled=true;btn.textContent=locked?'ð':lv>0?'LV UP':'UNLOCK'} 1163 btnCol.appendChild(btn); 1164 } 1165 // ãæå¤§ããã¿ã³ï¼MAXæªå°éï¼ããã¯è§£é¤æ¸ã¿ï¼è³¼å ¥å¯è½ãªå ´åï¼ 1166 if(!isMax&&!locked&&lv>=0){ 1167 const maxBtn=document.createElement('button');maxBtn.className='tr-btn'; 1168 maxBtn.style.cssText='padding:.25rem .5rem;font-size:.55rem;min-width:40px;background:#b8860b;color:#fff'; 1169 // æå¤§ä½ã¬ãã«è²·ãããè¨ç® 1170 let maxLvs=0,tempPts=S.pts,tmpLv=lv; 1171 while(tmpLv<effectiveMaxLv(sk)){ 1172 const c=sk.costFn(tmpLv+1); 1173 if(tempPts<c)break; 1174 tempPts-=c;tmpLv++;maxLvs++; 1175 } 1176 if(maxLvs>1){ 1177 maxBtn.className+=' unlock';maxBtn.textContent='æå¤§'; 1178 maxBtn.addEventListener('click',e=>{e.preventDefault();let bought=0;while(unlockSkill(sk.id))bought++;if(bought>0){snd('buy');renderTree();updSpot()}}); 1179 btnCol.appendChild(maxBtn); 1180 } 1181 } 1182 node.appendChild(btnCol); 1183 listEl.appendChild(node); 1184 }); 1185} 1186 1187// ============ Achievements UI ============ 1188let achFrom='title'; 1189function openAch(from){achFrom=from;renderAch();document.getElementById('achieve').style.display='flex'} 1190function closeAch(){ 1191 document.getElementById('achieve').style.display='none'; 1192 if(achFrom==='result')document.getElementById('result').style.display='flex'; 1193 else{showTitle();document.getElementById('title').style.display='flex'} 1194} 1195function renderAch(){ 1196 let unlocked=0; 1197 const list=document.getElementById('ach-list');list.innerHTML=''; 1198 ACHIEVEMENTS.forEach(a=>{ 1199 const done=a.check(S);if(done)unlocked++; 1200 const isHidden=a.hidden&&a.showCondition&&!a.showCondition(S)&&!done; 1201 const node=document.createElement('div');node.className='ach-node'+(done?' unlocked':''); 1202 // éçæ®ºãè§£æ¾æ¸ã¿âã¯ãªãã¯å¯è½ 1203 if(done&&a.id==='chaos_perfect'){node.className+=' clickable';node.style.cursor='pointer'; 1204 node.addEventListener('click',()=>{document.getElementById('achieve').style.display='none';showEnding()})} 1205 const icon=document.createElement('div');icon.className='ach-icon'+(done?'':' locked');icon.textContent=isHidden?'â':a.icon; 1206 const info=document.createElement('div');info.className='ach-info'; 1207 const dispName=isHidden?'???':a.name; 1208 const dispDesc=isHidden?'???':a.desc; 1209 info.innerHTML=`<div class="ach-name"${done?'':' style="color:#666"'}>${dispName}</div><div class="ach-desc"${done?'':' style="color:#555"'}>${dispDesc}</div>`; 1210 const chk=document.createElement('div');chk.className='ach-check';chk.textContent=done?'â ':'ð'; 1211 // éçæ®ºãè§£æ¾æ¸ã¿ââ¶ï¸ã§åçã示å 1212 if(done&&a.id==='chaos_perfect'){chk.textContent='â¶ï¸'} 1213 node.appendChild(icon);node.appendChild(info);node.appendChild(chk);list.appendChild(node); 1214 }); 1215 document.getElementById('ach-count').textContent=`${unlocked} / ${ACHIEVEMENTS.length} éæ`; 1216}
1217document.getElementById('ach-back').onclick=closeAch; 1218 1219// ============ Status UI ============ 1220function openStatus(){ 1221 renderStatus();document.getElementById('status').style.display='flex'; 1222} 1223function closeStatus(){ 1224 document.getElementById('status').style.display='none'; 1225 showTitle();document.getElementById('title').style.display='flex'; 1226} 1227function renderStatus(){ 1228 const list=document.getElementById('stat-list');list.innerHTML=''; 1229 const st=S.stats||{}; 1230 // --- æ¦ç¸¾ã»ã¯ã·ã§ã³ --- 1231 addStatSection(list,'â¾ æ¦ç¸¾',[ 1232 ['ð®','ç´¯è¨è©¦åæ°',fmt(st.games||0)], 1233 ['â¾','ç´¯è¨æçæ°',fmt(st.totalBalls||0)], 1234 ['ð','ç´¯è¨ã¹ã³ã¢',fmtS(st.totalScore||0)], 1235 ['ð','ãã¹ãã¹ã³ã¢',fmtS(S.best||0)], 1236 ['ð°','ææãã¤ã³ã',fmtS(S.pts||0)], 1237 ]); 1238 // --- ææã»ã¯ã·ã§ã³ --- 1239 const tb=st.totalBalls||0;const th=st.totalHits||0; 1240 const avg=tb>0?(th/tb*100).toFixed(1)+'%':'--'; 1241 addStatSection(list,'ð æææç¸¾',[ 1242 ['ð¥','ç´¯è¨HR',fmt(st.totalHR||0)], 1243 ['ðº','ç´¯è¨TRIPLE',fmt(st.totalTriple||0)], 1244 ['ð¸','ç´¯è¨DOUBLE',fmt(st.totalDouble||0)], 1245 ['ð¹','ç´¯è¨HIT',fmt(st.totalSingle||0)], 1246 ['âª','ç´¯è¨FOUL',fmt(st.totalFoul||0)], 1247 ['â','ç´¯è¨MISS',fmt(st.totalMiss||0)], 1248 ['ð','æç(MISS/FOULé¤å¤)',avg], 1249 ['ð','æå¤§ã³ã³ã',fmt(st.bestCombo||0)], 1250 ]); 1251 // --- è½åå¤ã»ã¯ã·ã§ã³ --- 1252 const scoreMult=getEffect('score_mult',0); 1253 const spotAdd=getEffect('spot_add',0); 1254 const speedMult=getEffect('speed_mult',1); 1255 const ptsMult=getEffect('pts_mult',1); 1256 const goubakuEff=active('goubaku')?skillVal('goubaku'):null; 1257 const goubakuAdd=goubakuEff?goubakuEff.hrZoneAdd:0; 1258 const giantEff=skillVal('giant_bat'); 1259 const hrExtra=giantEff?giantEff.hrZone:0; 1260 const totalHrZone=((HR_ZONE_BASE_RATIO+hrExtra+goubakuAdd)*100).toFixed(0); 1261 const masaiEff=active('masai')?skillVal('masai'):null; 1262 const ballScale=masaiEff?((masaiEff.ballScale-1)*100).toFixed(0):'0'; 1263 const jaganEff=active('jagan')?skillVal('jagan'):null; 1264 const slowTime=jaganEff?jaganEff.freezeTime.toFixed(1):'0'; 1265 const critEff=active('critical')?skillVal('critical'):null; 1266 const critRate=critEff?((critEff.value)*100).toFixed(0):'0'; 1267 const meikyoEff2=active('meikyo')?skillVal('meikyo'):null; 1268 const meikyoSpot=meikyoEff2?'-'+((1-meikyoEff2.spotScale)*100).toFixed(0)+'%':'--'; 1269 const meikyoScore=meikyoEff2?'Ã'+meikyoEff2.scoreMult:'--'; 1270 addStatSection(list,'â¡ ç¾å¨ã®è½åå¤',[ 1271 ['ðª','ã¹ã³ã¢åç','+'+(scoreMult*100).toFixed(0)+'%'], 1272 ['ð¯','ãã¼ãæ¡å¤§','+'+(spotAdd*100).toFixed(0)+'%'], 1273 ['ð¢','çéå¤å',((1-speedMult)*100).toFixed(1)+'%æ¸'], 1274 ['ð°','ptåç','Ã'+ptsMult], 1275 ['ð´','HRã¾ã¼ã³',totalHrZone+'%'], 1276 ['â¾','ãã¼ã«ãµã¤ãº','+'+ballScale+'%'], 1277 ['ð','éªç¼åæ¢æé',slowTime+'ç§'], 1278 ['â¡','ã¯ãªãã£ã«ã«ç',critRate+'%'], 1279 ['ð§','æé¡æ¢æ°´ãã¼ã',meikyoSpot], 1280 ['ð§','æé¡æ¢æ°´ã¹ã³ã¢',meikyoScore], 1281 ['â¾','EX ã¹ã³ã¢å ç®',active('extreme_bb')?'+'+(S.stats&&S.stats.games?S.stats.games:0)+'%':'--'], 1282 ['â¾','EX ptåçå ç®',active('extreme_bb')?'+'+(S.stats&&S.stats.totalHR?(S.stats.totalHR/10).toFixed(1):0):'--'], 1283 ]); 1284 // --- ã¹ãã«Lv --- 1285 const skCount=SKILL_TREE.filter(sk=>skillLv(sk.id)>=1).length; 1286 addStatSection(list,'ð ã¹ãã«',[ 1287 ['ð','ç¿å¾ã¹ãã«æ°',skCount+'/'+SKILL_TREE.length], 1288 ['ð ','ãã£ã¬ã³ã¸ã¯ãªã¢',fmt(st.challengeClears||0)], 1289 ]); 1290} 1291function addStatSection(parent,title,rows){ 1292 const sec=document.createElement('div');sec.className='stat-section'; 1293 const h=document.createElement('div');h.className='stat-section-title';h.textContent=title;sec.appendChild(h); 1294 rows.forEach(r=>{ 1295 const row=document.createElement('div');row.className='stat-row'; 1296 row.innerHTML=`<span class="stat-label">${r[0]} ${r[1]}</span><span class="stat-value">${r[2]}</span>`; 1297 sec.appendChild(row); 1298 }); 1299 parent.appendChild(sec); 1300} 1301function fmt(n){return n.toLocaleString()} 1302// ç縮ã¹ã³ã¢è¡¨è¨ (1K, 1M, 1B, 1T, 1aa, 1ab...) 1303function fmtS(n){ 1304 if(n<0)return'-'+fmtS(-n);
1305 if(n<10000)return n.toLocaleString(); 1306 const units=['','K','M','B','T']; 1307 // T以é: aa,ab,...az,ba,...zz 1308 function bigUnit(idx){ 1309 if(idx<5)return units[idx]; 1310 const i=idx-5;const a=String.fromCharCode(97+(i/26|0));const b=String.fromCharCode(97+i%26);return a+b; 1311 } 1312 let tier=0,v=n; 1313 while(v>=1000&&tier<30){v/=1000;tier++} 1314 return (tier>=1?(v>=100?v.toFixed(0):v>=10?v.toFixed(1):v.toFixed(2))+bigUnit(tier):n.toLocaleString()); 1315} 1316document.getElementById('stat-back').onclick=closeStatus; 1317 1318// ============ Ball List UI ============ 1319const BALL_LIST=[ 1320 {img:'ball.png',name:'ãã¼ãã«ãã¼ã«',icon:'â¾',desc:'æ®éã®çãéçã®æçã®ä¸ã§ã¯ãã¡ã°ãåªãããã¡ãªã¿ã«ç¡¬çã'}, 1321 {img:'Golden.png',name:'ã´ã¼ã«ãã³ãã¼ã«',icon:'ð',desc:'é»éã«è¼ãç¹å¥ãªçãæã¦ã°ã¹ã³ã¢ã50åã«ãªããã´ã¼ã«ãã³ãªãã ãããããããå½ç¶ã ãã'}, 1322 {img:'fire.png',name:'ãã¡ã¤ã¤ã¼ãã¼ã«',icon:'ð¥',desc:'ç¼ç±ã®çãçºããæ£æ°ãããªãé度ã§è¿«ãéçãã§ãéããã¦ã°ã©ãã£ãã¯ãè¦ããªã'}, 1323 {img:'diamond.png',name:'ãã¤ã¤ã¢ã³ããã¼ã«',icon:'ð',desc:'å®ç³ã®ããã«ç¾ããè¼ãçããã¼ã ã©ã³ã§æã¡è¿ãã°æçµç²å¾ptã3åã«ãªãããããªãã¨ããããããæããã®ã§ã¯ï¼'}, 1324 {img:'rainbow.png',name:'ã¬ã¤ã³ãã¼ãã¼ã«',icon:'ð',desc:'ä¸è²ã®å ãæ¾ã¤å¥è·¡ã®çã触ãããããã°ããã¹ã¦ããã¼ã ã©ã³ã«ãªãã¹ã³ã¢20åãå¥è·¡ã£ã¦ããã'}, 1325 {img:'ghost.png',name:'ã´ã¼ã¹ããã¼ã«ããã³ãã¼ã«ã',icon:'ð»',desc:'å£ãè·³ãè¿ããªããä¸è¦åã«è¿«ã亡éã®çãããã«ãããã°ãã¦ãªãã®ã§æã¦ãªããæã¦ããããã'}, 1326 {img:'ghost.png',name:'ã´ã¼ã¹ããã¼ã«ãæ¶ããéçã',icon:'ð»',desc:'ãã£ããã¨ããããå§¿ãæ¶ããªããè¿«ããåã§æã¤ãã ã'}, 1327]; 1328function openBallList(){ 1329 const list=document.getElementById('bl-list');list.innerHTML=''; 1330 BALL_LIST.forEach(b=>{ 1331 const card=document.createElement('div');card.className='bl-card'; 1332 const img=document.createElement('img');img.className='bl-img';img.src=b.img; 1333 const info=document.createElement('div');info.className='bl-info'; 1334 info.innerHTML=`<div class="bl-name">${b.name}</div><div class="bl-desc">${b.desc}</div>`; 1335 card.appendChild(img);card.appendChild(info);list.appendChild(card); 1336 }); 1337 document.getElementById('title').style.display='none'; 1338 document.getElementById('balllist').style.display='flex'; 1339} 1340function closeBallList(){ 1341 document.getElementById('balllist').style.display='none'; 1342 showTitle();document.getElementById('title').style.display='flex'; 1343} 1344document.getElementById('bl-back').onclick=closeBallList; 1345 1346// ============ Profile Card ============ 1347function loadPlayerName(){try{return localStorage.getItem('aeb_pname')||''}catch(e){return''}} 1348function savePlayerName(n){try{localStorage.setItem('aeb_pname',n)}catch(e){}} 1349 1350function openProfile(){ 1351 document.getElementById('title').style.display='none'; 1352 document.getElementById('profile').style.display='flex'; 1353 document.getElementById('pf-name').value=loadPlayerName()||''; 1354 generateProfileCard(); 1355} 1356function closeProfile(){ 1357 document.getElementById('profile').style.display='none'; 1358 showTitle();document.getElementById('title').style.display='flex'; 1359} 1360document.getElementById('pf-back').onclick=closeProfile; 1361document.getElementById('pf-name').addEventListener('input',function(){ 1362 savePlayerName(this.value);generateProfileCard(); 1363}); 1364document.getElementById('pf-dl').onclick=function(){ 1365 const canvas=document.getElementById('pf-canvas'); 1366 // fullscreen overlay with the card image 1367 const ov=document.createElement('div'); 1368 ov.style.cssText='position:fixed;inset:0;z-index:9999;background:#000;display:flex;align-items:center;justify-content:center;cursor:pointer'; 1369 const img=new Image();img.src=canvas.toDataURL('image/png'); 1370 img.style.cssText='max-width:100%;max-height:100%;object-fit:contain'; 1371 ov.appendChild(img); 1372 ov.onclick=()=>ov.remove(); 1373 document.body.appendChild(ov); 1374}; 1375 1376function generateProfileCard(){ 1377 const cv=document.getElementById('pf-canvas'); 1378 const ctx=cv.getContext('2d'); 1379 const W=1080,H=1920;cv.width=W;cv.height=H; 1380 const name=document.getElementById('pf-name').value||'NO NAME'; 1381 const st=S.stats||{}; 1382 const F='"Helvetica Neue",Arial,sans-serif'; 1383 1384 // === BG === 1385 const bg=ctx.createRadialGradient(W/2,H*0.25,0,W/2,H*0.25,W); 1386 bg.addColorStop(0,'#1a1035');bg.addColorStop(0.6,'#0d0d1f');bg.addColorStop(1,'#050510'); 1387 ctx.fillStyle=bg;ctx.fillRect(0,0,W,H); 1388 1389 // subtle grid 1390 ctx.save();ctx.globalAlpha=0.03;ctx.strokeStyle='#fff';ctx.lineWidth=1; 1391 for(let i=0;i<W;i+=60){ctx.beginPath();ctx.moveTo(i,0);ctx.lineTo(i,H);ctx.stroke()} 1392 for(let i=0;i<H;i+=60){ctx.beginPath();ctx.moveTo(0,i);ctx.lineTo(W,i);ctx.stroke()}
1393 ctx.restore(); 1394 1395 // accent glow behind image 1396 const glow=ctx.createRadialGradient(W/2,400,0,W/2,400,600); 1397 glow.addColorStop(0,'rgba(255,215,0,0.08)');glow.addColorStop(0.5,'rgba(255,107,53,0.03)');glow.addColorStop(1,'transparent'); 1398 ctx.fillStyle=glow;ctx.fillRect(0,0,W,900); 1399 1400 // top bar 1401 const bar=ctx.createLinearGradient(0,0,W,0); 1402 bar.addColorStop(0,'#FFD700');bar.addColorStop(0.4,'#FF8C00');bar.addColorStop(1,'#FF1744'); 1403 ctx.fillStyle=bar;ctx.fillRect(0,0,W,6); 1404 1405 // diagonal lines 1406 ctx.save();ctx.globalAlpha=0.04;ctx.strokeStyle='#FFD700';ctx.lineWidth=1; 1407 for(let i=-H;i<W+H;i+=80){ctx.beginPath();ctx.moveTo(i,0);ctx.lineTo(i+H,H);ctx.stroke()} 1408 ctx.restore(); 1409 1410 // === GAME TITLE === 1411 ctx.textAlign='center';ctx.fillStyle='rgba(255,255,255,0.3)'; 1412 ctx.font=`600 26px ${F}`; 1413 const ttl='ARAKI EXTREME BASEBALL'; 1414 let tx=W/2-ctx.measureText(ttl).width*0.65; 1415 for(let i=0;i<ttl.length;i++){ctx.fillText(ttl[i],tx,54);tx+=ctx.measureText(ttl[i]).width+7} 1416 1417 // === PROFILE IMAGE (big, rectangular) === 1418 let cy=80; 1419 if(imgs.profile){ 1420 const img=imgs.profile; 1421 const iw=img.naturalWidth,ih=img.naturalHeight; 1422 const maxW=W-120,maxH=750; 1423 const scale=Math.min(maxW/iw,maxH/ih); 1424 const dw=iw*scale,dh=ih*scale; 1425 const ix=W/2-dw/2,iy=cy; 1426 // subtle shadow behind image 1427 ctx.shadowColor='rgba(0,0,0,0.5)';ctx.shadowBlur=40;ctx.shadowOffsetY=10; 1428 ctx.drawImage(img,ix,iy,dw,dh); 1429 ctx.shadowBlur=0;ctx.shadowOffsetY=0; 1430 // thin gold border 1431 ctx.strokeStyle='rgba(255,215,0,0.2)';ctx.lineWidth=2; 1432 ctx.strokeRect(ix-1,iy-1,dw+2,dh+2); 1433 cy=iy+dh+50; 1434 } 1435 1436 // === PLAYER NAME === 1437 ctx.textAlign='center'; 1438 ctx.shadowColor='rgba(255,215,0,0.5)';ctx.shadowBlur=50; 1439 const nameGrad=ctx.createLinearGradient(W*0.15,0,W*0.85,0); 1440 nameGrad.addColorStop(0,'#FFD700');nameGrad.addColorStop(0.5,'#FFF');nameGrad.addColorStop(1,'#FFD700'); 1441 ctx.fillStyle=nameGrad; 1442 let nameSize=100;ctx.font=`900 ${nameSize}px ${F}`; 1443 let nm=name;while(ctx.measureText(nm).width>W-120&&nameSize>40){nameSize-=3;ctx.font=`900 ${nameSize}px ${F}`} 1444 ctx.fillText(nm,W/2,cy+nameSize*0.8); 1445 ctx.shadowBlur=0; 1446 cy+=nameSize+50; 1447 1448 // === DIVIDER === 1449 const dv=ctx.createLinearGradient(80,0,W-80,0); 1450 dv.addColorStop(0,'transparent');dv.addColorStop(0.3,'rgba(255,215,0,0.3)'); 1451 dv.addColorStop(0.7,'rgba(255,215,0,0.3)');dv.addColorStop(1,'transparent'); 1452 ctx.fillStyle=dv;ctx.fillRect(80,cy,W-160,2); 1453 cy+=60; 1454 1455 // === STAT CARDS (2x2) === 1456 const stats=[ 1457 {label:'BEST SCORE',value:fmtS(S.best||0),color:'#FFD700'}, 1458 {label:'GAMES',value:fmt(st.games||0),color:'#3B82F6'}, 1459 {label:'HOME RUNS',value:fmt(st.totalHR||0),color:'#FF6B35'}, 1460 {label:'HIT RATE',value:st.totalBalls>0?((st.totalHits||0)/st.totalBalls*100).toFixed(1)+'%':'--',color:'#4ADE80'}, 1461 ]; 1462 const cardW=440,cardH=170,gap=36; 1463 const gridX=(W-cardW*2-gap)/2; 1464 const gridY=cy;
1465 stats.forEach((s,i)=>{ 1466 const col=i%2,row=Math.floor(i/2); 1467 const cx=gridX+col*(cardW+gap),ccy=gridY+row*(cardH+gap); 1468 // card bg 1469 ctx.fillStyle='rgba(255,255,255,0.03)'; 1470 roundRect(ctx,cx,ccy,cardW,cardH,16);ctx.fill(); 1471 // left accent 1472 const accG=ctx.createLinearGradient(cx,ccy,cx,ccy+cardH); 1473 accG.addColorStop(0,s.color);accG.addColorStop(1,'transparent'); 1474 ctx.fillStyle=accG;roundRect(ctx,cx,ccy,5,cardH,2);ctx.fill(); 1475 // border 1476 ctx.strokeStyle='rgba(255,255,255,0.06)';ctx.lineWidth=1; 1477 roundRect(ctx,cx,ccy,cardW,cardH,16);ctx.stroke(); 1478 // label 1479 ctx.textAlign='left';ctx.fillStyle='rgba(255,255,255,0.45)'; 1480 ctx.font=`700 22px ${F}`;ctx.fillText(s.label,cx+30,ccy+48); 1481 // value 1482 ctx.fillStyle=s.color; 1483 let valSize=64;ctx.font=`900 ${valSize}px ${F}`; 1484 if(ctx.measureText(s.value).width>cardW-60){valSize=48;ctx.font=`900 ${valSize}px ${F}`} 1485 ctx.fillText(s.value,cx+30,ccy+125); 1486 }); 1487 cy=gridY+cardH*2+gap+50; 1488 1489 // === DIVIDER 2 === 1490 const dv2=ctx.createLinearGradient(80,0,W-80,0); 1491 dv2.addColorStop(0,'transparent');dv2.addColorStop(0.3,'rgba(255,255,255,0.12)'); 1492 dv2.addColorStop(0.7,'rgba(255,255,255,0.12)');dv2.addColorStop(1,'transparent'); 1493 ctx.fillStyle=dv2;ctx.fillRect(80,cy,W-160,1); 1494 cy+=45; 1495 1496 // === SPECIAL BADGES === 1497 const badges=[]; 1498 if(st.perfectGame)badges.push({t:'PERFECT GAME',c:'#FFD700'}); 1499 if(st.chaosMaxPerfect)badges.push({t:'DEMON SLAYER',c:'#FF1744'}); 1500 if(st.ghostPerfect)badges.push({t:'GHOST SLAYER',c:'#E040FB'}); 1501 if(st.rainbowHit)badges.push({t:'RAINBOW',c:'#FF69B4'}); 1502 if(st.fireHit)badges.push({t:'INFERNO',c:'#FF4500'}); 1503 if(badges.length>0){ 1504 ctx.font=`800 22px ${F}`; 1505 let totalBW=0;badges.forEach(b=>{totalBW+=ctx.measureText(b.t).width+44}); 1506 totalBW+=(badges.length-1)*14; 1507 let bx=W/2-totalBW/2; 1508 badges.forEach(b=>{ 1509 const tw=ctx.measureText(b.t).width+44; 1510 ctx.fillStyle='rgba(0,0,0,0.4)';roundRect(ctx,bx,cy-20,tw,40,20);ctx.fill(); 1511 ctx.strokeStyle=b.c;ctx.lineWidth=2;ctx.globalAlpha=0.7; 1512 roundRect(ctx,bx,cy-20,tw,40,20);ctx.stroke();ctx.globalAlpha=1; 1513 ctx.fillStyle=b.c;ctx.textAlign='center';ctx.fillText(b.t,bx+tw/2,cy+6); 1514 bx+=tw+14; 1515 }); 1516 } 1517 1518 // === BOTTOM BAR === 1519 const btm=ctx.createLinearGradient(0,0,W,0); 1520 btm.addColorStop(0,'#FFD700');btm.addColorStop(0.4,'#FF8C00');btm.addColorStop(1,'#FF1744'); 1521 ctx.fillStyle=btm;ctx.fillRect(0,H-6,W,6); 1522 1523 // === FOOTER === 1524 ctx.textAlign='center';ctx.fillStyle='rgba(255,255,255,0.15)'; 1525 ctx.font=`600 18px ${F}`; 1526 ctx.fillText('ARAKI EXTREME BASEBALL #ARAKIbaseball',W/2,H-22); 1527 1528 // corner accents 1529 ctx.save();ctx.globalAlpha=0.08;ctx.strokeStyle='#FFD700';ctx.lineWidth=2; 1530 ctx.beginPath();ctx.moveTo(24,60);ctx.lineTo(24,24);ctx.lineTo(60,24);ctx.stroke(); 1531 ctx.beginPath();ctx.moveTo(W-60,24);ctx.lineTo(W-24,24);ctx.lineTo(W-24,60);ctx.stroke(); 1532 ctx.beginPath();ctx.moveTo(24,H-60);ctx.lineTo(24,H-24);ctx.lineTo(60,H-24);ctx.stroke(); 1533 ctx.beginPath();ctx.moveTo(W-60,H-24);ctx.lineTo(W-24,H-24);ctx.lineTo(W-24,H-60);ctx.stroke(); 1534 ctx.restore(); 1535} 1536 1537// roundRect helper 1538function roundRect(ctx,x,y,w,h,r){ 1539 ctx.beginPath();ctx.moveTo(x+r,y);ctx.lineTo(x+w-r,y);ctx.quadraticCurveTo(x+w,y,x+w,y+r); 1540 ctx.lineTo(x+w,y+h-r);ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h); 1541 ctx.lineTo(x+r,y+h);ctx.quadraticCurveTo(x,y+h,x,y+h-r); 1542 ctx.lineTo(x,y+r);ctx.quadraticCurveTo(x,y,x+r,y);ctx.closePath(); 1543} 1544 1545// ============ Reset ============ 1546function doReset(){ 1547 localStorage.removeItem('aeb_save'); 1548 S=ld();sv(S); 1549 document.getElementById('confirm').style.display='none'; 1550 showTitle();document.getElementById('title').style.display='flex'; 1551} 1552document.getElementById('cf-yes').onclick=doReset; 1553document.getElementById('cf-no').onclick=()=>{document.getElementById('confirm').style.display='none'}; 1554 1555// ============ Title ============ 1556function showTitle(){ 1557 S=ld();playBgm(bgmOp); 1558 // ãã¤ã«ã¹ãã¼ã³è¡¨ç¤º 1559 const ms=getMilestone(S);const nextMs=getNextMilestone(S); 1560 const msEl=document.getElementById('t-ms'); 1561 if(ms){ 1562 msEl.innerHTML=`<span class="ms-icon">${ms.icon}</span> <span style="color:${ms.color};font-weight:800">${ms.title}</span>`;
1563 if(nextMs)msEl.innerHTML+=`<span style="color:rgba(255,255,255,.4);margin:0 .3rem">â</span><span style="color:rgba(255,255,255,.5)">${nextMs.icon}${nextMs.title} (Lv${nextMs.lv})</span>`; 1564 }else if(nextMs){ 1565 msEl.innerHTML=`<span style="color:rgba(255,255,255,.5)">次ã®ç§°å·: ${nextMs.icon}${nextMs.title} (Lv${nextMs.lv})</span>`; 1566 }else{msEl.innerHTML=''} 1567 document.getElementById('t-best').innerHTML=S.best>0?`ð <span style="color:#FFD700">${fmtS(S.best)}</span>`:''; 1568 document.getElementById('t-pts').innerHTML=`ð° <span style="color:#FFD700">${fmtS(S.pts)}</span> pts`; 1569 // ãã¼ã«ä¸è¦§ãã¿ã³ï¼ãæ¯ãã¢ã¼ãè§£æ¾å¾ï¼ 1570 document.getElementById('btn-t-balls').style.display=(S.skills.otawamure||0)>=1?'':'none'; 1571 // ãããã£ã¼ã«ãã¿ã³ï¼ã¹ãã«è§£æ¾å¾ï¼ 1572 document.getElementById('btn-t-profile').style.display=(S.skills.profile_card||0)>=1?'':'none'; 1573} 1574 1575// ============ Buttons ============ 1576// å ¨ãã¿ã³ã«ã¯ãªãã¯é³ 1577document.addEventListener('click',e=>{if(e.target.closest('.btn,.tr-btn,.snd-btn,.tr-tab'))snd('buy')}); 1578document.getElementById('btn-play').onclick=startGame; 1579document.getElementById('btn-retry').onclick=startGame; 1580document.getElementById('btn-t-tree').onclick=()=>{document.getElementById('title').style.display='none';openTree('title')}; 1581document.getElementById('btn-t-ach').onclick=()=>{document.getElementById('title').style.display='none';openAch('title')}; 1582document.getElementById('btn-t-status').onclick=()=>{document.getElementById('title').style.display='none';openStatus()}; 1583document.getElementById('btn-t-balls').onclick=()=>{openBallList()}; 1584document.getElementById('btn-t-profile').onclick=()=>{openProfile()}; 1585document.getElementById('btn-t-sound').onclick=()=>{ea();document.getElementById('sound-settings').style.display='flex'}; 1586document.getElementById('btn-t-reset').onclick=()=>{document.getElementById('confirm').style.display='flex'}; 1587document.getElementById('btn-r-tree').onclick=()=>{document.getElementById('result').style.display='none';openTree('result')}; 1588document.getElementById('btn-r-top').onclick=()=>{document.getElementById('result').style.display='none';showTitle();document.getElementById('title').style.display='flex'}; 1589// ⢠ãã¬ã¤ä¸æãã¿ã³ - çµæç ´æ£ãã¦TOP㸠1590document.getElementById('btn-quit').onclick=()=>{ 1591 st='finished';document.getElementById('hud').style.display='none'; 1592 document.getElementById('ch-banner').style.display='none'; 1593 playBgm(bgmOp);showTitle();document.getElementById('title').style.display='flex'; 1594}; 1595document.getElementById('tr-back').onclick=closeTree; 1596 1597// ============ Prevent text selection on rapid tap ============ 1598document.addEventListener('selectstart',e=>e.preventDefault()); 1599document.addEventListener('contextmenu',e=>e.preventDefault()); 1600 1601// ============ Init ============ 1602updSpot();showTitle();requestAnimationFrame(upd); 1603})(); 1604</script>
1604 1605</div> 1606</body> 1607</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.