User prompt
el sprite del slime sigue pegandose mucho al del player y se sobre posisiona sobre el la idea es que este un poco mas separado para que le haga daño y ese daño no sea continuo sino que hace dalo el enemigo en ticks de un segundo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ahora que los enemigos no se puedan atravezar ni estre ellos ni atravezar al player y solo con estar junto al player le van haciendo un 5% de daño
User prompt
muy bien pero ahora hay que darle mas velociad de movimiento
User prompt
muy bien ahora sabemos que el player se mueve de a media casilla pero cuando se mueve de forma constante se nota como no es fluido el movimiento asi que para hacerlo mas fluido podemos hacer que se mueva de a un quinto de casilla un 0.20
User prompt
ahora vamos a mejorar un poco la logca de los botones de las flechas y es que quiero que el personaje siga avanzando si el boton continua oprimido
User prompt
viendolo bien necesitamos otro asset para el player que sera el de mirar para abajo el cual va separado de el de mirar arriba y el delos lados como esta esta bien ya que es un mirrow pero arriba y abajo si distintos assets
User prompt
no asi no solo deja como el espacio para un sedundo asset del player y yo en ese aset pongo la imagen
User prompt
bien ya mira hacia los lados ahora falta arriba y abajo lo cual me imagino que tengo que yo poner la imagen pero tu agrega la logica para que yo al poner las imagenes el mire arriba y abajo
User prompt
ahora hay que mejorar un poco el personaje y es hacer que su sprite mire hacia el lado donde esta mirando o caminando asi tendra mas dinamismo
User prompt
muy bien soo un pequeño detalle los muros que no se generen entre celdas 1x1 sino que siempre esten dentro de un 1x1 relacionado al suelo
User prompt
muy bien soo un pequeño detalle los minerales y rocas que no se generen entre celdas 1x1 sino que siempre esten dentro de un 1x1 relacionado al suelo
User prompt
muy bien ahora mas mejoras visuales y es que como sabemos el mapa se compone de cuadriculas asi que quiero que todo ocupe 1x1 minerales personaje enemigos suelo y muros de manera visual ya que como estan las imagenes en los assets solo es ajustarlas
User prompt
todo muy bien ahora unos detalles en los botones ya que como le agrege imagenes a esos assets quiero que quites como esas flechas pico y espada blanquitos que estan encima de los botones y no dejan ver bien la imagen del boton
User prompt
necesitamos añadir textura en el suelo para poder ver mas claramente la cuadricula del mapa en general adeemas que el personaje asi como los enemigos que si lo hacen se pueda mover en un 1x1 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
perfecto ahora cambiemos un poco el aspecto de los minerales y rocas ya que deberian ocupar visualmente una casilla 1x1 cada una pero al minarlos reducen su tamaño visual a la mitad y se vuelve recolectable ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
muy bien y ahora en la parte derecha un boton de un pico y otro de espada el del pico al estar junto a un mineral o roca lo picara y el de espeda al estar unto a un enemigo le hara daño asi que los slimes deben ser derrotados con 3 golpes y dropear un item que sea slime
User prompt
en la parte inferior izquierda agregar una especie de botones que seran una flechas una hacia arriba otra hacia abajo una a la derecha y la otra a la izquierda y el personaje se movera en la direccion acorde cuando el player presione sobre una de esas flechas
User prompt
bien ahora un par de cambios los enemigos pueden pasar por pasillos de 1x1 pero el personaje no asi que eso tambien lo deberia hacer el personaje pasar por 1x1 ademas que con el click izquierdo si el personaje esta unto a un mineral o roca pueda minar dicho objeto
User prompt
has mas realista el sistema del mapa de las minas y que los enemicos no puedan atravezar las rocas ni minerales
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'addEventListener')' in or related to this line: 'document.addEventListener('keydown', handleKeyDown);' Line Number: 547
User prompt
nesesito hacer que el personaje lo pueda mover con awsd y al estar ensima de un objeto o enemigo interactue con el con la barra de espacio
User prompt
La lógica de los caminos es forma un camino único con tal vez varía difulcaciones no es crear salar ramdom en el mapa la idea es que se sienta como una mina de verdad
User prompt
Los muros deben formar el límite de cada piso formando caminos con lógica en los cuales el jugador se pueda desplazar y encontrar los minerales rojas y enemigos
User prompt
La roca también debe ser recolectable
User prompt
Porque todo tiene el mismo Sprite de las rocas al generar en cada piso de forma aletoria así mismo se deben generar los materiales con distintas áreas en probabilidades y los más raros aparecen con más frecuencia en pisos más altos
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var HealthItem = Container.expand(function () { var self = Container.call(this); var heartGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.healAmount = 25; self.collect = function () { if (self.collected) return; self.collected = true; LK.getSound('collect').play(); player.heal(self.healAmount); // Remove from healthItems array for (var i = healthItems.length - 1; i >= 0; i--) { if (healthItems[i] === self) { healthItems.splice(i, 1); break; } } game.removeChild(self); }; return self; }); var Ladder = Container.expand(function () { var self = Container.call(this); var ladderGraphics = self.attachAsset('ladder', { anchorX: 0.5, anchorY: 0.5 }); self.used = false; self.use = function () { if (self.used) return; self.used = true; currentFloor++; generateFloor(); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 100; self.health = self.maxHealth; self.speed = 3; self.attackRange = 80; self.attackDamage = 25; self.lastAttackTime = 0; self.attackCooldown = 500; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.effects.flashObject(self, 0xFF0000, 300); LK.getSound('hurt').play(); }; self.heal = function (amount) { self.health = Math.min(self.maxHealth, self.health + amount); }; self.canAttack = function () { return LK.ticks - self.lastAttackTime > self.attackCooldown; }; self.canMoveTo = function (x, y) { return !checkCollisionWithWalls(x, y, 32); }; self.attack = function () { if (!self.canAttack()) return; self.lastAttackTime = LK.ticks; LK.getSound('attack').play(); // Check for slimes in attack range with line of sight for (var i = 0; i < slimes.length; i++) { var slime = slimes[i]; var dx = slime.x - self.x; var dy = slime.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.attackRange && hasLineOfSight(self.x, self.y, slime.x, slime.y)) { slime.takeDamage(self.attackDamage); } } // Check for rocks in attack range with line of sight for (var i = 0; i < rocks.length; i++) { var rock = rocks[i]; var dx = rock.x - self.x; var dy = rock.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.attackRange && hasLineOfSight(self.x, self.y, rock.x, rock.y)) { rock.hit(); } } }; return self; }); var Resource = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.collected = false; var resourceGraphics = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); self.collect = function () { if (self.collected) return; self.collected = true; LK.getSound('collect').play(); // Update inventory if (!inventory[self.type]) { inventory[self.type] = 0; } inventory[self.type]++; // Remove from resources array for (var i = resources.length - 1; i >= 0; i--) { if (resources[i] === self) { resources.splice(i, 1); break; } } game.removeChild(self); }; return self; }); var Rock = Container.expand(function (rockType) { var self = Container.call(this); self.rockType = rockType || 'rock'; var rockGraphics = self.attachAsset(self.rockType, { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 3; self.health = self.maxHealth; self.destroyed = false; self.hit = function () { if (self.destroyed) return; self.health--; LK.getSound('mine_hit').play(); LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.destroy(); } }; self.destroy = function () { if (self.destroyed) return; self.destroyed = true; // Drop resources based on rock type var resource; if (self.rockType === 'coal') { resource = new Resource('coal'); } else if (self.rockType === 'copper_ore') { resource = new Resource('copper_ore'); } else if (self.rockType === 'iron_ore') { resource = new Resource('iron_ore'); } else if (self.rockType === 'gold_ore') { resource = new Resource('gold_ore'); } else if (self.rockType === 'gem') { resource = new Resource('gem'); } else { // Regular rock has chance to drop random resource var dropChance = Math.random(); if (dropChance < 0.3) { var resourceType = Math.random(); if (resourceType < 0.5) { resource = new Resource('coal'); } else { resource = new Resource('copper_ore'); } } } if (resource) { resource.x = self.x; resource.y = self.y; resources.push(resource); game.addChild(resource); } // Chance to spawn ladder if it doesn't exist yet if (!ladder && Math.random() < 0.15) { ladder = new Ladder(); ladder.x = self.x; ladder.y = self.y; game.addChild(ladder); } // Remove from rocks array for (var i = rocks.length - 1; i >= 0; i--) { if (rocks[i] === self) { rocks.splice(i, 1); break; } } game.removeChild(self); }; return self; }); var Slime = Container.expand(function () { var self = Container.call(this); var slimeGraphics = self.attachAsset('slime', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 50; self.health = self.maxHealth; self.speed = 1; self.attackDamage = 15; self.lastAttackTime = 0; self.attackCooldown = 1000; self.attackRange = 50; self.destroyed = false; self.takeDamage = function (damage) { if (self.destroyed) return; self.health -= damage; LK.effects.flashObject(self, 0xFF0000, 200); if (self.health <= 0) { self.destroy(); } }; self.destroy = function () { if (self.destroyed) return; self.destroyed = true; // Drop heart sometimes if (Math.random() < 0.3) { var heart = new HealthItem(); heart.x = self.x; heart.y = self.y; healthItems.push(heart); game.addChild(heart); } // Remove from slimes array for (var i = slimes.length - 1; i >= 0; i--) { if (slimes[i] === self) { slimes.splice(i, 1); break; } } // Increase score LK.setScore(LK.getScore() + 10); game.removeChild(self); }; self.update = function () { if (self.destroyed) return; // Check if player is visible (line of sight) var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (hasLineOfSight(self.x, self.y, player.x, player.y) && distance < 300) { // Move towards player if visible and within detection range if (distance > 0) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; var newX = self.x + moveX; var newY = self.y + moveY; // Check collision before moving if (!checkCollisionWithWalls(newX, newY, 20)) { self.x = newX; self.y = newY; } } // Attack player if in range and visible if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackCooldown) { self.lastAttackTime = LK.ticks; player.takeDamage(self.attackDamage); } } }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F1B14 }); /**** * Game Code ****/ var player; var rocks = []; var slimes = []; var resources = []; var healthItems = []; var ladder; var inventory = {}; var currentFloor = 1; var walls = []; function checkCollisionWithWalls(x, y, radius) { for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var dx = Math.abs(x - wall.x); var dy = Math.abs(y - wall.y); if (dx < 32 + radius && dy < 32 + radius) { return true; } } return false; } function hasLineOfSight(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; var distance = Math.sqrt(dx * dx + dy * dy); var steps = Math.floor(distance / 16); for (var i = 0; i <= steps; i++) { var checkX = x1 + dx * i / steps; var checkY = y1 + dy * i / steps; if (checkCollisionWithWalls(checkX, checkY, 8)) { return false; } } return true; } // UI Elements var healthBar; var floorText; var inventoryText; function initializeGame() { player = game.addChild(new Player()); player.x = 1024; player.y = 1366; // Create UI healthBar = new Text2('Health: 100/100', { size: 40, fill: 0xFF0000 }); healthBar.anchor.set(0, 0); LK.gui.topLeft.addChild(healthBar); healthBar.x = 120; healthBar.y = 20; floorText = new Text2('Floor: 1', { size: 40, fill: 0xFFFFFF }); floorText.anchor.set(0.5, 0); LK.gui.top.addChild(floorText); floorText.y = 20; inventoryText = new Text2('', { size: 30, fill: 0xFFFF00 }); inventoryText.anchor.set(1, 0); LK.gui.topRight.addChild(inventoryText); inventoryText.x = -20; inventoryText.y = 20; generateFloor(); } function generateFloor() { // Clear existing objects clearFloor(); // Generate perimeter walls for (var x = 0; x < 2048; x += 64) { var topWall = new Wall(); topWall.x = x + 32; topWall.y = 132; walls.push(topWall); game.addChild(topWall); var bottomWall = new Wall(); bottomWall.x = x + 32; bottomWall.y = 2700; walls.push(bottomWall); game.addChild(bottomWall); } for (var y = 132; y < 2700; y += 64) { var leftWall = new Wall(); leftWall.x = 32; leftWall.y = y + 32; walls.push(leftWall); game.addChild(leftWall); var rightWall = new Wall(); rightWall.x = 2016; rightWall.y = y + 32; walls.push(rightWall); game.addChild(rightWall); } // Generate interior walls var numWalls = 8 + Math.floor(currentFloor * 2); for (var i = 0; i < numWalls; i++) { var wall = new Wall(); wall.x = 200 + Math.random() * 1648; wall.y = 300 + Math.random() * 2132; walls.push(wall); game.addChild(wall); } // Generate rocks with different types based on floor var numRocks = 15 + Math.floor(currentFloor * 2); for (var i = 0; i < numRocks; i++) { var rockType = 'rock'; // Default rock type var rand = Math.random(); // Higher floors have better chances for rare materials var floorMultiplier = Math.min(currentFloor / 10, 1); // Cap at floor 10 if (rand < 0.3) { rockType = 'coal'; // Common on all floors } else if (rand < 0.3 + 0.2 * floorMultiplier) { rockType = 'copper_ore'; // More common on higher floors } else if (rand < 0.3 + 0.2 * floorMultiplier + 0.15 * floorMultiplier) { rockType = 'iron_ore'; // Rare, more common on higher floors } else if (rand < 0.3 + 0.2 * floorMultiplier + 0.15 * floorMultiplier + 0.1 * floorMultiplier) { rockType = 'gold_ore'; // Very rare, much more common on higher floors } else if (rand < 0.3 + 0.2 * floorMultiplier + 0.15 * floorMultiplier + 0.1 * floorMultiplier + 0.05 * floorMultiplier) { rockType = 'gem'; // Extremely rare, only on higher floors } var rock = new Rock(rockType); do { rock.x = 200 + Math.random() * 1648; rock.y = 300 + Math.random() * 2132; } while (checkCollisionWithWalls(rock.x, rock.y, 32)); rocks.push(rock); game.addChild(rock); } // Generate slimes var numSlimes = 3 + Math.floor(currentFloor * 1.5); for (var i = 0; i < numSlimes; i++) { var slime = new Slime(); do { slime.x = 200 + Math.random() * 1648; slime.y = 300 + Math.random() * 2132; } while (checkCollisionWithWalls(slime.x, slime.y, 32)); slime.maxHealth += Math.floor(currentFloor * 10); slime.health = slime.maxHealth; slimes.push(slime); game.addChild(slime); } // Ladder will be generated when mining rocks ladder = null; // Update floor text floorText.setText('Floor: ' + currentFloor); } function clearFloor() { // Remove all walls for (var i = 0; i < walls.length; i++) { game.removeChild(walls[i]); } walls = []; // Remove all rocks for (var i = 0; i < rocks.length; i++) { game.removeChild(rocks[i]); } rocks = []; // Remove all slimes for (var i = 0; i < slimes.length; i++) { game.removeChild(slimes[i]); } slimes = []; // Remove all resources for (var i = 0; i < resources.length; i++) { game.removeChild(resources[i]); } resources = []; // Remove all health items for (var i = 0; i < healthItems.length; i++) { game.removeChild(healthItems[i]); } healthItems = []; // Remove ladder if (ladder) { game.removeChild(ladder); ladder = null; } } function updateUI() { // Update health bar healthBar.setText('Health: ' + player.health + '/' + player.maxHealth); // Update inventory display var inventoryStr = ''; for (var item in inventory) { if (inventory[item] > 0) { inventoryStr += item.replace('_', ' ') + ': ' + inventory[item] + '\n'; } } inventoryText.setText(inventoryStr); } var dragNode = null; function handleMove(x, y, obj) { if (dragNode) { var newX = x; var newY = y; // Keep player within bounds newX = Math.max(64, Math.min(1984, newX)); newY = Math.max(164, Math.min(2668, newY)); // Check collision with walls if (!checkCollisionWithWalls(newX, newY, 32)) { dragNode.x = newX; dragNode.y = newY; } } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = player; handleMove(x, y, obj); // Attack on tap player.attack(); }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { if (!player) return; // Update slimes for (var i = 0; i < slimes.length; i++) { slimes[i].update(); } // Check automatic mining when player is on top of rocks for (var i = rocks.length - 1; i >= 0; i--) { var rock = rocks[i]; var dx = rock.x - player.x; var dy = rock.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 30) { // Player is standing on/very close to rock rock.hit(); } } // Check resource collection for (var i = resources.length - 1; i >= 0; i--) { var resource = resources[i]; var dx = resource.x - player.x; var dy = resource.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { resource.collect(); } } // Check health item collection for (var i = healthItems.length - 1; i >= 0; i--) { var healthItem = healthItems[i]; var dx = healthItem.x - player.x; var dy = healthItem.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { healthItem.collect(); } } // Check ladder interaction if (ladder && !ladder.used) { var dx = ladder.x - player.x; var dy = ladder.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 50) { ladder.use(); } } // Update UI updateUI(); }; // Initialize the game initializeGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var HealthItem = Container.expand(function () {
var self = Container.call(this);
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.healAmount = 25;
self.collect = function () {
if (self.collected) return;
self.collected = true;
LK.getSound('collect').play();
player.heal(self.healAmount);
// Remove from healthItems array
for (var i = healthItems.length - 1; i >= 0; i--) {
if (healthItems[i] === self) {
healthItems.splice(i, 1);
break;
}
}
game.removeChild(self);
};
return self;
});
var Ladder = Container.expand(function () {
var self = Container.call(this);
var ladderGraphics = self.attachAsset('ladder', {
anchorX: 0.5,
anchorY: 0.5
});
self.used = false;
self.use = function () {
if (self.used) return;
self.used = true;
currentFloor++;
generateFloor();
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 100;
self.health = self.maxHealth;
self.speed = 3;
self.attackRange = 80;
self.attackDamage = 25;
self.lastAttackTime = 0;
self.attackCooldown = 500;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
LK.effects.flashObject(self, 0xFF0000, 300);
LK.getSound('hurt').play();
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
self.canAttack = function () {
return LK.ticks - self.lastAttackTime > self.attackCooldown;
};
self.canMoveTo = function (x, y) {
return !checkCollisionWithWalls(x, y, 32);
};
self.attack = function () {
if (!self.canAttack()) return;
self.lastAttackTime = LK.ticks;
LK.getSound('attack').play();
// Check for slimes in attack range with line of sight
for (var i = 0; i < slimes.length; i++) {
var slime = slimes[i];
var dx = slime.x - self.x;
var dy = slime.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.attackRange && hasLineOfSight(self.x, self.y, slime.x, slime.y)) {
slime.takeDamage(self.attackDamage);
}
}
// Check for rocks in attack range with line of sight
for (var i = 0; i < rocks.length; i++) {
var rock = rocks[i];
var dx = rock.x - self.x;
var dy = rock.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.attackRange && hasLineOfSight(self.x, self.y, rock.x, rock.y)) {
rock.hit();
}
}
};
return self;
});
var Resource = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.collected = false;
var resourceGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.collect = function () {
if (self.collected) return;
self.collected = true;
LK.getSound('collect').play();
// Update inventory
if (!inventory[self.type]) {
inventory[self.type] = 0;
}
inventory[self.type]++;
// Remove from resources array
for (var i = resources.length - 1; i >= 0; i--) {
if (resources[i] === self) {
resources.splice(i, 1);
break;
}
}
game.removeChild(self);
};
return self;
});
var Rock = Container.expand(function (rockType) {
var self = Container.call(this);
self.rockType = rockType || 'rock';
var rockGraphics = self.attachAsset(self.rockType, {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 3;
self.health = self.maxHealth;
self.destroyed = false;
self.hit = function () {
if (self.destroyed) return;
self.health--;
LK.getSound('mine_hit').play();
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
self.destroy();
}
};
self.destroy = function () {
if (self.destroyed) return;
self.destroyed = true;
// Drop resources based on rock type
var resource;
if (self.rockType === 'coal') {
resource = new Resource('coal');
} else if (self.rockType === 'copper_ore') {
resource = new Resource('copper_ore');
} else if (self.rockType === 'iron_ore') {
resource = new Resource('iron_ore');
} else if (self.rockType === 'gold_ore') {
resource = new Resource('gold_ore');
} else if (self.rockType === 'gem') {
resource = new Resource('gem');
} else {
// Regular rock has chance to drop random resource
var dropChance = Math.random();
if (dropChance < 0.3) {
var resourceType = Math.random();
if (resourceType < 0.5) {
resource = new Resource('coal');
} else {
resource = new Resource('copper_ore');
}
}
}
if (resource) {
resource.x = self.x;
resource.y = self.y;
resources.push(resource);
game.addChild(resource);
}
// Chance to spawn ladder if it doesn't exist yet
if (!ladder && Math.random() < 0.15) {
ladder = new Ladder();
ladder.x = self.x;
ladder.y = self.y;
game.addChild(ladder);
}
// Remove from rocks array
for (var i = rocks.length - 1; i >= 0; i--) {
if (rocks[i] === self) {
rocks.splice(i, 1);
break;
}
}
game.removeChild(self);
};
return self;
});
var Slime = Container.expand(function () {
var self = Container.call(this);
var slimeGraphics = self.attachAsset('slime', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = self.maxHealth;
self.speed = 1;
self.attackDamage = 15;
self.lastAttackTime = 0;
self.attackCooldown = 1000;
self.attackRange = 50;
self.destroyed = false;
self.takeDamage = function (damage) {
if (self.destroyed) return;
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.destroy();
}
};
self.destroy = function () {
if (self.destroyed) return;
self.destroyed = true;
// Drop heart sometimes
if (Math.random() < 0.3) {
var heart = new HealthItem();
heart.x = self.x;
heart.y = self.y;
healthItems.push(heart);
game.addChild(heart);
}
// Remove from slimes array
for (var i = slimes.length - 1; i >= 0; i--) {
if (slimes[i] === self) {
slimes.splice(i, 1);
break;
}
}
// Increase score
LK.setScore(LK.getScore() + 10);
game.removeChild(self);
};
self.update = function () {
if (self.destroyed) return;
// Check if player is visible (line of sight)
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (hasLineOfSight(self.x, self.y, player.x, player.y) && distance < 300) {
// Move towards player if visible and within detection range
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
var newX = self.x + moveX;
var newY = self.y + moveY;
// Check collision before moving
if (!checkCollisionWithWalls(newX, newY, 20)) {
self.x = newX;
self.y = newY;
}
}
// Attack player if in range and visible
if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackCooldown) {
self.lastAttackTime = LK.ticks;
player.takeDamage(self.attackDamage);
}
}
};
return self;
});
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F1B14
});
/****
* Game Code
****/
var player;
var rocks = [];
var slimes = [];
var resources = [];
var healthItems = [];
var ladder;
var inventory = {};
var currentFloor = 1;
var walls = [];
function checkCollisionWithWalls(x, y, radius) {
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
var dx = Math.abs(x - wall.x);
var dy = Math.abs(y - wall.y);
if (dx < 32 + radius && dy < 32 + radius) {
return true;
}
}
return false;
}
function hasLineOfSight(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
var distance = Math.sqrt(dx * dx + dy * dy);
var steps = Math.floor(distance / 16);
for (var i = 0; i <= steps; i++) {
var checkX = x1 + dx * i / steps;
var checkY = y1 + dy * i / steps;
if (checkCollisionWithWalls(checkX, checkY, 8)) {
return false;
}
}
return true;
}
// UI Elements
var healthBar;
var floorText;
var inventoryText;
function initializeGame() {
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Create UI
healthBar = new Text2('Health: 100/100', {
size: 40,
fill: 0xFF0000
});
healthBar.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthBar);
healthBar.x = 120;
healthBar.y = 20;
floorText = new Text2('Floor: 1', {
size: 40,
fill: 0xFFFFFF
});
floorText.anchor.set(0.5, 0);
LK.gui.top.addChild(floorText);
floorText.y = 20;
inventoryText = new Text2('', {
size: 30,
fill: 0xFFFF00
});
inventoryText.anchor.set(1, 0);
LK.gui.topRight.addChild(inventoryText);
inventoryText.x = -20;
inventoryText.y = 20;
generateFloor();
}
function generateFloor() {
// Clear existing objects
clearFloor();
// Generate perimeter walls
for (var x = 0; x < 2048; x += 64) {
var topWall = new Wall();
topWall.x = x + 32;
topWall.y = 132;
walls.push(topWall);
game.addChild(topWall);
var bottomWall = new Wall();
bottomWall.x = x + 32;
bottomWall.y = 2700;
walls.push(bottomWall);
game.addChild(bottomWall);
}
for (var y = 132; y < 2700; y += 64) {
var leftWall = new Wall();
leftWall.x = 32;
leftWall.y = y + 32;
walls.push(leftWall);
game.addChild(leftWall);
var rightWall = new Wall();
rightWall.x = 2016;
rightWall.y = y + 32;
walls.push(rightWall);
game.addChild(rightWall);
}
// Generate interior walls
var numWalls = 8 + Math.floor(currentFloor * 2);
for (var i = 0; i < numWalls; i++) {
var wall = new Wall();
wall.x = 200 + Math.random() * 1648;
wall.y = 300 + Math.random() * 2132;
walls.push(wall);
game.addChild(wall);
}
// Generate rocks with different types based on floor
var numRocks = 15 + Math.floor(currentFloor * 2);
for (var i = 0; i < numRocks; i++) {
var rockType = 'rock'; // Default rock type
var rand = Math.random();
// Higher floors have better chances for rare materials
var floorMultiplier = Math.min(currentFloor / 10, 1); // Cap at floor 10
if (rand < 0.3) {
rockType = 'coal'; // Common on all floors
} else if (rand < 0.3 + 0.2 * floorMultiplier) {
rockType = 'copper_ore'; // More common on higher floors
} else if (rand < 0.3 + 0.2 * floorMultiplier + 0.15 * floorMultiplier) {
rockType = 'iron_ore'; // Rare, more common on higher floors
} else if (rand < 0.3 + 0.2 * floorMultiplier + 0.15 * floorMultiplier + 0.1 * floorMultiplier) {
rockType = 'gold_ore'; // Very rare, much more common on higher floors
} else if (rand < 0.3 + 0.2 * floorMultiplier + 0.15 * floorMultiplier + 0.1 * floorMultiplier + 0.05 * floorMultiplier) {
rockType = 'gem'; // Extremely rare, only on higher floors
}
var rock = new Rock(rockType);
do {
rock.x = 200 + Math.random() * 1648;
rock.y = 300 + Math.random() * 2132;
} while (checkCollisionWithWalls(rock.x, rock.y, 32));
rocks.push(rock);
game.addChild(rock);
}
// Generate slimes
var numSlimes = 3 + Math.floor(currentFloor * 1.5);
for (var i = 0; i < numSlimes; i++) {
var slime = new Slime();
do {
slime.x = 200 + Math.random() * 1648;
slime.y = 300 + Math.random() * 2132;
} while (checkCollisionWithWalls(slime.x, slime.y, 32));
slime.maxHealth += Math.floor(currentFloor * 10);
slime.health = slime.maxHealth;
slimes.push(slime);
game.addChild(slime);
}
// Ladder will be generated when mining rocks
ladder = null;
// Update floor text
floorText.setText('Floor: ' + currentFloor);
}
function clearFloor() {
// Remove all walls
for (var i = 0; i < walls.length; i++) {
game.removeChild(walls[i]);
}
walls = [];
// Remove all rocks
for (var i = 0; i < rocks.length; i++) {
game.removeChild(rocks[i]);
}
rocks = [];
// Remove all slimes
for (var i = 0; i < slimes.length; i++) {
game.removeChild(slimes[i]);
}
slimes = [];
// Remove all resources
for (var i = 0; i < resources.length; i++) {
game.removeChild(resources[i]);
}
resources = [];
// Remove all health items
for (var i = 0; i < healthItems.length; i++) {
game.removeChild(healthItems[i]);
}
healthItems = [];
// Remove ladder
if (ladder) {
game.removeChild(ladder);
ladder = null;
}
}
function updateUI() {
// Update health bar
healthBar.setText('Health: ' + player.health + '/' + player.maxHealth);
// Update inventory display
var inventoryStr = '';
for (var item in inventory) {
if (inventory[item] > 0) {
inventoryStr += item.replace('_', ' ') + ': ' + inventory[item] + '\n';
}
}
inventoryText.setText(inventoryStr);
}
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode) {
var newX = x;
var newY = y;
// Keep player within bounds
newX = Math.max(64, Math.min(1984, newX));
newY = Math.max(164, Math.min(2668, newY));
// Check collision with walls
if (!checkCollisionWithWalls(newX, newY, 32)) {
dragNode.x = newX;
dragNode.y = newY;
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
// Attack on tap
player.attack();
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
if (!player) return;
// Update slimes
for (var i = 0; i < slimes.length; i++) {
slimes[i].update();
}
// Check automatic mining when player is on top of rocks
for (var i = rocks.length - 1; i >= 0; i--) {
var rock = rocks[i];
var dx = rock.x - player.x;
var dy = rock.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
// Player is standing on/very close to rock
rock.hit();
}
}
// Check resource collection
for (var i = resources.length - 1; i >= 0; i--) {
var resource = resources[i];
var dx = resource.x - player.x;
var dy = resource.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
resource.collect();
}
}
// Check health item collection
for (var i = healthItems.length - 1; i >= 0; i--) {
var healthItem = healthItems[i];
var dx = healthItem.x - player.x;
var dy = healthItem.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
healthItem.collect();
}
}
// Check ladder interaction
if (ladder && !ladder.used) {
var dx = ladder.x - player.x;
var dy = ladder.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 50) {
ladder.use();
}
}
// Update UI
updateUI();
};
// Initialize the game
initializeGame();
Heart pixart. In-Game asset. 2d. High contrast. No shadows
Muro de piedras tipo cueva. In-Game asset. 2d. High contrast. No shadows
Slime pixart cute. In-Game asset. 2d. High contrast. No shadows
Minero pixart cute. In-Game asset. 2d. High contrast. No shadows
Escalera pixart. In-Game asset. 2d. High contrast. No shadows
Gold ore poxart. In-Game asset. 2d. High contrast. No shadows
Coal ore. In-Game asset. 2d. High contrast. No shadows
Chopper ore pixart. In-Game asset. 2d. High contrast. No shadows
Rocas pixart. In-Game asset. 2d. High contrast. No shadows
Iron ore pixart. In-Game asset. 2d. High contrast. No shadows
Gema de mina super especial pixart. In-Game asset. 2d. High contrast. No shadows
flechita hacia arriba pixart. In-Game asset. 2d. High contrast. No shadows
pico de madera pixart. In-Game asset. 2d. High contrast. No shadows
espada de madera pixart. In-Game asset. 2d. High contrast. No shadows
quitale el circulo del casco
que el minero este mirando de frente y llendo de frente
suelo de tierra pixart. In-Game asset. 2d. High contrast. No shadows
boton de un inventario pixelart. In-Game asset. 2d. High contrast. No shadows
quitar la palabra "inventory"
entrada a una mina pixelart. In-Game asset. 2d. High contrast. No shadows
lobo babeando pixelart. In-Game asset. 2d. High contrast. No shadows
arbusto pixelart. In-Game asset. 2d. High contrast. No shadows
cesped pixelart. In-Game asset. 2d. High contrast. No shadows
npc market pixelart. In-Game asset. 2d. High contrast. No shadows
coin pixelart. In-Game asset. 2d. High contrast. No shadows