Introduced config.js for easy multi-game maintenance
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
const CONFIG = {
|
||||||
|
gameName: 'PokéSQL',
|
||||||
|
subject: 'SQL',
|
||||||
|
examName: 'SQL',
|
||||||
|
townName: 'SQL Town',
|
||||||
|
saveKey: 'pokesql_save_v2',
|
||||||
|
titleText: 'SQL',
|
||||||
|
titleEdition: '★ SQL TRAINER ★',
|
||||||
|
titleFooter: 'PokéSQL v1.0 · SQL · github.com/JustinOros',
|
||||||
|
townNameUpper:'SQL TOWN',
|
||||||
|
continueLogoSuffix: 'SQL',
|
||||||
|
expLabel: 'SQL EXP',
|
||||||
|
battleMove: 'SQL KNOWLEDGE',
|
||||||
|
battleMiss: 'SQL QUERY',
|
||||||
|
completeMsg: "You've conquered SQL Town and mastered Microsoft T-SQL! Your SQL journey is just beginning — more towns and exams await!",
|
||||||
|
badges: [
|
||||||
|
'🥉 SQL EXPLORER — Q25',
|
||||||
|
'🥈 SQL APPRENTICE — Q50',
|
||||||
|
'🥇 SQL PRACTITIONER — Q75',
|
||||||
|
'🏆 SQL CHAMPION — Q100',
|
||||||
|
],
|
||||||
|
milestones: {
|
||||||
|
25: { badge: '🥉 SQL EXPLORER', stars: '★ ★ ☆ ☆' },
|
||||||
|
50: { badge: '🥈 SQL APPRENTICE', stars: '★ ★ ★ ☆' },
|
||||||
|
75: { badge: '🥇 SQL PRACTITIONER', stars: '★ ★ ★ ★' },
|
||||||
|
},
|
||||||
|
introLines: [
|
||||||
|
"Hello {name}! Welcome to PokéSQL, the world of SQL training! My name is Professor Oak, the SQL Professor!",
|
||||||
|
"Your mission? Journey through SQL Town, challenge SQL masters, and conquer 100 database questions to become the ultimate SQL Trainer!",
|
||||||
|
"But first... every trainer needs a partner Pokémon! Let's choose yours, {name}!",
|
||||||
|
],
|
||||||
|
namePrompt: "Hello there! Welcome to PokéSQL! My name is Professor Oak — the SQL Professor. Now tell me, what is your name?",
|
||||||
|
};
|
||||||
@@ -1,16 +1,3 @@
|
|||||||
const CONFIG = {
|
|
||||||
gameName: 'PokéSQL',
|
|
||||||
subject: 'SQL',
|
|
||||||
examName: 'SQL',
|
|
||||||
townName: 'SQL Town',
|
|
||||||
saveKey: 'pokesql_save_v2',
|
|
||||||
introLines: [
|
|
||||||
"Hello {name}! Welcome to PokéSQL, the world of SQL training! My name is Professor Oak, the SQL Professor!",
|
|
||||||
"Your mission? Journey through SQL Town, challenge SQL masters, and conquer 100 database questions to become the ultimate SQL Trainer!",
|
|
||||||
"But first... every trainer needs a partner Pokémon! Let's choose yours, {name}!",
|
|
||||||
],
|
|
||||||
namePrompt: "Hello there! Welcome to PokéSQL! My name is Professor Oak — the SQL Professor. Now tell me, what is your name?",
|
|
||||||
};
|
|
||||||
|
|
||||||
const ALL_POKEMON = [
|
const ALL_POKEMON = [
|
||||||
{ name:'Charmander', emoji:'🔥', type:'Fire' },
|
{ name:'Charmander', emoji:'🔥', type:'Fire' },
|
||||||
@@ -106,13 +93,9 @@ const INTRO_MSGS = CONFIG.introLines.map(text => ({ speaker:'PROFESSOR OAK', npc
|
|||||||
const CORRECT_FB = ["That's right!","Excellent work!","Perfect!","Outstanding!","Correct!","You're a natural!","Great answer!","Spot on!","Impressive!","Well done!"];
|
const CORRECT_FB = ["That's right!","Excellent work!","Perfect!","Outstanding!","Correct!","You're a natural!","Great answer!","Spot on!","Impressive!","Well done!"];
|
||||||
const WRONG_FB = ["Not quite...","Hmm, that's not it.","Try again next time!","Almost...","Not this time!"];
|
const WRONG_FB = ["Not quite...","Hmm, that's not it.","Try again next time!","Almost...","Not this time!"];
|
||||||
|
|
||||||
const MILESTONES = {
|
|
||||||
25: { badge:'🥉 CLOUD EXPLORER', stars:'★ ★ ☆ ☆' },
|
|
||||||
50: { badge:'🥈 AZURE APPRENTICE', stars:'★ ★ ★ ☆' },
|
|
||||||
75: { badge:'🥇 CLOUD PRACTITIONER', stars:'★ ★ ★ ★' },
|
|
||||||
};
|
|
||||||
|
|
||||||
const SAVE_KEY = CONFIG.saveKey;
|
const SAVE_KEY = CONFIG.saveKey;
|
||||||
|
const MILESTONES = CONFIG.milestones;
|
||||||
|
|
||||||
function saveGame(s) {
|
function saveGame(s) {
|
||||||
try { localStorage.setItem(SAVE_KEY, JSON.stringify({
|
try { localStorage.setItem(SAVE_KEY, JSON.stringify({
|
||||||
@@ -2028,7 +2011,7 @@ class Game {
|
|||||||
const msg = document.getElementById('battle-anim-msg');
|
const msg = document.getElementById('battle-anim-msg');
|
||||||
|
|
||||||
if (correct) {
|
if (correct) {
|
||||||
msg.textContent = `${playerPoke.name} used SQL KNOWLEDGE!`;
|
msg.textContent = `${playerPoke.name} used ${CONFIG.battleMove}!`;
|
||||||
SFX.attack();
|
SFX.attack();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
npcHp.style.width = '0%';
|
npcHp.style.width = '0%';
|
||||||
@@ -2044,7 +2027,7 @@ class Game {
|
|||||||
this.showResult(true, q);
|
this.showResult(true, q);
|
||||||
}, 2200);
|
}, 2200);
|
||||||
} else {
|
} else {
|
||||||
msg.textContent = `${playerPoke.name} used SQL QUERY... but it missed!`;
|
msg.textContent = `${playerPoke.name} used ${CONFIG.battleMiss}... but it missed!`;
|
||||||
SFX.attack();
|
SFX.attack();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
msg.textContent = `${npcPoke.name} used COUNTER ATTACK!`;
|
msg.textContent = `${npcPoke.name} used COUNTER ATTACK!`;
|
||||||
|
|||||||
+31
-12
@@ -7,7 +7,7 @@
|
|||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<meta name="theme-color" content="#0a0520">
|
<meta name="theme-color" content="#0a0520">
|
||||||
<title>PokéSQL — Lean SQL</title>
|
<title id="page-title">PokéSQL — Learn SQL</title>
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
@@ -28,19 +28,19 @@
|
|||||||
<div class="title-stars"></div>
|
<div class="title-stars"></div>
|
||||||
<div class="title-main">
|
<div class="title-main">
|
||||||
<div class="title-logo">
|
<div class="title-logo">
|
||||||
<span class="title-poke">POKÉ</span><span class="title-sql">SQL</span>
|
<span class="title-poke">POKÉ</span><span class="title-game" id="title-game-text">SQL</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="title-edition">★ SQL TRAINER ★</div>
|
<div class="title-edition" id="title-edition-text">★ SQL TRAINER ★</div>
|
||||||
<div class="title-tap blink">PRESS START</div>
|
<div class="title-tap blink">PRESS START</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="title-footer">PokéSQL v1.0 · SQL · github.com/JustinOros</div>
|
<div class="title-footer" id="title-footer-text">PokéSQL v1.0 · SQL · github.com/JustinOros</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CONTINUE OR NEW GAME -->
|
<!-- CONTINUE OR NEW GAME -->
|
||||||
<div id="screen-continue" class="screen">
|
<div id="screen-continue" class="screen">
|
||||||
<div class="continue-bg">
|
<div class="continue-bg">
|
||||||
<div class="continue-logo">POKÉ<span>SQL</span></div>
|
<div class="continue-logo">POKÉ<span id="continue-logo-text">SQL</span></div>
|
||||||
<div class="continue-card" id="continue-card">
|
<div class="continue-card" id="continue-card">
|
||||||
<div class="continue-card-header">📂 CONTINUE</div>
|
<div class="continue-card-header">📂 CONTINUE</div>
|
||||||
<div class="save-row"><span class="save-lbl">TRAINER</span><span class="save-val" id="save-name-disp">—</span></div>
|
<div class="save-row"><span class="save-lbl">TRAINER</span><span class="save-val" id="save-name-disp">—</span></div>
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
<div class="map-header">
|
<div class="map-header">
|
||||||
<div class="map-left">
|
<div class="map-left">
|
||||||
<span class="map-pin">📍</span>
|
<span class="map-pin">📍</span>
|
||||||
<span class="map-town-name">SQL TOWN</span>
|
<span class="map-town-name" id="map-town-name-text">SQL TOWN</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="map-center">
|
<div class="map-center">
|
||||||
<div class="prog-bar-outer"><div class="prog-bar-inner" id="map-prog-bar"></div></div>
|
<div class="prog-bar-outer"><div class="prog-bar-inner" id="map-prog-bar"></div></div>
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
<div class="levelup-box">
|
<div class="levelup-box">
|
||||||
<div class="lu-stars blink" id="lu-stars">★ BADGE EARNED! ★</div>
|
<div class="lu-stars blink" id="lu-stars">★ BADGE EARNED! ★</div>
|
||||||
<div class="lu-sprite"><div class="lu-player-sprite"></div></div>
|
<div class="lu-sprite"><div class="lu-player-sprite"></div></div>
|
||||||
<div class="lu-text"><span id="lu-name">ASH</span> gained SQL EXP!</div>
|
<div class="lu-text"><span id="lu-name">ASH</span> gained <span id="exp-label-text">SQL EXP</span>!</div>
|
||||||
<div class="lu-badge" id="lu-badge">🏅 CLOUD TRAINEE</div>
|
<div class="lu-badge" id="lu-badge">🏅 CLOUD TRAINEE</div>
|
||||||
<div class="lu-prog-wrap">
|
<div class="lu-prog-wrap">
|
||||||
<div class="lu-prog-outer"><div class="lu-prog-inner" id="lu-prog-inner"></div></div>
|
<div class="lu-prog-outer"><div class="lu-prog-inner" id="lu-prog-inner"></div></div>
|
||||||
@@ -277,14 +277,14 @@
|
|||||||
<div class="complete-trophy">🏆</div>
|
<div class="complete-trophy">🏆</div>
|
||||||
<div class="complete-title">CHAMPION!</div>
|
<div class="complete-title">CHAMPION!</div>
|
||||||
<div class="complete-name" id="complete-name">ASH</div>
|
<div class="complete-name" id="complete-name">ASH</div>
|
||||||
<p class="complete-msg">You've conquered SQL Town and mastered Microsoft T-SQL! Your SQL journey is just beginning — more towns and exams await!</p>
|
<p class="complete-msg"><span id="complete-msg-text">You've conquered SQL Town and mastered Microsoft T-SQL! Your SQL journey is just beginning — more towns and exams await!</span></p>
|
||||||
<div class="complete-stats" id="complete-stats"></div>
|
<div class="complete-stats" id="complete-stats"></div>
|
||||||
<div class="complete-pokemon" id="complete-pokemon"></div>
|
<div class="complete-pokemon" id="complete-pokemon"></div>
|
||||||
<div class="complete-badges">
|
<div class="complete-badges">
|
||||||
<div class="badge-row">🥉 SQL EXPLORER — Q25</div>
|
<div class="badge-row"><span id="badge-1">🥉 SQL EXPLORER — Q25</span></div>
|
||||||
<div class="badge-row">🥈 SQL APPRENTICE — Q50</div>
|
<div class="badge-row"><span id="badge-2">🥈 SQL APPRENTICE — Q50</span></div>
|
||||||
<div class="badge-row">🥇 SQL PRACTITIONER — Q75</div>
|
<div class="badge-row"><span id="badge-3">🥇 SQL PRACTITIONER — Q75</span></div>
|
||||||
<div class="badge-row">🏆 SQL CHAMPION — Q100</div>
|
<div class="badge-row"><span id="badge-4">🏆 SQL CHAMPION — Q100</span></div>
|
||||||
<div class="badge-row">🗺️ More towns & exams coming soon...</div>
|
<div class="badge-row">🗺️ More towns & exams coming soon...</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-pixel btn-red btn-full" id="btn-play-again">▶ PLAY AGAIN</button>
|
<button class="btn-pixel btn-red btn-full" id="btn-play-again">▶ PLAY AGAIN</button>
|
||||||
@@ -316,6 +316,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="toast" class="toast hidden"></div>
|
<div id="toast" class="toast hidden"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const set = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val; };
|
||||||
|
set('title-game-text', CONFIG.titleText);
|
||||||
|
set('title-edition-text', CONFIG.titleEdition);
|
||||||
|
set('title-footer-text', CONFIG.titleFooter);
|
||||||
|
set('continue-logo-text', CONFIG.continueLogoSuffix);
|
||||||
|
set('map-town-name-text', CONFIG.townNameUpper);
|
||||||
|
set('exp-label-text', CONFIG.expLabel);
|
||||||
|
set('complete-msg-text', CONFIG.completeMsg);
|
||||||
|
if (CONFIG.badges) {
|
||||||
|
CONFIG.badges.forEach((b, i) => set(`badge-${i+1}`, b));
|
||||||
|
}
|
||||||
|
set('page-title', CONFIG.gameName + ' — Learn ' + CONFIG.subject);
|
||||||
|
document.title = CONFIG.gameName + ' — Learn ' + CONFIG.subject;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script src="config.js"></script>
|
||||||
<script src="game.js"></script>
|
<script src="game.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -379,7 +379,7 @@ html, body {
|
|||||||
.title-main { text-align:center; z-index:1; padding:24px 16px; }
|
.title-main { text-align:center; z-index:1; padding:24px 16px; }
|
||||||
.title-logo { margin-bottom:16px; line-height:1; }
|
.title-logo { margin-bottom:16px; line-height:1; }
|
||||||
.title-poke { font-size:clamp(22px,7.5vw,38px); color:var(--yellow); text-shadow:4px 4px 0 #7a5800,0 0 24px rgba(248,192,48,.5); animation:goldShimmer 3s ease-in-out infinite; display:inline-block; }
|
.title-poke { font-size:clamp(22px,7.5vw,38px); color:var(--yellow); text-shadow:4px 4px 0 #7a5800,0 0 24px rgba(248,192,48,.5); animation:goldShimmer 3s ease-in-out infinite; display:inline-block; }
|
||||||
.title-sql { font-size:clamp(22px,7.5vw,38px); color:#60c8ff; text-shadow:4px 4px 0 #003d70,0 0 24px rgba(96,200,255,.5); display:inline-block; animation:blueShimmer 3s ease-in-out infinite; }
|
.title-game { font-size:clamp(22px,7.5vw,38px); color:#60c8ff; text-shadow:4px 4px 0 #003d70,0 0 24px rgba(96,200,255,.5); display:inline-block; animation:blueShimmer 3s ease-in-out infinite; }
|
||||||
.title-sub { font-size:clamp(6px,1.8vw,8px); color:rgba(255,255,255,.75); letter-spacing:1px; margin:10px 0 6px; }
|
.title-sub { font-size:clamp(6px,1.8vw,8px); color:rgba(255,255,255,.75); letter-spacing:1px; margin:10px 0 6px; }
|
||||||
.title-edition { font-size:clamp(5.5px,1.6vw,7px); color:var(--yellow); margin-bottom:24px; animation:goldShimmer 3s ease-in-out infinite; }
|
.title-edition { font-size:clamp(5.5px,1.6vw,7px); color:var(--yellow); margin-bottom:24px; animation:goldShimmer 3s ease-in-out infinite; }
|
||||||
.title-deco { font-size:clamp(22px,6vw,32px); margin-bottom:28px; display:flex; gap:16px; justify-content:center; }
|
.title-deco { font-size:clamp(22px,6vw,32px); margin-bottom:28px; display:flex; gap:16px; justify-content:center; }
|
||||||
|
|||||||
Reference in New Issue
Block a user