Pokémon Chile: Región Aukan
by AstroHero57499 lines14.9 KB
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Pokémon Chile: Región Aukan</title>
<style>
*{box-sizing:border-box}
body{margin:0;background:#101827;color:white;font-family:Arial,sans-serif}
button{border:0;border-radius:10px;padding:12px;background:#ffcc00;color:#101827;font-weight:bold;font-size:14px}
button:disabled{opacity:.4}
header{background:#0a192f;padding:12px;text-align:center;border-bottom:3px solid #ffcc00}
header b{color:#ffcc00}
#app{max-width:900px;margin:auto;padding:12px}
.panel{background:#1e293b;border:1px solid #475569;border-radius:15px;padding:15px;margin:10px 0}
h1,h2,h3{margin-top:5px}
.small{font-size:12px;color:#cbd5e1}
.grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
#world{width:100%;height:auto;background:#65a653;border-radius:12px;touch-action:none}
#battleCanvas{width:100%;background:#253b35;border-radius:12px;touch-action:none}
#controls{display:flex;justify-content:space-between;gap:15px;margin-top:10px}
#pad{display:grid;grid-template-columns:45px 45px 45px;grid-template-rows:45px 45px 45px;gap:3px}
#pad button{padding:0;background:#334155;color:white}
#pad span{display:block}
#actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.hidden{display:none!important}
.bar{height:12px;background:#475569;border-radius:20px;overflow:hidden;margin:5px 0}
.bar div{height:100%;background:#22c55e;width:100%}
.card{background:#334155;border-radius:12px;padding:12px}
</style>
</head>
<body>
<header>
<b>🇨🇱 POKÉMON CHILE</b> — REGIÓN AUKAN
</header>
<div id="app">
<section id="menu" class="panel">
<h1>Pokémon Chile</h1>
<p>Una aventura por todo Chile.</p>
<button onclick="newGame()">Nueva partida</button>
<button onclick="continueGame()">Continuar</button>
<p class="small">Versión de desarrollo para Android y PC.</p>
</section>
<section id="starter" class="panel hidden">
<h2>Elige tu Pokémon inicial</h2>
<div class="grid" id="starterChoices"></div>
</section>
<section id="gameScreen" class="hidden">
<div class="panel">
<b id="locationName">Región de La Araucanía</b>
<span class="small" id="coordinates"></span>
<div class="small" id="teamSummary"></div>
</div>
<canvas id="world" width="800" height="480"></canvas>
<div id="controls">
<div id="pad">
<span></span><button data-key="up">▲</button><span></span>
<button data-key="left">◀</button><span></span><button data-key="right">▶</button>
<span></span><button data-key="down">▼</button><span></span>
</div>
<div id="actions">
<button onclick="interact()">Interactuar</button>
<button onclick="showDex()">Pokédex</button>
<button onclick="showMap()">Regiones</button>
<button onclick="showTeam()">Equipo</button>
<button onclick="saveGame()">Guardar</button>
</div>
</div>
</section>
<section id="battleScreen" class="panel hidden">
<h2>⚔️ Combate en tiempo real</h2>
<canvas id="battleCanvas" width="800" height="330"></canvas>
<div class="grid">
<div class="card">
<b id="myName"></b>
<div class="bar"><div id="myBar"></div></div>
<small id="myHP"></small>
</div>
<div class="card">
<b id="foeName"></b>
<div class="bar"><div id="foeBar"></div></div>
<small id="foeHP"></small>
</div>
</div>
<p id="battleMessage">¡Un Pokémon salvaje apareció!</p>
<div class="grid">
<button onclick="useMove(0)">Ataque 1</button>
<button onclick="useMove(1)">Ataque 2</button>
<button onclick="useMove(2)">Ataque 3</button>
<button onclick="useMove(3)">Ataque 4</button>
<button onclick="throwBall()">🔴 Poké Ball</button>
<button onclick="flee()">Escapar</button>
</div>
<div id="battlePad" class="small">Muévete con las flechas o WASD para esquivar.</div>
</section>
<section id="info" class="panel hidden">
<div id="infoContent"></div>
<button onclick="closeInfo()">Volver</button>
</section>
</div>
<script>
"use strict";
// =====================================
// DATOS GENERALES DEL JUEGO
// =====================================
const TYPES = [
"Normal","Fuego","Agua","Planta","Eléctrico","Hielo",
"Lucha","Veneno","Tierra","Volador","Psíquico","Bicho",
"Roca","Fantasma","Dragón","Siniestro","Acero","Hada",
"Cósmico","Espíritu","Urbano","Orden","Ritmo","Mitológico",
"Club de Fútbol","Huaso","Minero","Folclore","Pastero",
"Paranormal","Dinosaurio","Cuico","Youtuber","Guardia",
"Ladrón","Mafioso","Influencer","Político"
];
const REGIONS = [
"Arica y Parinacota","Tarapacá","Antofagasta","Atacama",
"Coquimbo","Valparaíso","Metropolitana","O'Higgins",
"Maule","Ñuble","Biobío","La Araucanía","Los Ríos",
"Los Lagos","Aysén","Magallanes y la Antártica Chilena"
];
const starters = [
{name:"Pudú",emoji:"🦌",type:"Planta",hp:60,moves:["Placaje","Hoja veloz","Raíces","Poder natural"]},
{name:"Zorro Culpeo",emoji:"🦊",type:"Fuego",hp:55,moves:["Mordisco","Llamarada","Embestida","Fuego salvaje"]},
{name:"Pingüino de Humboldt",emoji:"🐧",type:"Agua",hp:65,moves:["Picotazo","Burbuja","Chorro de agua","Marea"] }
];
const wildSpecies = [
{name:"Monito del Monte",emoji:"🐭",type:"Espíritu",hp:35},
{name:"Cóndor",emoji:"🦅",type:"Volador",hp:45},
{name:"Zorro Culpeo",emoji:"🦊",type:"Fuego",hp:42},
{name:"Pudú",emoji:"🦌",type:"Planta",hp:38},
{name:"Pingüino de Humboldt",emoji:"🐧",type:"Agua",hp:40},
{name:"Lagarto Chileno",emoji:"🦎",type:"Tierra",hp:32}
];
let state={
mode:"menu",
region:11,
city:"Temuco",
player:{x:400,y:250,speed:3},
team:[],
dex:[],
balls:10,
enemy:null,
lastEncounter:0,
keys:{},
battleFrame:0
};
const $=id=>document.getElementById(id);
const world=$("world");
const ctx=world.getContext("2d");
const bc=$("battleCanvas").getContext("2d");
// =====================================
// PANTALLAS
// =====================================
function screen(name){
["menu","starter","gameScreen","battleScreen","info"].forEach(id=>{
$(id).classList.toggle("hidden",id!==name);
});
}
function newGame(){
state.team=[];
state.dex=[];
state.balls=10;
$("starterChoices").innerHTML="";
starters.forEach((p,i)=>{
const b=document.createElement("button");
b.innerHTML=`<div style="font-size:38px">${p.emoji}</div>
<b>${p.name}</b><br>${p.type}<br>Elegir`;
b.onclick=()=>chooseStarter(i);
$("starterChoices").appendChild(b);
});
screen("starter");
}
function chooseStarter(i){
const p=starters[i];
state.team=[{
...p,maxHp:p.hp,level:5,energy:100
}];
state.dex=[p.name];
state.mode="world";
screen("gameScreen");
refreshHUD();
drawWorld();
}
function continueGame(){
try{
const saved=JSON.parse(localStorage.getItem("aukanSave"));
if(!saved){alert("No hay una partida guardada.");return;}
Object.assign(state,saved);
state.mode="world";
screen("gameScreen");
refreshHUD();
drawWorld();
}catch(e){alert("No se pudo cargar la partida.");}
}
function saveGame(){
const data={
region:state.region,city:state.city,
player:state.player,team:state.team,
dex:state.dex,balls:state.balls
};
localStorage.setItem("aukanSave",JSON.stringify(data));
alert("¡Partida guardada!");
}
function refreshHUD(){
$("locationName").textContent=REGIONS[state.region]+" — "+state.city;
$("teamSummary").textContent="Equipo: "+state.team.map(p=>p.name).join(", ");
$("coordinates").textContent=" | Poké Balls: "+state.balls;
}
// =====================================
// EXPLORACIÓN
// =====================================
function drawWorld(){
if(state.mode!=="world")return;
const w=world.width,h=world.height;
ctx.clearRect(0,0,w,h);
ctx.fillStyle="#73a957";
ctx.fillRect(0,0,w,h);
// Camino
ctx.fillStyle="#c6a77b";
ctx.fillRect(0,190,w,95);
// Río y puente
ctx.fillStyle="#399ac4";
ctx.fillRect(560,0,75,h);
ctx.fillStyle="#9b7653";
ctx.fillRect(548,205,100,40);
// Vegetación
for(let i=0;i<75;i++){
let x=(i*97+43)%w,y=(i*61+17)%h;
if(y>185&&y<290)continue;
ctx.fillStyle="#276d38";
ctx.beginPath();ctx.arc(x,y,17,0,Math.PI*2);ctx.fill();
ctx.fillStyle="#347f40";
ctx.beginPath();ctx.arc(x-5,y-6,10,0,Math.PI*2);ctx.fill();
}
// Hierba alta
for(let i=0;i<8;i++){
let x=60+i*82,y=330+(i%2)*30;
ctx.fillStyle="#286c35";
ctx.fillRect(x,y,40,45);
ctx.fillStyle="#8ac65a";
for(let j=0;j<4;j++)ctx.fillRect(x+j*9,y+4,4,30);
}
// Edificios
ctx.fillStyle="#b76c46";
ctx.fillRect(680,55,90,85);
ctx.fillStyle="#f3d49b";
ctx.fillRect(695,72,23,22);
ctx.fillRect(733,72,23,22);
ctx.fillStyle="#70442e";
ctx.fillRect(713,105,25,35);
// Jugador
ctx.fillStyle="#1d4ed8";
ctx.fillRect(state.player.x-11,state.player.y-15,22,30);
ctx.fillStyle="#f5d0a2";
ctx.fillRect(state.player.x-8,state.player.y-25,16,12);
requestAnimationFrame(drawWorld);
}
function movePlayer(){
if(state.mode!=="world")return;
const p=state.player;
let dx=0,dy=0;
if(state.keys.up)dy--;
if(state.keys.down)dy++;
if(state.keys.left)dx--;
if(state.keys.right)dx++;
if(dx||dy){
const l=Math.hypot(dx,dy);
p.x+=dx/l*p.speed;p.y+=dy/l*p.speed;
p.x=Math.max(15,Math.min(785,p.x));
p.y=Math.max(15,Math.min(465,p.y));
if(p.y>325&&Math.random()<0.012)encounter();
}
requestAnimationFrame(movePlayer);
}
document.addEventListener("keydown",e=>{
const k=e.key.toLowerCase();
if(["arrowup","w"].includes(k))state.keys.up=true;
if(["arrowdown","s"].includes(k))state.keys.down=true;
if(["arrowleft","a"].includes(k))state.keys.left=true;
if(["arrowright","d"].includes(k))state.keys.right=true;
});
document.addEventListener("keyup",e=>{
const k=e.key.toLowerCase();
if(["arrowup","w"].includes(k))state.keys.up=false;
if(["arrowdown","s"].includes(k))state.keys.down=false;
if(["arrowleft","a"].includes(k))state.keys.left=false;
if(["arrowright","d"].includes(k))state.keys.right=false;
});
document.querySelectorAll("[data-key]").forEach(btn=>{
const k=btn.dataset.key;
btn.addEventListener("pointerdown",e=>{e.preventDefault();state.keys[k]=true;});
["pointerup","pointerleave","pointercancel"].forEach(ev=>
btn.addEventListener(ev,()=>state.keys[k]=false));
});
// =====================================
// ENCUENTROS
// =====================================
function encounter(){
if(state.mode!=="world"||Date.now()-state.lastEncounter<2500)return;
state.lastEncounter=Date.now();
const p=wildSpecies[Math.floor(Math.random()*wildSpecies.length)];
startBattle(p);
}
function startBattle(species){
state.enemy={...species,maxHp:species.hp,energy:100,x:650,y:160};
state.mode="battle";
state.battleFrame=0;
screen("battleScreen");
$("battleMessage").textContent="¡Un "+species.name+" salvaje apareció!";
refreshBattle();
battleLoop();
}
function refreshBattle(){
const me=state.team[0],foe=state.enemy;
if(!me||!foe)return;
$("myName").textContent=me.emoji+" "+me.name+" Nv."+me.level;
$("foeName").textContent=foe.emoji+" "+foe.name;
$("myHP").textContent=me.hp+" / "+me.maxHp+" PS";
$("foeHP").textContent=foe.hp+" / "+foe.maxHp+" PS";
$("myBar").style.width=Math.max(0,me.hp/me.maxHp*100)+"%";
$("foeBar").style.width=Math.max(0,foe.hp/foe.maxHp*100)+"%";
}
// =====================================
// COMBATE EN TIEMPO REAL
// =====================================
function battleLoop(){
if(state.mode!=="battle")return;
const me=state.team[0],foe=state.enemy;
state.battleFrame++;
bc.clearRect(0,0,800,330);
bc.fillStyle="#365b43";bc.fillRect(0,0,800,330);
bc.fillStyle="#6b9d5b";
bc.beginPath();bc.ellipse(170,260,120,35,0,0,Math.PI*2);bc.fill();
bc.beginPath();bc.ellipse(620,100,120,35,0,0,Math.PI*2);bc.fill();
// Pokémon
bc.font="64px Arial";
bc.fillText(me.emoji,me.x||170,me.y||250);
bc.fillText(foe.emoji,foe.x,foe.y);
// Movimiento automático enemigo
if(state.battleFrame%3===0){
const dx=(me.x||170)-foe.x,dy=(me.y||250)-foe.y;
const d=Math.hypot(dx,dy)||1;
foe.x+=dx/d*1.1;foe.y+=dy/d*1.1;
if(d<70&&state.battleFrame%45===0){
me.hp=Math.max(0,me.hp-4);
$("battleMessage").textContent=foe.name+" atacó.";
refreshBattle();
if(me.hp<=0){finishBattle(false);return;}
}
}
if(state.keys.up)me.y=(me.y||250)-3;
if(state.keys.down)me.y=(me.y||250)+3;
if(state.keys.left)me.x=(me.x||170)-3;
if(state.keys.right)me.x=(me.x||170)+3;
me.x=Math.max(40,Math.min(760,me.x||170));
me.y=Math.max(60,Math.min(290,me.y||250));
if(state.battleFrame%2===0)refreshBattle();
requestAnimationFrame(battleLoop);
}
function useMove(i){
if(state.mode!=="battle")return;
const me=state.team[0],foe=state.enemy;
if(me.energy<10){$("battleMessage").textContent="No tienes energía suficiente.";return;}
me.energy-=10;
const damage=8+i*4+Math.floor(Math.random()*5);
foe.hp=Math.max(0,foe.hp-damage);
$("battleMessage").textContent=me.name+" usó "+me.moves[i]+" e hizo "+damage+" de daño.";
refreshBattle();
if(foe.hp<=0){finishBattle(true);return;}
}
function throwBall(){
if(state.mode!=="battle")return;
if(state.balls<=0){$("battleMessage").textContent="No quedan Poké Balls.";return;}
state.balls--;
const foe=state.enemy;
const chance=0.3+(1-foe.hp/foe.maxHp)*0.55;
if(Math.random()<chance){
$("battleMessage").textContent="¡Capturaste a "+foe.name+"!";
if(!state.dex.includes(foe.name))state.dex.push(foe.name);
if(state.team.length<6){
state.team.push({...foe,hp:foe.maxHp,level:3,moves:["Placaje","Ataque veloz","Defensa","Poder especial"]});
}
finishBattle(false);
}else{
$("battleMessage").textContent="¡El Pokémon escapó de la Poké Ball!";
refreshBattle();
}
}
function flee(){
if(Math.random()<0.8)finishBattle(false);
else $("battleMessage").textContent="¡No pudiste escapar!";
}
function finishBattle(victory){
state.mode="world";
screen("gameScreen");
if(victory&&state.team[0])state.team[0].level++;
refreshHUD();
drawWorld();
}
// =====================================
// MENÚS DEL JUEGO
// =====================================
function interact(){
if(state.mode!=="world")return;
alert("Explora Aukan y busca personajes y lugares especiales.");
}
function showDex(){
$("infoContent").innerHTML="<h2>📖 Pokédex Aukan</h2>"+
"<p>Pokémon descubiertos: "+state.dex.length+"</p>"+
state.dex.map(n=>"<div class='card'>"+n+"</div>").join("")+
"<p>Los registros se ampliarán con nuevas especies.</p>";
screen("info");
}
function showTeam(){
$("infoContent").innerHTML="<h2>Tu equipo Pokémon</h2>"+
state.team.map(p=>"<div class='card'>"+p.emoji+" "+p.name+
" — "+p.type+" — Nivel "+p.level+"</div>").join("");
screen("info");
}
function showMap(){
$("infoContent").innerHTML="<h2>Mapa de Aukan</h2>"+
REGIONS.map((r,i)=>"<div class='card'>"+(i+1)+". "+r+
(i===state.region?" — Estás aquí":"")+"</div>").join("")+
"<p>La conexión y los mapas de cada región se desarrollarán por etapas.</p>";
screen("info");
}
function closeInfo(){
screen("gameScreen");
drawWorld();
}
// =====================================
// INICIO
// =====================================
document.getElementById("battleScreen").addEventListener("click",e=>{
if(e.target.id==="battleCanvas")return;
});
</script>
</body>
</html>
Game Source: Pokémon Chile: Región Aukan
Creator: AstroHero57
Libraries: none
Complexity: complex (499 lines, 14.9 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: pok-mon-chile-regi-n-aukan-astrohero57" to link back to the original. Then publish at arcadelab.ai/publish.