Little Alchemy - Element Lab
by AtomicBolt46439 lines8.6 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Little Alchemy - Element Lab</title>
<style>
* { box-sizing:border-box; }
body {
margin:0;
font-family:Arial,sans-serif;
background:#101827;
color:white;
}
header {
padding:18px;
text-align:center;
background:#18243a;
}
h1 { margin:0; color:#70e5ff; }
header p { color:#bdc9dc; }
.main {
display:grid;
grid-template-columns:230px 1fr;
gap:12px;
padding:12px;
}
.panel {
background:#1b2940;
border-radius:12px;
padding:12px;
}
h3 { margin-top:5px; }
#elements {
display:flex;
flex-wrap:wrap;
gap:8px;
}
.element {
background:#344761;
border:1px solid #607794;
border-radius:9px;
padding:10px;
cursor:grab;
user-select:none;
text-align:center;
min-width:85px;
touch-action:none;
}
.element:hover { background:#486484; }
#workspace {
height:570px;
position:relative;
overflow:hidden;
background-color:#172438;
background-image:radial-gradient(#34445d 1px,transparent 1px);
background-size:22px 22px;
border:2px solid #435a79;
border-radius:12px;
}
.item {
position:absolute;
padding:10px 14px;
background:#344761;
border:2px solid #83cfff;
border-radius:12px;
cursor:grab;
user-select:none;
white-space:nowrap;
touch-action:none;
box-shadow:0 4px 10px #0005;
}
.item.selected {
border-color:#ffe66d;
background:#52678b;
}
button {
padding:10px 15px;
border:0;
border-radius:8px;
background:#5ac8fa;
color:#102030;
font-weight:bold;
cursor:pointer;
margin:3px;
}
button:hover { background:#9be4ff; }
#message {
color:#ffe66d;
min-height:22px;
text-align:center;
}
.stats {
color:#b9cce4;
margin:10px 0;
}
@media(max-width:650px) {
.main { grid-template-columns:1fr; }
#workspace { height:450px; }
#elements { max-height:200px; overflow:auto; }
}
</style>
</head>
<body>
<header>
<h1>๐งช LITTLE ALCHEMY</h1>
<p>Combine elements and discover a whole new world!</p>
</header>
<div class="main">
<div class="panel">
<h3>๐ Discoveries</h3>
<div class="stats">
Discovered: <span id="count">4</span>
</div>
<div id="elements"></div>
<br>
<button onclick="clearBoard()">Clear Board</button>
<button onclick="resetGame()">Reset Game</button>
</div>
<div class="panel">
<h3>๐ Experiment Table</h3>
<div id="workspace"></div>
<p id="message">Drag two elements together to combine them!</p>
</div>
</div>
<script>
const recipes = {
"water+fire":"Steam",
"earth+fire":"Lava",
"air+fire":"Energy",
"earth+water":"Mud",
"air+water":"Rain",
"air+earth":"Dust",
"fire+mud":"Brick",
"water+mud":"Plant",
"rain+earth":"Plant",
"rain+plant":"Flower",
"plant+earth":"Tree",
"plant+water":"Algae",
"fire+tree":"Ash",
"fire+wood":"Ash",
"tree+tree":"Forest",
"air+energy":"Storm",
"water+energy":"Life",
"earth+life":"Human",
"water+life":"Fish",
"air+life":"Bird",
"fire+life":"Phoenix",
"earth+lava":"Volcano",
"water+lava":"Stone",
"air+stone":"Sand",
"fire+sand":"Glass",
"water+sand":"Beach",
"stone+fire":"Metal",
"metal+energy":"Electricity",
"water+electricity":"Battery",
"electricity+metal":"Robot",
"human+stone":"Tool",
"human+tree":"Wood",
"human+fire":"Cook",
"human+water":"Swimmer",
"bird+water":"Duck",
"bird+fire":"Phoenix",
"fish+human":"Mermaid",
"plant+sun":"Flower",
"sun+water":"Rainbow",
"sun+fire":"Solar Energy",
"air+steam":"Cloud",
"cloud+water":"Rain",
"cloud+energy":"Lightning",
"lightning+metal":"Electricity",
"earth+plant":"Grass",
"grass+water":"Swamp",
"swamp+energy":"Life",
"mud+fire":"Brick",
"stone+human":"Statue",
"metal+human":"Knight",
"fire+metal":"Sword",
"water+ice":"Ocean",
"ice+sun":"Water",
"water+water":"Ocean",
"fire+fire":"Energy",
"air+air":"Wind",
"earth+earth":"Land",
"wind+water":"Wave",
"wave+earth":"Beach",
"ocean+life":"Whale",
"human+electricity":"Scientist",
"scientist+robot":"Cyborg",
"tree+fire":"Charcoal"
};
function key(a,b) {
return [a,b].sort().join("+").toLowerCase();
}
const database = {
"earth":"๐",
"water":"๐ง",
"fire":"๐ฅ",
"air":"๐จ",
"steam":"โจ๏ธ",
"lava":"๐",
"energy":"โก",
"mud":"๐ค",
"rain":"๐ง๏ธ",
"dust":"๐ซ๏ธ",
"brick":"๐งฑ",
"plant":"๐ฑ",
"flower":"๐ธ",
"tree":"๐ณ",
"algae":"๐ชธ",
"ash":"๐",
"wood":"๐ชต",
"forest":"๐ฒ",
"storm":"โ๏ธ",
"life":"๐งฌ",
"human":"๐ง",
"fish":"๐",
"bird":"๐ฆ",
"phoenix":"๐ฆ
",
"volcano":"๐",
"stone":"๐ชจ",
"sand":"๐๏ธ",
"glass":"๐ช",
"beach":"๐๏ธ",
"metal":"๐ฉ",
"electricity":"โก",
"battery":"๐",
"robot":"๐ค",
"tool":"๐จ",
"cook":"๐จโ๐ณ",
"swimmer":"๐",
"duck":"๐ฆ",
"mermaid":"๐ง",
"sun":"โ๏ธ",
"rainbow":"๐",
"solar energy":"๐",
"cloud":"โ๏ธ",
"lightning":"๐ฉ๏ธ",
"grass":"๐ฟ",
"swamp":"๐",
"statue":"๐ฟ",
"knight":"โ๏ธ",
"sword":"๐ก๏ธ",
"ice":"๐ง",
"ocean":"๐",
"wind":"๐ฌ๏ธ",
"land":"๐๏ธ",
"wave":"๐",
"whale":"๐",
"scientist":"๐งโ๐ฌ",
"cyborg":"๐ฆพ",
"charcoal":"โฌ"
};
let discovered = ["Earth","Water","Fire","Air"];
let selected = null;
let dragging = null;
let offsetX = 0;
let offsetY = 0;
const workspace = document.getElementById("workspace");
function emoji(name) {
return database[name.toLowerCase()] || "โจ";
}
function updateList() {
const list = document.getElementById("elements");
list.innerHTML = "";
discovered.forEach(name => {
const el = document.createElement("div");
el.className = "element";
el.textContent = emoji(name)+" "+name;
el.onpointerdown = e => {
if(e.target.closest(".element")) {
createItem(name, 100+Math.random()*250,
100+Math.random()*250);
}
};
list.appendChild(el);
});
document.getElementById("count").textContent =
discovered.length;
}
function createItem(name,x,y) {
const item = document.createElement("div");
item.className = "item";
item.textContent = emoji(name)+" "+name;
item.dataset.name = name;
item.style.left = Math.max(0,Math.min(
workspace.clientWidth-100,x))+"px";
item.style.top = Math.max(0,Math.min(
workspace.clientHeight-50,y))+"px";
workspace.appendChild(item);
item.addEventListener("pointerdown", e => {
e.preventDefault();
dragging = item;
const rect = item.getBoundingClientRect();
const board = workspace.getBoundingClientRect();
offsetX = e.clientX-rect.left;
offsetY = e.clientY-rect.top;
item.setPointerCapture(e.pointerId);
item.style.zIndex = 1000;
});
item.addEventListener("pointermove", e => {
if(dragging !== item) return;
const rect = workspace.getBoundingClientRect();
item.style.left = Math.max(0,Math.min(
workspace.clientWidth-item.offsetWidth,
e.clientX-rect.left-offsetX))+"px";
item.style.top = Math.max(0,Math.min(
workspace.clientHeight-item.offsetHeight,
e.clientY-rect.top-offsetY))+"px";
});
item.addEventListener("pointerup", () => {
if(dragging !== item) return;
dragging = null;
item.style.zIndex = 1;
const others = [...workspace.querySelectorAll(".item")]
.filter(el => el !== item);
for(const other of others) {
if(overlap(item,other)) {
combine(item,other);
break;
}
}
});
}
function overlap(a,b) {
const r1 = a.getBoundingClientRect();
const r2 = b.getBoundingClientRect();
return !(r1.right<r2.left ||
r1.left>r2.right ||
r1.bottom<r2.top ||
r1.top>r2.bottom);
}
function combine(a,b) {
const first = a.dataset.name;
const second = b.dataset.name;
const result = recipes[key(first,second)];
if(!result) {
document.getElementById("message").textContent =
"โ No combination found! Try something else.";
return;
}
if(discovered.includes(result)) {
document.getElementById("message").textContent =
"You already discovered "+result+"!";
return;
}
const rect = a.getBoundingClientRect();
const board = workspace.getBoundingClientRect();
const x = rect.left-board.left;
const y = rect.top-board.top;
a.remove();
b.remove();
discovered.push(result);
updateList();
createItem(result,x,y);
document.getElementById("message").textContent =
"๐ NEW DISCOVERY: "+emoji(result)+" "+result+"!";
}
function clearBoard() {
workspace.innerHTML = "";
document.getElementById("message").textContent =
"Board cleared! Drag in some elements.";
}
function resetGame() {
discovered = ["Earth","Water","Fire","Air"];
clearBoard();
updateList();
document.getElementById("message").textContent =
"Fresh start! Discover new elements!";
}
updateList();
</script>
</body>
</html>Game Source: Little Alchemy - Element Lab
Creator: AtomicBolt46
Libraries: none
Complexity: complex (439 lines, 8.6 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: little-alchemy-element-lab-atomicbolt46" to link back to the original. Then publish at arcadelab.ai/publish.