Created
December 26, 2025 08:51
-
-
Save dollspirit67-alt/9fce190f62789ee3e940364e6b829bb7 to your computer and use it in GitHub Desktop.
아무렇게rpg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="ko"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>아무하게 RPG - 보스 전투 모드</title> | |
| <style> | |
| body{margin:0;overflow:hidden;background:#333;color:white;font-family:sans-serif;} | |
| canvas{display:block;background:#3cb371;} | |
| #ui{position:absolute;top:0;left:0;width:100%;pointer-events:none;} | |
| #skill-bar button,#boss-buttons button{pointer-events:auto;margin:2px;} | |
| #dialogue{position:absolute;bottom:0;width:100%;background:rgba(0,0,0,0.7);padding:5px;font-size:18px;} | |
| #boss-buttons{position:absolute;top:50px;left:50px;} | |
| </style> | |
| </head> | |
| <body> | |
| <canvas id="game" width="800" height="500"></canvas> | |
| <div id="ui"> | |
| <div id="hp">HP: 200</div> | |
| <div id="mana">MP: 100</div> | |
| <div id="skill-bar"></div> | |
| <div id="dialogue"></div> | |
| <div id="boss-buttons"> | |
| <button onclick="startBossBattle(bosses.guardian)">신전 보스</button> | |
| <button onclick="startBossBattle(bosses.cloudBoss)">구름 보스</button> | |
| <button onclick="startBossBattle(bosses.destroyer)">파괴자</button> | |
| <button onclick="startBossBattle(hiddenBoss)">히든 보스</button> | |
| <button onclick="startGacha()">가챠</button> | |
| </div> | |
| </div> | |
| <audio id="bgm" loop src="https://freesound.org/data/previews/522/522429_3248244-lq.mp3"></audio> | |
| <script> | |
| const canvas=document.getElementById("game"); | |
| const ctx=canvas.getContext("2d"); | |
| const bgm=document.getElementById("bgm"); | |
| bgm.volume=0.3; bgm.play(); | |
| const player={name:"크림",x:100,y:100,speed:3,hp:200,maxHp:200,mana:100,maxMana:100,level:99,skills:[],inventory:[],tutorialCleared:false}; | |
| const monsters=[{name:"좀비",x:300,y:200,hp:120,atk:20},{name:"닭",x:500,y:350,hp:60,atk:10}]; | |
| const bosses={ | |
| guardian:{key:"guardian",name:"신전을 지키는 자",hp:2000,atk:200,def:91}, | |
| cloudBoss:{key:"cloudBoss",name:"구름 보스",hp:1000,atk:177,def:99}, | |
| destroyer:{key:"destroyer",name:"파괴자",hp:9999,atk:999,def:999} | |
| }; | |
| const hiddenBoss={name:"???",hp:5000,atk:300,def:150,key:"hidden",patterns:[]}; | |
| // -------------------- 스킬 정의 -------------------- | |
| player.skills=[ | |
| {name:"피어스",mana:50,effect:()=>{if(Math.random()<0.5){showDialogue("피어스 발동! 적 턴 스킵!"); nextMonsterTurn=false;}}}, | |
| {name:"조작",mana:90,effect:()=>{if(Math.random()<0.9){showDialogue("조작 발동! 공격 성공!"); currentBoss.hp-=player.level*10;}}} | |
| ]; | |
| // -------------------- 보스 패턴 -------------------- | |
| const bossPatterns={ | |
| guardian:[ | |
| ()=>{player.hp-=50;showDialogue("신전을 지키는 자 공격! HP-50");}, | |
| ()=>{player.hp-=30;showDialogue("신전을 지키는 자 마법 공격! HP-30");} | |
| ], | |
| cloudBoss:[ | |
| ()=>{player.hp-=40;showDialogue("천둥 번개! HP-40");}, | |
| ()=>{player.hp-=20;showDialogue("바람 스킬! HP-20");} | |
| ], | |
| destroyer:[ | |
| ()=>{player.hp-=100;showDialogue("망치 공격! HP-100");}, | |
| ()=>{player.hp-=150;showDialogue("레이저 발사! HP-150");}, | |
| ()=>{player.hp-=80;showDialogue("폭탄 폭발! HP-80");} | |
| ] | |
| }; | |
| // -------------------- UI -------------------- | |
| function showDialogue(text){document.getElementById("dialogue").innerText=text;} | |
| function updateUI(){document.getElementById("hp").innerText=`HP: ${player.hp}`;document.getElementById("mana").innerText=`MP: ${player.mana}`;} | |
| // -------------------- 스킬 UI -------------------- | |
| function drawSkillBar(){ | |
| const bar=document.getElementById("skill-bar"); | |
| bar.innerHTML=""; | |
| player.skills.forEach(skill=>{ | |
| const btn=document.createElement("button"); | |
| btn.innerText=`${skill.name} (${skill.mana}MP)`; | |
| btn.onclick=()=>{ | |
| if(player.mana>=skill.mana){player.mana-=skill.mana; skill.effect(); drawSkillBar();} | |
| }; | |
| bar.appendChild(btn); | |
| }); | |
| } | |
| drawSkillBar(); | |
| // -------------------- 이동 -------------------- | |
| let keys={}; | |
| document.addEventListener("keydown",e=>keys[e.key]=true); | |
| document.addEventListener("keyup",e=>keys[e.key]=false); | |
| canvas.addEventListener("touchmove",e=>{const t=e.touches[0];player.x=t.clientX-canvas.offsetLeft;player.y=t.clientY-canvas.offsetTop;}); | |
| function movePlayer(){if(keys.w) player.y-=player.speed;if(keys.s) player.y+=player.speed;if(keys.a) player.x-=player.speed;if(keys.d) player.x+=player.speed;} | |
| // -------------------- 그리기 -------------------- | |
| function drawPlayer(){ctx.fillStyle="blue";ctx.fillRect(player.x,player.y,30,30);} | |
| function drawMonsters(){monsters.forEach(m=>{ctx.fillStyle="red";ctx.fillRect(m.x,m.y,30,30);});} | |
| function drawTitle(){ctx.fillStyle="white";ctx.font="48px sans-serif";ctx.fillText("아무하게 RPG",230,120);} | |
| // -------------------- 가챠 -------------------- | |
| const rarityTable=[{name:"커먼",chance:40},{name:"일반",chance:25},{name:"중간",chance:15},{name:"전설",chance:8},{name:"신화",chance:5},{name:"이색적",chance:4},{name:"시크릿",chance:3}]; | |
| const items={"커먼":["낡은 검","천 갑옷"],"일반":["강철 검","회복 반지"],"중간":["마법 검","속도 부츠"],"전설":["용의 검"],"신화":["시간의 시계"],"이색적":["버그난 검"],"시크릿":["???"]}; | |
| function rollRarity(){const roll=Math.random()*100;let sum=0;for(let r of rarityTable){sum+=r.chance;if(roll<=sum)return r.name;}} | |
| function pickItem(rarity){return items[rarity][Math.floor(Math.random()*items[rarity].length)];} | |
| function revealItem(){const rarity=rollRarity();const item=pickItem(rarity);player.inventory.push({item,rarity});showDialogue(`🎉 ${rarity} 등급 획득: ${item}`);} | |
| function startGacha(){let flashes=0;const interval=setInterval(()=>{ctx.fillStyle=flashes%2?"black":"white";ctx.fillRect(0,0,800,500);flashes++;if(flashes>10){clearInterval(interval);revealItem();}},50);} | |
| // -------------------- 보스 컷신 & 전투 -------------------- | |
| let currentBoss=null; let nextMonsterTurn=true; | |
| function bossCutscene(boss){let alpha=1;const interval=setInterval(()=>{ctx.clearRect(0,0,800,500);ctx.fillStyle=`rgba(0,0,0,${alpha})`;ctx.fillRect(0,0,800,500);ctx.fillStyle="red";ctx.font="bold 50px sans-serif";ctx.fillText(`${boss.name} 등장!`,150,250);alpha-=0.02;if(alpha<=0) clearInterval(interval);},30);} | |
| function bossTurn(boss){if(boss.hp<=0) return;const patterns=boss.patterns || bossPatterns[boss.key] || []; if(patterns.length===0) return; const move=patterns[Math.floor(Math.random()*patterns.length)]; move();} | |
| function autoBattle(boss){if(player.hp<=0){showDialogue("게임 오버!"); return;} if(boss.hp<=0){showDialogue(`${boss.name} 처치!`); return;} setTimeout(()=>{if(nextMonsterTurn){bossTurn(boss);} nextMonsterTurn=true; autoBattle(boss);},1000);} | |
| function startBossBattle(boss){currentBoss=boss;bossCutscene(boss);setTimeout(()=>{autoBattle(boss);},1500);} | |
| // -------------------- 게임 루프 -------------------- | |
| function gameLoop(){ctx.clearRect(0,0,800,500);drawTitle();drawPlayer();drawMonsters();movePlayer();updateUI();requestAnimationFrame(gameLoop);} | |
| gameLoop(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment