Pizzería Simulador 2D 🇦🇷
by MegaGalaxy31716 lines19.7 KB
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pizzería Simulador 2D 🇦🇷</title>
<style>
* {box-sizing: border-box; margin: 0; padding: 0;}
body {
font-family: 'Segoe UI', Roboto, Arial, sans-serif;
background: #2c1810;
color: #f8f4e9;
display: flex;
justify-content: center;
line-height: 1.5;
}
#app {
width: 100%;
max-width: 980px;
padding: 12px;
}
h1 {
text-align: center;
margin: 8px 0 16px;
font-size: 24px;
color: #ffcc44;
text-shadow: 2px 2px 0 #884400;
}
/* Panel Superior */
#top {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
gap: 8px;
background: #442614;
padding: 12px;
border-radius: 8px;
border: 3px solid #884400;
font-size: 11px;
}
.top-block {
background: #5a331a;
padding: 8px;
border-radius: 6px;
border: 2px solid #995511;
text-align: center;
}
.top-label {
font-size: 9px;
color: #e0c8a0;
display: block;
}
.top-value {
font-weight: bold;
color: #fff8e6;
font-size: 13px;
}
.neg { color: #ff6666; }
.pos { color: #88ff88; }
/* Botones Principales */
.btn-row {
display: flex;
gap: 8px;
margin: 12px 0;
flex-wrap: wrap;
}
.btn-row button {
flex: 1;
padding: 9px;
border: 3px solid #663300;
border-radius: 6px;
font-weight: bold;
cursor: pointer;
background: #b36b24;
color: #fff;
font-size: 12px;
transition: all 0.15s;
}
.btn-row button:hover { transform: scale(1.03); background: #cc8033; }
.btn-row button:active { transform: scale(0.98); }
/* Cocina 2D */
#kitchen-2d {
background: #5a331a;
border: 4px solid #884400;
border-radius: 8px;
padding: 16px;
position: relative;
height: 400px;
margin-bottom: 12px;
overflow: hidden;
background-image:
linear-gradient(90deg, #6b3e20 20px, transparent 20px),
linear-gradient(#6b3e20 20px, transparent 20px);
background-size: 40px 40px;
}
.zone {
position: absolute;
border: 3px solid #995511;
border-radius: 6px;
background: #7a4522;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-weight: bold;
color: #fff8e6;
box-shadow: inset 0 0 10px rgba(0,0,0,0.3);
}
#ingredients-table { width: 220px; height: 200px; top: 20px; left: 20px; font-size: 12px; }
#oven { width: 160px; height: 220px; top: 20px; right: 20px; font-size: 14px; }
#counter { width: 340px; height: 100px; bottom: 20px; left: 50%; transform: translateX(-50%); font-size: 12px; }
/* Pizza */
#pizza-2d {
width: 120px;
height: 120px;
border-radius: 50%;
background: #f9d076;
border: 4px solid #b87a3e;
position: relative;
margin: 8px auto;
box-shadow: inset 0 0 10px rgba(0,0,0,0.4);
transition: all 0.4s ease;
}
#pizza-2d.fresh { box-shadow: inset 0 0 10px rgba(0,0,0,0.4), 0 0 10px #ffdd44; }
#pizza-2d.regular { filter: brightness(0.92); }
#pizza-2d.dry { filter: brightness(0.78) saturate(0.85); }
#pizza-2d.overcooked { filter: brightness(0.65) saturate(0.7); }
#pizza-2d.burnt { background: #5a280e; border-color: #3a1808; filter: brightness(0.5); }
.ing-2d {
position: absolute;
width: 14px;
height: 14px;
border-radius: 50%;
box-shadow: 0 0 2px rgba(0,0,0,0.7);
}
.tomato { background: #dc2626; }
.cheese { background: #ffdd44; }
.pepper { background: #22aa44; }
.ham { background: #994411; }
.mushroom { background: #774422; }
.onion { background: #e8e0f0; }
.olive { background: #111122; }
.oregano { background: #559922; }
/* Lista Ingredientes */
#ing-list {
width: 100%;
height: 150px;
overflow-y: auto;
padding: 4px;
font-size: 10px;
}
.ing-btn {
background: #995522;
border: 2px solid #cc8833;
border-radius: 4px;
padding: 3px 5px;
margin: 2px 0;
cursor: pointer;
color: #fff;
text-align: left;
transition: all 0.2s;
}
.ing-btn.out { opacity: 0.35; cursor: not-allowed; }
.ing-btn:hover:not(.out) { background: #b36b24; }
/* Cliente y Pedido */
#client-bar {
background: #442614;
border: 3px solid #884400;
border-radius: 8px;
padding: 10px;
margin-bottom: 12px;
font-size: 12px;
}
#bar-wrap {
height: 16px;
background: #663311;
border-radius: 8px;
overflow: hidden;
margin-top: 6px;
border: 2px solid #995511;
}
#bar {
height: 100%;
width: 100%;
background: linear-gradient(90deg, #ff4422 0%, #ffcc22 50%, #22cc44 100%);
transition: width 0.2s ease;
}
#ticket {
background: #442614;
border: 3px solid #884400;
border-radius: 8px;
padding: 12px;
margin-bottom: 12px;
font-family: 'Courier New', monospace;
font-size: 12px;
}
/* Botones de Acción */
.action-btn {
width: 100%;
padding: 9px;
margin: 5px 0;
border: 3px solid #662200;
border-radius: 6px;
font-weight: bold;
cursor: pointer;
font-size: 12px;
}
#cook-btn { background: #cc3311; color: white; }
#serve-btn { background: #229933; color: white; }
#reset-btn { background: #775533; color: white; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
/* Modales */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.85);
justify-content: center;
align-items: center;
z-index: 200;
}
.modal-content {
background: #442614;
border: 4px solid #ffaa22;
border-radius: 10px;
padding: 20px;
width: 92%;
max-width: 580px;
max-height: 90vh;
overflow-y: auto;
}
.modal h3 {
text-align: center;
margin-bottom: 15px;
color: #ffdd44;
}
.store-item, .inv-item, .loan-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
margin: 6px 0;
background: #5a331a;
border-radius: 6px;
border: 2px solid #995522;
font-size: 12px;
}
.fresh { border-color: #44aa44; background: #335522; }
.close-modal {
width: 100%;
background: #cc3311;
border: 2px solid #882200;
color: white;
margin-top: 12px;
padding: 8px;
border-radius: 6px;
cursor: pointer;
}
#resumen {
display: none;
background: #442614;
border: 3px solid #ffaa22;
border-radius: 8px;
padding: 16px;
margin: 12px 0;
font-size: 12px;
}
#msg {
text-align: center;
padding: 8px;
background: #442614;
border-radius: 6px;
margin-top: 8px;
border: 2px solid #884400;
min-height: 36px;
font-size: 12px;
}
</style>
</head>
<body>
<div id="app">
<h1>🍕 Pizzería Simulador 2D 🇦🇷</h1>
<!-- Panel Superior -->
<div id="top">
<div class="top-block"><span class="top-label">Caja</span><span class="top-value">$<span id="money">8500</span></span></div>
<div class="top-block"><span class="top-label">Día</span><span class="top-value"><span id="day">1</span></span></div>
<div class="top-block"><span class="top-label">Pedidos</span><span class="top-value"><span id="ordersDone">0</span>/<span id="ordersGoal">3</span></span></div>
<div class="top-block"><span class="top-label">Horno</span><span class="top-value" id="ovenStatus">100%</span></div>
<div class="top-block"><span class="top-label">Heladera</span><span class="top-value" id="fridgeStatus">✅</span></div>
<div class="top-block"><span class="top-label">Clima</span><span class="top-value" id="weather">☀️</span></div>
<div class="top-block"><span class="top-label">Temp</span><span class="top-value" id="temp">22°C</span></div>
<div class="top-block"><span class="top-label">Inflación</span><span class="top-value" id="inflation">3.8%</span></div>
<div class="top-block"><span class="top-label">Deuda</span><span class="top-value neg" id="debt">$0</span></div>
</div>
<!-- Botones Principales -->
<div class="btn-row">
<button onclick="openStore()">🛒 Comprar</button>
<button onclick="openInventory()">📦 Stock</button>
<button onclick="openMaintenance()">🔧 Equipos</button>
<button onclick="openFinances()">📊 Finanzas</button>
<button onclick="openLoans()">💸 Préstamos</button>
</div>
<!-- Barra de Cliente -->
<div id="client-bar">
<span>👤 Cliente: <span id="clientName">-</span> | <span id="clientType"></span></span>
<div id="bar-wrap"><div id="bar"></div></div>
</div>
<!-- Pedido Actual -->
<div id="ticket">📝 Pedido: <span id="orderText">Esperando...</span></div>
<!-- Cocina -->
<div id="kitchen-2d">
<div id="ingredients-table" class="zone">
🧺 Ingredientes
<div id="ing-list"></div>
</div>
<div id="oven" class="zone">
🔥 Horno
<div id="pizza-2d" class="fresh"></div>
<div id="ovenInfo">Listo</div>
<button id="cook-btn" class="action-btn" onclick="startCooking()">Cocinar</button>
</div>
<div id="counter" class="zone">
🛎️ Mostrador
<button id="serve-btn" class="action-btn" onclick="serveOrder()" disabled>Entregar</button>
<button id="reset-btn" class="action-btn" onclick="resetPizza()">Deshacer ($30)</button>
</div>
</div>
<!-- Modales -->
<div id="storeModal" class="modal">
<div class="modal-content">
<h3>🛒 Proveedor Mayorista</h3>
<p>💰 Efectivo: $<span id="storeMoney">0</span></p>
<div id="storeList"></div>
<button class="close-modal" onclick="closeStore()">Cerrar</button>
</div>
</div>
<div id="inventoryModal" class="modal">
<div class="modal-content">
<h3>📦 Control de Stock</h3>
<p>🔴 Vencido | 🟡 Por vencer | 🟢 Buen estado</p>
<div id="inventoryList"></div>
<button class="close-modal" onclick="closeInventory()">Cerrar</button>
</div>
</div>
<div id="maintenanceModal" class="modal">
<div class="modal-content">
<h3>🔧 Mantenimiento</h3>
<p>Horno: <span id="ovenStatusText"></span></p>
<p>Heladera: <span id="fridgeStatusText"></span></p>
<div class="store-item"><span>🔧 Reparar horno</span><span>$2500</span><button onclick="repairOven()">Hacer</button></div>
<div class="store-item"><span>❄️ Reparar heladera</span><span>$950</span><button onclick="repairFridge()">Hacer</button></div>
<button class="close-modal" onclick="closeMaintenance()">Cerrar</button>
</div>
</div>
<div id="financesModal" class="modal">
<div class="modal-content">
<h3>📊 Finanzas</h3>
<div id="financesContent"></div>
<button class="close-modal" onclick="closeFinances()">Cerrar</button>
</div>
</div>
<div id="loansModal" class="modal">
<div class="modal-content">
<h3>💸 Préstamos</h3>
<p>Deuda actual: $<span id="currentDebt">0</span></p>
<div id="loansList"></div>
<button class="close-modal" onclick="closeLoans()">Cerrar</button>
</div>
</div>
<div id="resumen">
<h3>📊 Cierre del Día <span id="resDay"></span></h3>
<p>✅ Pedidos: <span id="resOrders"></span> / <span id="resGoal"></span></p>
<p>💵 Ventas: +$<span id="resIncome"></span></p>
<p>🛒 Gastos: -$<span id="resExpenses"></span></p>
<p><strong>📈 Ganancia: $<span id="resNet"></span></strong></p>
<button onclick="startNewDay()" style="width:100%; margin-top:15px; padding:10px; background:#ffaa22; border:none; border-radius:6px; font-weight:bold;">➡️ Siguiente día</button>
</div>
<div id="msg">¡Empezá comprando insumos!</div>
</div>
<script>
// --------------------------
// VARIABLES
// --------------------------
let money = 8500;
let day = 1;
let ordersDone = 0;
let ordersGoal = 3;
let dailyIncome = 0;
let dailyExpenses = 0;
let debt = 0;
let ovenCondition = 100;
let fridgeCondition = 100;
let inventory = [];
let currentOrder = [];
let pizzaBuild = [];
let isCooked = false;
let isCooking = false;
let isBurnt = false;
const names = ["Luca","Mia","Sofia","Nico","Emma","Tomas","Julia","Bruno","Ana","Pablo","Martina"];
const ingNames = {
dough:"Masa", tomato:"Salsa", cheese:"Queso", pepper:"Pimiento", ham:"Jamón",
mushroom:"Champiñón", onion:"Cebolla", olive:"Aceituna", oregano:"Orégano"
};
const basePrices = {
dough:1600, tomato:1250, cheese:2350, pepper:800, ham:2800, mushroom:1800,
onion:900, olive:1350, oregano:450
};
const recipes = {
1: [["dough","tomato","cheese"], ["dough","tomato","cheese","pepper"]],
2: [["dough","tomato","cheese","ham"], ["dough","tomato","cheese","oregano"]],
3: [["dough","tomato","cheese","ham","mushroom"]]
};
// --------------------------
// INICIO
// --------------------------
window.onload = startGame;
function startGame() {
updateUI();
newClientOrder();
updateAvailableStock();
updateOvenUI();
updateFridgeUI();
}
// --------------------------
// ACTUALIZAR INTERFAZ GENERAL
// --------------------------
function updateUI() {
document.getElementById("money").textContent = money;
document.getElementById("day").textContent = day;
document.getElementById("ordersDone").textContent = ordersDone;
document.getElementById("debt").textContent = debt;
}
function setMessage(text) {
document.getElementById("msg").textContent = text;
}
// --------------------------
// CLIENTES Y PEDIDOS
// --------------------------
function newClientOrder() {
if(ordersDone >= ordersGoal) { endDay(); return; }
const dayRecipes = recipes[Math.min(day,3)];
currentOrder = dayRecipes[Math.floor(Math.random() * dayRecipes.length)];
document.getElementById("orderText").textContent = currentOrder.map(i => ingNames[i]).join(" + ");
document.getElementById("clientName").textContent = names[Math.floor(Math.random() * names.length)];
document.getElementById("clientType").textContent = "Cliente habitual";
pizzaBuild = [];
isCooked = false;
isCooking = false;
isBurnt = false;
document.getElementById("serve-btn").disabled = true;
document.getElementById("pizza-2d").className = "fresh";
document.getElementById("ovenInfo").textContent = "Listo";
renderPizza();
}
// --------------------------
// INGREDIENTES
// --------------------------
function addIngredient(type) {
if(isCooking || isCooked) return;
if(!hasIngredient(type)) {
setMessage(`❌ No hay ${ingNames[type]}`);
return;
}
consumeIngredient(type);
pizzaBuild.push(type);
renderPizza();
updateAvailableStock();
setMessage(`✔ Agregado: ${ingNames[type]}`);
}
function hasIngredient(type) {
return inventory.some(i => i.type === type && i.quantity > 0);
}
function consumeIngredient(type) {
for(let i=0; i<inventory.length; i++) {
if(inventory[i].type === type && inventory[i].quantity > 0) {
inventory[i].quantity--;
if(inventory[i].quantity <= 0) inventory.splice(i,1);
break;
}
}
}
function renderPizza() {
const pizza = document.getElementById("pizza-2d");
pizza.innerHTML = "";
pizzaBuild.forEach((ing, i) => {
const el = document.createElement("div");
el.className = `ing-2d ${ing}`;
el.style.left = `${20 + (i % 4) * 20}px`;
el.style.top = `${20 + Math.floor(i / 4) * 20}px`;
pizza.appendChild(el);
});
}
function updateAvailableStock() {
const list = document.getElementById("ing-list");
list.innerHTML = "";
const total = {};
for(const ing of Object.keys(ingNames)) total[ing] = 0;
inventory.forEach(i => total[i.type] += i.quantity);
for(const ing of Object.keys(total)) {
const cls = total[ing] > 0 ? "ing-btn" : "ing-btn out";
list.innerHTML += `<div class="${cls}" onclick="addIngredient('${ing}')">${ingNames[ing]}: ${total[ing]}</div>`;
}
}
// --------------------------
// COCCIÓN
// --------------------------
function startCooking() {
if(isCooking || pizzaBuild.length === 0 || ovenCondition < 20) {
setMessage(ovenCondition < 20 ? "⚠️ El horno está muy dañado" : "⚠️ No se puede cocinar");
return;
}
isCooking = true;
let time = 0;
const timer = setInterval(() => {
time++;
document.getElementById("ovenInfo").textContent = `Cocinando... ${time}s`;
if(time >= 6) {
clearInterval(timer);
isCooking = false;
isCooked = true;
ovenCondition = Math.max(0, ovenCondition - 5);
updateOvenUI();
if(time > 9) {
isBurnt = true;
document.getElementById("pizza-2d").className = "burnt";
setMessage("🔥 Se quemó la pizza");
} else if(time > 7) {
document.getElementById("pizza-2d").className = "overcooked";
setMessage("⚠️ Un poco pasada");
} else {
document.getElementById("pizza-2d").className = "regular";
setMessage("🍕 Lista para servir");
}
document.getElementById("serve-btn").disabled = false;
}
}, 1000);
}
// --------------------------
// SERVIR
// --------------------------
function serveOrder() {
if(!isCooked) return;
let correct = JSON.stringify([...pizzaBuild].sort()) === JSON.stringify([...currentOrder].sort());
let earn = correct ? 1200 : 400;
if(isBurnt) earn = 100;
money += earn;
dailyIncome += earn;
ordersDone++;
updateUI();
setMessage(correct ? "😎 Pedido perfecto!" : "😅 Pedido incompleto o mal armado");
setTimeout(newClientOrder, 1500);
}
// --------------------------
// REINICIAR
// --------------------------
function resetPizza() {
if(money < 30 || isCooking) return setMessage("❌ No se puede deshacer");
money -= 30;
dailyExpenses += 30;
// Devolver ingredientes
pizzaBuild.forEach(ing => {
const exists = inventory.find(i => i.type === ing);
if(exists) exists.quantity++;
else inventory.push({type:ing, quantity:1});
});
pizzaBuild = [];
isCooked = false;
isBurnt = false;
document.getElementById("serve-btn").disabled = true;
renderPizza();
updateAvailableStock();
updateUI();
setMessage("🔄 Deshecho, ingredientes devueltos");
}
// --------------------------
// TIENDA
// --------------------------
function openStore() {
document.getElementById("storeMoney").textContent = money;
const list = document.getElementById("storeList");
list.innerHTML = "";
for(const ing of Object.keys(basePrices)) {
list.innerHTML += `<div class="store-item">
<span>${ingNames[ing]} (10u)</span>
<span>$${basePrices[ing]}</span>
<button onclick="buy('${ing}')">Comprar</button>
</div>`;
}
document.getElementById("storeModal").style.display = "flex";
}
function closeStore() { document.getElementById("storeModal").style.display = "none"; }
function buy(type) {
const price = basePrices[type];
if(money < price) { setMessage("❌ No alcanza el dinero"); return; }
money -= price;
dailyExpenses += price;
const item = inventory.find(i => i.type === type);
if(item) item.quantity += 10;
else inventory.push({type, quantity:10});
updateAvailableStock();
updateUI();
closeStore();
setMessage(`✅ Comprado: ${ingNames[type]}`);
}
// --------------------------
// STOCK
// --------------------------
function openInventory() {
const list = document.getElementById("inventoryList");
list.innerHTML = "";
if(inventory.length === 0) {
list.innerHTML = "<p>No hay ingredientes en stock</p>";
} else {
inventory.forEach(i => {
list.innerHTML += `<div class="inv-item fresh">
<span>${ingNames[i.type]}</span>
<span>${i.quantity} unidades</span>
</div>`;
});
}
document.getElementById("inventoryModal").style.display = "flex";
}
function closeInventory() { document.getElementById("inventoryModal").style.display = "none"; }
// --------------------------
// MANTENIMIENTO
// --------------------------
function openMaintenance() {
updateOvenUI();
updateFridgeUI();
document.getElementById("maintenanceModal").style.display = "flex";
}
function closeMaintenance() { document.getElementById("maintenanceModal").style.display = "none"; }
function repairOven() {
if(money < 2500) return setMessage("❌ No alcanza para reparar");
money -= 2500;
dailyExpenses += 2500;
ovenCondition = 100;
updateOvenUI();
closeMaintenance();
setMessage("✅ Horno reparado al 100%");
}
function repairFridge() {
if(money < 950) return setMessage("❌ No alcanza para reparar");
money -= 950;
dailyExpenses += 950;
fridgeCondition = 100;
updateFridgeUI();
closeMaintenance();
setMessage("✅ Heladera reparada al 100%");
}
function updateOvenUI() {
document.getElementById("ovenStatus").textContent = `${ovenCondition}%`;
document.getElementById("ovenStatusText").textContent = `${ovenCondition}%`;
}
function updateFridgeUI() {
document.getElGame Source: Pizzería Simulador 2D 🇦🇷
Creator: MegaGalaxy31
Libraries: none
Complexity: complex (716 lines, 19.7 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: pizzer-a-simulador-2d-megagalaxy31" to link back to the original. Then publish at arcadelab.ai/publish.