Skip to Main Content

OUR GROUP
색상반전 아이콘

Invert Colors

화면 확대 아이콘

Zoom In

화면 축소 아이콘

Zoom Out

100

PLAY THE ANIMATION!

당신이 꿈꿔왔던RPG 에픽세븐

일곱 번째 세계의 멸망을
막기 위한 여정
“계승자여, 세상을 지켜라”

방대하고 아름다운 스토리
최고의 작가진이 만들어낸 대서사시,
‘7번째 세계’에 당신을 초대합니다.

 archive이미지
  • Over140regions

    전 세계 140개국
    출시

  • 20million

    1200만 다운로드
    돌파

  • 10th place

    미국, 일본, 한국 등
    전세계 주요 국가 매출
    10위 달성

풀 프레임
2D 애니메이션

매력적인 캐릭터,
눈을 감으면
떠오르는 캐릭터

전투와 함께 펼쳐지는
화려한 연출

애니메이션에
전략을 더하다.

한 편의 애니메이션을
플레이해보세요.

다양한 개성을 가진
영웅들을 만나보세요.

전세계 유저들과
함께하는 실시간 대전!

나만의 방식으로 영웅을 조합하여
전략적인 전투를 즐길 수 있습니다.

월드 아레나에서
치열한 전략의 세계를 경험하세요

GO TO WEBSITE

INDEX

Soundtrack - Star Light Island

/* ========================================================= Game 페이지 키보드 포커스 흐름 패치 (ES5 즉시실행) ... ========================================================= */ (function () { // 페이지가 게임 상세가 아니면 종료 function $(sel, root) { return (root || document).querySelector(sel); } function $all(sel, root) { return (root || document).querySelectorAll(sel); } function ensureTabbable(el) { if (!el) return el; var n = el.nodeName.toLowerCase(); var native = (n === "a" && el.hasAttribute("href")) || n === "button" || n === "input" || n === "select" || n === "textarea"; if (!native && !el.hasAttribute("tabindex")) el.setAttribute("tabindex", "0"); return el; } function isGamePage() { return !!$(".game_nav_wrapper"); } if (!isGamePage()) return; // 공통 이동 function goSkip() { var s = getNodes().skipLink; if (s) { ensureTabbable(s); try { s.focus(); } catch (_) {} } } // 본문 루트 후보(gnb 스크립트가 포커스를 주는 대상과 동일 계열) function getContentRoot() { return ( document.querySelector("[data-scroll-container]") || document.querySelector(".locomotive") || document.querySelector(".locomotive_inner") || document.querySelector("#main") || document.querySelector("#content") || document.querySelector("main") || null ); } // 노드 캐시 function getNodes() { return { skipLink: $(".skip-nav a"), content: getContentRoot(), sound: $("#sound"), // game_sound 토글 대상 website: $(".website_anchor"), navName: $(".game_nav_name"), navList: $(".game_nav_list"), navWrapper: $(".game_nav"), navItems: $all(".game_nav_list .nav_list_item a"), infoWrap: $(".game_section_info"), infoLinks: $all(".game_section_info a[href]"), gameSound: $("#game_sound"), }; } function getNavFocusables() { var n = getNodes(); if (!n.navList) return []; return n.navList.querySelectorAll( 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' ); } // nav 리스트 열고/닫기(높이 기반, game.js 호버 동작을 키보드로 재현) function openNavList() { var n = getNodes(); if (!n.navList) return; var prev = n.navList.style.height; n.navList.style.height = "auto"; var h = n.navList.getBoundingClientRect().height; n.navList.style.height = prev || "0px"; n.navList.style.height = h + "px"; } function closeNavList() { var n = getNodes(); if (n.navList) n.navList.style.height = "0px"; } // 1) 본문 루트에 포커스가 들어오면 → #sound로 강제 이관 (레이스 완전 차단) var redirectedOnceFlag = false; function moveFocusToSoundChain() { var n = getNodes(); var first = n.sound || n.website || n.navName; if (!first) return false; ensureTabbable(first); first.focus(); return document.activeElement === first; } document.addEventListener( "focusin", function (e) { var n = getNodes(); if (!n.content) return; if (e.target === n.content && !redirectedOnceFlag) { redirectedOnceFlag = true; setTimeout(function () { moveFocusToSoundChain(); setTimeout(function () { redirectedOnceFlag = false; }, 600); }, 0); } }, true ); var __soundClickGuard = false; function triggerSoundToggle() { var n = getNodes(); if (!n.sound || __soundClickGuard) return; __soundClickGuard = true; // game.js의 위임 클릭을 1회만 발생 if (typeof n.sound.click === "function") n.sound.click(); else if (window.jQuery) window.jQuery(n.sound).trigger("click"); // 아주 짧게 가드 유지 후 해제 (같은 키 입력으로 생길 수 있는 추가 click 무시) setTimeout(function () { __soundClickGuard = false; }, 50); } // 2) #sound → website_anchor → nav_name(열기) → nav_items 순회 function bindLinearFlow() { var n = getNodes(); if (n.gameSound) { ensureTabbable(n.gameSound); n.gameSound.addEventListener("keydown", function (e) { var isEnter = e.key === "Enter" || e.keyCode === 13; var isSpace = e.key === " " || e.key === "Spacebar" || e.keyCode === 32; if (isEnter || isSpace) { e.preventDefault(); e.stopPropagation(); triggerSoundToggle(); } }); } // sound (#sound) 에서 Enter/Space → 토글, Tab → website_anchor (없으면 nav_name) // (둘 다 없으면 info 첫 링크 → 없으면 skip-nav) if (n.sound) { ensureTabbable(n.sound); n.sound.addEventListener("keydown", function (e) { var isEnter = e.key === "Enter" || e.keyCode === 13; var isSpace = e.key === " " || e.key === "Spacebar" || e.keyCode === 32; if (isEnter || isSpace) { e.preventDefault(); e.stopPropagation(); triggerSoundToggle(); return; } if (e.key === "Tab" && !e.shiftKey) { var to = getNodes().website || getNodes().navName; if (to) { e.preventDefault(); ensureTabbable(to); to.focus(); } else { var info = getNodes().infoLinks; if (info && info.length) { e.preventDefault(); closeNavList(); ensureTabbable(info[0]); info[0].focus(); } else { // game_info 자체가 없으면 즉시 skip-nav e.preventDefault(); goSkip(); } } } }); } // website_anchor ↔ sound / nav_name if (n.website) { ensureTabbable(n.website); n.website.addEventListener("keydown", function (e) { if (e.key === "Tab" && !e.shiftKey) { var to = getNodes().navName; if (to) { e.preventDefault(); openNavList(); ensureTabbable(to); to.focus(); } } else if (e.key === "Tab" && e.shiftKey) { var back = getNodes().sound; if (back) { e.preventDefault(); ensureTabbable(back); back.focus(); } } }); } // nav_name 포커스 시 목록 열기, Tab → 첫 nav item if (n.navName) { ensureTabbable(n.navName); n.navName.addEventListener("focus", function () { openNavList(); }); n.navName.addEventListener("keydown", function (e) { if (e.key === "Enter" || e.keyCode === 13) openNavList(); if (e.key === "Tab" && !e.shiftKey) { var items = getNodes().navItems; if (items && items.length) { e.preventDefault(); ensureTabbable(items[0]); items[0].focus(); } } else if (e.key === "Tab" && e.shiftKey) { var back = getNodes().website || getNodes().sound; if (back) { e.preventDefault(); closeNavList(); ensureTabbable(back); back.focus(); } } }); } // nav items: 첫 아이템 Shift+Tab ← nav_name, 마지막 → info 첫 링크 (없으면 skip-nav) var items = n.navItems; if (items && items.length) { var first = items[0]; var last = items[items.length - 1]; first.addEventListener("keydown", function (e) { if (e.key === "Tab" && e.shiftKey) { e.preventDefault(); var back = getNodes().navName || getNodes().website || getNodes().sound; if (back) { ensureTabbable(back); back.focus(); } } }); last.addEventListener("keydown", function (e) { if (e.key === "Tab" && !e.shiftKey) { var info = getNodes().infoLinks; if (info && info.length) { e.preventDefault(); closeNavList(); ensureTabbable(info[0]); info[0].focus(); } else { // nav 마지막인데 game_info 없으면 skip-nav e.preventDefault(); closeNavList(); goSkip(); } } }); } // 추가 보강: 네비 내부 '마지막 포커스'에서 Tab 시 강제 탈출 if (n.navList) { n.navList.addEventListener("keydown", function (e) { if (e.key === "Tab" && !e.shiftKey) { var navFocusables = getNavFocusables(); if ( navFocusables.length && document.activeElement === navFocusables[navFocusables.length - 1] ) { var infoFirst = getNodes().infoLinks && getNodes().infoLinks[0]; if (infoFirst) { e.preventDefault(); closeNavList(); infoFirst.focus(); } else { e.preventDefault(); closeNavList(); goSkip(); } } } }); } } // 3) game_info a들 순회 후 → skip-nav 복귀 function bindInfoFlow() { var n = getNodes(); var links = n.infoLinks; // game_info에 링크가 없으면 바로 skip-nav로 if (!links || !links.length) { goSkip(); return; } // 첫 링크 Shift+Tab → nav_items 마지막 links[0].addEventListener("keydown", function (e) { if (e.key === "Tab" && e.shiftKey) { var items = getNodes().navItems; if (items && items.length) { e.preventDefault(); ensureTabbable(items[items.length - 1]); items[items.length - 1].focus(); } } }); // 마지막 링크 Tab → skip-nav links[links.length - 1].addEventListener("keydown", function (e) { if (e.key === "Tab" && !e.shiftKey) { e.preventDefault(); goSkip(); } }); } // DOM 변경 대비: 네비/정보 영역에 변경이 생기면 재바인딩 var _navObserver, _infoObserver; function observeAndRebind() { var n = getNodes(); if (n.navList && !_navObserver) { _navObserver = new MutationObserver(function () { bindLinearFlow(); }); _navObserver.observe(n.navList, { childList: true, subtree: true, attributes: false, }); } if (n.infoWrap && !_infoObserver) { _infoObserver = new MutationObserver(function () { bindInfoFlow(); }); _infoObserver.observe(n.infoWrap, { childList: true, subtree: true, attributes: false, }); } } // 4) DOM 준비 후 바인딩 function ready(fn) { if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", fn); else setTimeout(fn, 0); } ready(function () { closeNavList(); bindLinearFlow(); bindInfoFlow(); observeAndRebind(); }); })(); -->