Skip to content

Instantly share code, notes, and snippets.

@dollspirit67-alt
Created December 26, 2025 08:51
Show Gist options
  • Select an option

  • Save dollspirit67-alt/9fce190f62789ee3e940364e6b829bb7 to your computer and use it in GitHub Desktop.

Select an option

Save dollspirit67-alt/9fce190f62789ee3e940364e6b829bb7 to your computer and use it in GitHub Desktop.
아무렇게rpg
<!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