🎮ArcadeLab

우리들의 고등학교 시뮬레이터

by FrozenPanda36
350 lines14.8 KB
▶ Play
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>우리들의 고등학교 시뮬레이터</title>
<style>
*{box-sizing:border-box}
body{margin:0;background:#101827;color:white;font-family:Arial,"Malgun Gothic",sans-serif}
button,input,select{font:inherit}
button{cursor:pointer;border:0;border-radius:9px;padding:11px;background:#3979dc;color:white;margin:3px}
button:hover{filter:brightness(1.2)}
input{padding:12px;border-radius:8px;border:1px solid #aaa;margin:5px;width:90%;color:#111}
.panel{background:#202e42;border:1px solid #40536c;border-radius:14px;padding:18px;margin:12px auto;max-width:850px}
.center{text-align:center}
.hidden{display:none!important}
.small{font-size:12px;color:#bdcce0}
h1,h2{color:#8dc3ff}
#game{max-width:1000px;margin:auto;padding:10px}
#top{display:flex;justify-content:space-between;flex-wrap:wrap;background:#263951;padding:13px;border-radius:12px;gap:8px}
#scene{height:340px;border-radius:12px;overflow:hidden;position:relative;background:linear-gradient(#8bc9ef 0%,#c7e8f3 53%,#658c5c 53%,#315a36 100%);border:3px solid #52677d}
.building{position:absolute;bottom:70px;left:20%;width:60%;height:155px;background:#d8d4c8;border:5px solid #7e8a9a}
.building:before{content:"우리들의 고등학교";position:absolute;top:10px;left:0;right:0;text-align:center;color:#293d55;font-weight:bold;font-size:19px}
.window{position:absolute;background:#5483a6;border:4px solid #eee;width:12%;height:48px;top:55px}
.w1{left:12%}.w2{left:42%}.w3{right:12%}
.door{position:absolute;bottom:0;left:43%;height:75px;width:15%;background:#785b43;border:4px solid #eee}
#sceneText{position:absolute;bottom:10px;left:0;right:0;text-align:center;color:white;text-shadow:1px 2px 4px black;font-weight:bold}
#dialogue{background:#111d2c;padding:12px;border-radius:10px;margin-top:10px;min-height:55px}
#actions{display:flex;flex-wrap:wrap;justify-content:center;margin:10px}
#actions button{min-width:110px}
#log{height:110px;overflow:auto;background:#111d2c;padding:10px;border-radius:8px;font-size:13px}
.choice{display:block;width:100%;text-align:left;margin:7px 0;background:#344d6b}
.stat{display:inline-block;background:#314965;padding:8px;border-radius:8px;margin:3px}
</style>
</head>
<body>
<div id="login" class="panel center" style="margin-top:35px">
<h1>🏫 우리들의 고등학교</h1>
<h2>학교 시뮬레이터</h2>
<p>로그인 번호를 입력하세요.</p>
<input id="loginId" placeholder="로그인 번호를 입력하세요">
<br><button onclick="login()">로그인</button>
<p class="small">로그인 번호가 없다면 회원가입을 해주세요.</p>
<div id="loginError" style="color:#ff8888"></div>
<button onclick="showSignup()">회원가입</button>
<button onclick="report()">신고하기</button>
<div id="signup" class="hidden">
<h2>회원가입</h2>
<input id="birth" type="date" placeholder="생년월일">
<input id="realname" placeholder="이름">
<input id="newid" placeholder="아이디">
<br><button onclick="register()">가입하기</button>
<p class="small">테스트 버전: 정보는 현재 사용 중인 브라우저에만 저장됩니다. 실제 개인정보 대신 테스트용 정보를 사용하세요.</p>
</div>
<div id="registerResult"></div>
</div>

<div id="roleScreen" class="panel center hidden">
<h1>어떤 역할을 선택하시겠습니까?</h1>
<p>선택한 역할은 직접 조종하고 나머지 역할은 AI가 조종합니다.</p>
<div id="roles"></div>
</div>

<div id="game" class="hidden">
<div id="top">
<div>📅 <span id="date"></span></div>
<div>🕒 <span id="clock"></span></div>
<div>👤 <span id="playerName"></span> / <span id="playerRole"></span></div>
<div>📍 <span id="location"></span></div>
</div>

<div class="panel">
<div class="stat">❤️ 체력 <span id="health">100</span></div>
<div class="stat">📚 성적 <span id="grade">50</span></div>
<div class="stat">🎓 대학 진학 점수 <span id="college">0</span></div>
<div class="stat">💰 용돈 <span id="money">50000</span>원</div>
<div class="stat">🏫 학년 <span id="year">1</span>학년</div>
</div>

<div id="scene">
<div class="building">
<div class="window w1"></div>
<div class="window w2"></div>
<div class="window w3"></div>
<div class="door"></div>
</div>
<div id="sceneText">학교 시뮬레이터에 오신 것을 환영합니다!</div>
</div>

<div id="dialogue">게임을 시작했습니다. 주변 인물들이 당신에게 말을 걸 수 있습니다.</div>
<div class="panel">
<h3>🎮 행동하기</h3>
<div id="actions"></div>
<div class="small center">컴퓨터에서는 WASD 또는 방향키로 이동할 수 있습니다.</div>
</div>

<div class="panel">
<h3>📖 시험 및 학습</h3>
<div id="quizArea">시험이나 공부를 선택하면 문제가 나타납니다.</div>
</div>

<div class="panel">
<h3>💬 학교 인물들의 대화</h3>
<div id="log"></div>
</div>
<div class="center">
<button onclick="saveGame()">💾 저장하기</button>
<button onclick="location.reload()">처음으로</button>
</div>
</div>

<script>
const roles=["학생","선생님","교장","교무실 임직원","이사장"];
let user=null, role="", place="집", day=2, month=3, year=2026;
let hour=8, minute=20, grade=50, college=0, health=100, money=50000;
let schoolYear=1, sleeping=false, examDone={};
let accounts=JSON.parse(localStorage.getItem("schoolAccounts")||"{}");

const $=id=>document.getElementById(id);

function showSignup(){
 $("signup").classList.toggle("hidden");
 $("loginError").innerText="";
}
function register(){
 let birth=$("birth").value;
 let name=$("realname").value.trim();
 let id=$("newid").value.trim();
 if(!birth||!name||!id){alert("생년월일, 이름, 아이디를 모두 입력해주세요.");return;}
 if(accounts[id]){alert("이미 존재하는 아이디입니다.");return;}
 let number="HS"+Math.floor(100000+Math.random()*900000);
 accounts[id]={birth,name,number};
 localStorage.setItem("schoolAccounts",JSON.stringify(accounts));
 $("registerResult").innerHTML="<h3>회원가입 완료!</h3>로그인 번호: <b>"+number+"</b><p>이 번호를 기억해주세요.</p>";
}
function login(){
 let number=$("loginId").value.trim();
 user=Object.values(accounts).find(a=>a.number===number);
 if(!user){
 $("loginError").innerHTML="로그인 번호가 존재하지 않는 번호입니다.<br><small>회원가입 및 신고를 아래에서 이용해주세요.</small>";
 return;
 }
 $("login").classList.add("hidden");
 $("roleScreen").classList.remove("hidden");
 $("roles").innerHTML=roles.map(r=>`<button onclick="chooseRole('${r}')">${r}</button>`).join("");
}
function report(){
 alert("신고 접수 테스트 화면입니다. 실제 신고 서버에는 연결되어 있지 않습니다.");
}
function chooseRole(r){
 role=r;
 $("roleScreen").classList.add("hidden");
 $("game").classList.remove("hidden");
 $("playerName").innerText=user.name;
 $("playerRole").innerText=role;
 actions();
 update();
 log("게임 시작! "+user.name+"님은 "+role+" 역할을 선택했습니다.");
 log("AI 선생님, 학생, 교장, 교무실 임직원, 이사장이 활동을 시작합니다.");
 if(role==="학생")log("오늘은 2026년 3월 2일. 새로운 고등학교 생활이 시작됩니다!");
}
function log(s){
 let box=$("log");
 box.innerHTML+="<p>["+clock()+"] "+s+"</p>";
 box.scrollTop=box.scrollHeight;
}
function clock(){
 return String(hour).padStart(2,"0")+":"+String(minute).padStart(2,"0");
}
function update(){
 $("date").innerText=year+"년 "+month+"월 "+day+"일";
 $("clock").innerText=clock();
 $("location").innerText=place;
 $("health").innerText=health;
 $("grade").innerText=grade;
 $("college").innerText=college;
 $("money").innerText=money;
 $("year").innerText=schoolYear;
}
function actions(){
 let list=[];
 if(role==="학생"){
 list=["등교하기","교실 들어가기","수업 듣기","공부하기","친구와 대화","급식 먹기","모의고사","중간고사","기말고사","야간자율학습","집으로 돌아가기","잠자기"];
 }else if(role==="선생님"){
 list=["학교 출근","교실 들어가기","수업 진행","학생 상담","시험 감독","교무실 가기","퇴근"];
 }else if(role==="교장"){
 list=["학교 출근","교내 방송","교무회의","학교 순찰","학생 격려","퇴근"];
 }else if(role==="교무실 임직원"){
 list=["출근하기","교무실 업무","성적 처리","학생 상담","교장과 회의","퇴근"];
 }else{
 list=["학교 방문","교장 면담","학교 시설 확인","예산 회의","학생 격려","학교 행사 참석","귀가"];
 }
 $("actions").innerHTML=list.map(x=>`<button onclick="act('${x}')">${x}</button>`).join("");
}
function advance(min){
 minute+=min;
 while(minute>=60){minute-=60;hour++;}
 if(hour>=24){
 hour=0;
 day++;
 if(day>30){day=1;month++;}
 if(month>12){month=1;year++;}
 }
 update();
}
function setPlace(p){
 place=p;
 $("sceneText").innerText=p;
 update();
}
function act(a){
 if(a==="등교하기"||a==="학교 출근"||a==="학교 방문"){
 setPlace("학교 정문");
 advance(20);
 log("학교에 도착했습니다.");
 aiTalk();
 }else if(a==="교실 들어가기"){
 setPlace("교실");
 advance(5);
 log("교실에 들어왔습니다. 친구들이 이야기를 나누고 있습니다.");
 aiTalk();
 }else if(a==="교무실 가기"||a==="교무실 업무"){
 setPlace("교무실");
 advance(15);
 log("교무실에서 업무를 시작합니다.");
 }else if(a==="집으로 돌아가기"||a==="퇴근"||a==="귀가"){
 setPlace("집");
 advance(30);
 log("집에 도착했습니다. 오늘 하루도 수고했습니다!");
 }else if(a==="잠자기"){
 if(place!=="집"){alert("집으로 돌아간 뒤 잠을 잘 수 있습니다.");return;}
 hour=7;minute=0;day++;
 if(day>30){day=1;month++;}
 health=100;
 advance(0);
 log("잠을 잤습니다. 새로운 하루가 시작됩니다.");
 setPlace("집");
 }else if(a==="수업 듣기"||a==="수업 진행"){
 advance(50);
 grade=Math.min(100,grade+2);
 college+=2;
 log("수업을 마쳤습니다. 학습 능력이 향상되었습니다.");
 aiTalk();
 }else if(a==="공부하기"||a==="야간자율학습"){
 advance(a==="공부하기"?60:120);
 grade=Math.min(100,grade+4);
 college+=4;
 health=Math.max(0,health-8);
 log("열심히 공부했습니다! 성적과 진학 점수가 올랐습니다.");
 }else if(a==="급식 먹기"){
 advance(30);health=Math.min(100,health+15);
 log("오늘의 급식을 먹었습니다.");
 }else if(a==="친구와 대화"||a==="학생 상담"){
 advance(10);aiTalk();
 }else if(a==="모의고사"){
 exam("모의고사");
 }else if(a==="중간고사"){
 exam("중간고사");
 }else if(a==="기말고사"){
 exam("기말고사");
 }else if(a==="시험 감독"){
 setPlace("시험장");
 advance(50);log("시험 감독을 진행했습니다.");
 }else{
 advance(20);
 log(a+" 활동을 진행했습니다.");
 aiTalk();
 }
 update();
}
function aiTalk(){
 let people=["AI 학생","AI 선생님","AI 교장","AI 교무실 직원","AI 이사장"];
 let lines=[
 "오늘 수업 정말 재미있었어요!",
 "다음 시험은 꼭 좋은 성적을 받아야겠어.",
 "학교생활은 성실함이 가장 중요합니다.",
 "오늘은 학생들의 출석을 확인하겠습니다.",
 "학교 시설을 더 좋게 만들어야겠습니다.",
 "이번 주에 학교 행사가 예정되어 있습니다.",
 "오늘 야간자율학습에 참여할 건가요?",
 "열심히 하면 원하는 대학에 갈 수 있을 거야!",
 "선생님, 질문이 있어요!",
 "오늘 급식 메뉴가 정말 맛있었어요!"
 ];
 let who=people[Math.floor(Math.random()*people.length)];
 let line=lines[Math.floor(Math.random()*lines.length)];
 $("dialogue").innerText=who+": "+line;
 log(who+": "+line);
}
const questions=[
 {q:"대한민국의 수도는 어디일까요?",o:["서울","부산","대전","광주"],a:0},
 {q:"다음 중 소수인 것은?",o:["9","15","17","21"],a:2},
 {q:"물의 화학식은?",o:["CO2","H2O","O2","NaCl"],a:1},
 {q:"영어 단어 Apple의 뜻은?",o:["바나나","사과","포도","복숭아"],a:1},
 {q:"대한민국의 광복절은 몇 월 며칠일까요?",o:["3월 1일","6월 6일","8월 15일","10월 3일"],a:2},
 {q:"2차 방정식 x²=9의 해 중 양수는?",o:["1","2","3","9"],a:2},
 {q:"태양계에서 가장 큰 행성은?",o:["지구","화성","목성","금성"],a:2},
 {q:"훈민정음을 창제한 왕은?",o:["태조","세종대왕","정조","영조"],a:1},
 {q:"영어 문장 I am a student.의 뜻은?",o:["나는 선생님이다","나는 학생이다","나는 의사다","나는 학교다"],a:1},
 {q:"삼각형의 내각의 합은?",o:["90도","180도","270도","360도"],a:1}
];
let currentQuestion=null;
function exam(type){
 if(role!=="학생"&&type!=="모의고사"){alert("현재 시험 응시 기능은 학생 역할 전용입니다.");return;}
 let key=year+"-"+month+"-"+day+"-"+type;
 if(examDone[key]){alert("오늘 이 시험은 이미 응시했습니다.");return;}
 currentQuestion=questions[Math.floor(Math.random()*questions.length)];
 $("quizArea").innerHTML="<h3>📝 "+type+"</h3><p>"+currentQuestion.q+"</p>"+
 currentQuestion.o.map((x,i)=>`<button class="choice" onclick="answer(${i},'${key}')">${i+1}. ${x}</button>`).join("");
 advance(40);
 log(type+"이 시작되었습니다.");
}
function answer(n,key){
 if(!currentQuestion)return;
 examDone[key]=true;
 if(n===currentQuestion.a){
 grade=Math.min(100,grade+8);
 college+=10;
 $("quizArea").innerHTML="<h3 style='color:#73e99a'>정답입니다! 🎉</h3><p>성적과 대학 진학 점수가 올랐습니다.</p>";
 log("시험 정답! 성적이 향상되었습니다.");
 }else{
 grade=Math.max(0,grade-2);
 $("quizArea").innerHTML="<h3 style='color:#ff9292'>아쉽지만 오답입니다.</h3><p>정답: "+currentQuestion.o[currentQuestion.a]+"</p>";
 log("시험에서 오답을 선택했습니다.");
 }
 currentQuestion=null;
 update();
}
function saveGame(){
 let data={role,place,day,month,year,hour,minute,grade,college,health,money,schoolYear};
 localStorage.setItem("schoolSave",JSON.stringify(data));
 alert("게임 진행 상황을 저장했습니다.");
}
function move(dir){
 if(place==="집"&&dir==="앞"){setPlace("집 앞 길");return;}
 if(place==="집 앞 길"&&dir==="앞"){setPlace("학교 정문");advance(10);return;}
 if(dir==="뒤")setPlace("복도");
 else if(dir==="앞")setPlace("교실");
 else if(dir==="왼쪽")setPlace("학교 운동장");
 else if(dir==="오른쪽")setPlace("교무실");
 advance(2);
}
document.addEventListener("keydown",e=>{
 let d={w:"앞",ArrowUp:"앞",s:"뒤",ArrowDown:"뒤",a:"왼쪽",ArrowLeft:"왼쪽",d:"오른쪽",ArrowRight:"오른쪽"}[e.key];
 if(d&&!$("game").classList.contains("hidden"))move(d);
});
</script>
</body>
</html>

Game Source: 우리들의 고등학교 시뮬레이터

Creator: FrozenPanda36

Libraries: none

Complexity: complex (350 lines, 14.8 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-frozenpanda36" to link back to the original. Then publish at arcadelab.ai/publish.