Created
December 26, 2025 09:18
-
-
Save dollspirit67-alt/9a8af019e3180efb606002f6de7b1664 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 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);} | |
| // ======= 게임 루프 ======= | |
| const canvas=document.getElementById("game"); | |
| const ctx=canvas.getContext("2d"); | |
| 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