Meta Description" name="description" />
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>EvoMon - Biomes & Housing</title>
<style>
body { margin: 0; background: #1a1a1a; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; }
#game-container { border: 6px solid #444; border-radius: 4px; box-shadow: 0 0 50px rgba(0,0,0,0.8); }
canvas { display: block; image-rendering: pixelated; }
</style>
</head>
<body>
<div id="game-container">
<canvas id="gameCanvas" width="640" height="480"></canvas>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const TILE = 32;
// PALETAS POR BIOMA
const COLORS = {
// Bioma 0: Pradera (Agua/Planta)
grass: ['#88D070', '#58B050', '#387838'],
water: ['#4090FF', '#3060E0', '#70C0FF'],
// Bioma 1: Eléctrico (Industrial)
tech: ['#A0A0B8', '#707090', '#404060', '#F8E868'],
// Bioma 2: Fuego (Volcánico)
fire: ['#605050', '#403030', '#F85830', '#F8B830'],
// Estructuras y Jugador
house: { roof: '#D84030', wall: '#F8F8D8', door: '#704030', window: '#70C0F8' },
player: { red: '#E03020', skin: '#F8C0A0', blue: '#406090' }
};
// TIPOS DE TILES
// 0: Hierba, 1: Camino, 2: Árbol, 3: Hierba Alta, 4: Agua, 5: Metal, 6: Lava, 7: Muro Casa, 8: Tejado, 9: Puerta
const map = [
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
[2,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5],
[2,0,8,8,8,0,3,3,0,0,5,5,5,5,11,5,5,5,5,5], // Casa y entrada a zona eléctrica
[2,0,7,9,7,0,3,3,0,0,5,5,3,3,3,3,5,5,5,5],
[2,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,2],
[4,4,4,4,4,0,1,0,0,0,0,0,0,0,1,0,6,6,6,6], // Paso entre agua y lava
[4,4,4,4,4,0,1,0,0,0,0,0,0,0,1,0,6,6,6,6],
[2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,2],
[2,3,3,3,0,0,1,0,0,3,3,3,0,0,1,0,3,3,3,2],
[2,3,3,3,0,0,1,1,1,3,3,3,0,0,1,0,3,3,3,2],
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]
];
function drawTile(x, y, type) {
ctx.save();
ctx.translate(x, y);
switch(type) {
case 0: // CÉSPED MEJORADO
ctx.fillStyle = COLORS.grass[0]; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = COLORS.grass[1];
for(let i=0; i<4; i++) ctx.fillRect(Math.random()*TILE, Math.random()*TILE, 2, 2);
break;
case 1: // CAMINO
ctx.fillStyle = '#E8D080'; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = '#D0B870'; ctx.fillRect(0, 0, TILE, 2);
break;
case 2: // ÁRBOL (Planta)
ctx.fillStyle = COLORS.grass[0]; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = '#503820'; ctx.fillRect(12, 20, 8, 12);
ctx.fillStyle = '#387838'; ctx.beginPath(); ctx.arc(16, 12, 12, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#58B050'; ctx.beginPath(); ctx.arc(12, 10, 8, 0, Math.PI*2); ctx.fill();
break;
case 3: // HIERBA ALTA
ctx.fillStyle = COLORS.grass[0]; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = COLORS.grass[2];
for(let i=0; i<3; i++) {
ctx.fillRect(4 + i*8, 10, 4, 15);
ctx.fillStyle = COLORS.grass[1]; ctx.fillRect(4 + i*8, 8, 4, 2);
ctx.fillStyle = COLORS.grass[2];
}
break;
case 4: // AGUA (Animada con Date.now)
let offset = Math.sin(Date.now()/500)*2;
ctx.fillStyle = COLORS.water[1]; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = COLORS.water[0]; ctx.fillRect(4+offset, 8, 20, 2);
ctx.fillRect(8-offset, 20, 15, 2);
break;
case 5: // METAL (Eléctrico)
ctx.fillStyle = COLORS.tech[1]; ctx.fillRect(0,0,TILE,TILE);
ctx.strokeStyle = COLORS.tech[0]; ctx.strokeRect(2,2,TILE-4,TILE-4);
ctx.fillStyle = COLORS.tech[3]; if(Math.random()>0.98) ctx.fillRect(12,12,8,8); // Chispa
break;
case 6: // LAVA (Fuego)
let pulse = Math.abs(Math.sin(Date.now()/1000));
ctx.fillStyle = COLORS.fire[2]; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = COLORS.fire[3]; ctx.globalAlpha = pulse;
ctx.fillRect(4, 4, TILE-8, TILE-8);
break;
case 7: // PARED CASA
ctx.fillStyle = COLORS.house.wall; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = '#D0D0B0'; ctx.fillRect(0, TILE-4, TILE, 4);
break;
case 8: // TEJADO CASA
ctx.fillStyle = COLORS.house.roof; ctx.fillRect(0,4,TILE,TILE);
ctx.fillStyle = '#A03020'; ctx.fillRect(0, TILE-2, TILE, 4);
break;
case 9: // PUERTA
ctx.fillStyle = COLORS.house.wall; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = COLORS.house.door; ctx.fillRect(6,4,20,28);
ctx.fillStyle = '#F8E868'; ctx.fillRect(20, 18, 4, 4); // Pomo
break;
case 11: // GENERADOR (Rasgo Eléctrico)
ctx.fillStyle = COLORS.tech[2]; ctx.fillRect(0,0,TILE,TILE);
ctx.fillStyle = COLORS.tech[3]; ctx.fillRect(8, 8, 16, 16);
break;
}
ctx.restore();
}
let player = { gx: 2, gy: 4, x: 2*TILE, y: 4*TILE, dir: 'down' };
function drawPlayer() {
ctx.save();
ctx.translate(player.x, player.y);
// Sombra
ctx.fillStyle = "rgba(0,0,0,0.2)";
ctx.beginPath(); ctx.ellipse(16, 28, 10, 5, 0, 0, Math.PI*2); ctx.fill();
// Cuerpo
ctx.fillStyle = COLORS.player.red; ctx.fillRect(8, 12, 16, 12);
ctx.fillStyle = COLORS.player.blue; ctx.fillRect(8, 24, 16, 6);
// Cabeza
ctx.fillStyle = COLORS.player.skin; ctx.fillRect(10, 4, 12, 10);
ctx.fillStyle = COLORS.player.red; ctx.fillRect(8, 2, 16, 5); // Gorra
ctx.restore();
}
function update() {
player.x += (player.gx * TILE - player.x) * 0.2;
player.y += (player.gy * TILE - player.y) * 0.2;
}
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(let r=0; r<map.length; r++) {
for(let c=0; c<map[r].length; c++) {
drawTile(c*TILE, r*TILE, map[r][c]);
}
}
drawPlayer();
update();
requestAnimationFrame(render);
}
window.addEventListener('keydown', e => {
let nx = player.gx, ny = player.gy;
if(e.key === 'ArrowUp') ny--;
if(e.key === 'ArrowDown') ny++;
if(e.key === 'ArrowLeft') nx--;
if(e.key === 'ArrowRight') nx++;
// Colisiones: No pasar por árboles(2), tejados(8), agua(4), lava(6) o muros(7)
const col = [2, 4, 6, 7, 8];
if(map[ny] && map[ny][nx] !== undefined && !col.includes(map[ny][nx])) {
player.gx = nx;
player.gy = ny;
}
});
render();
</script>
</body>
</html>
1
1
7KB
7KB
145.0ms
196.0ms
145.0ms