User prompt
ya agrege la nueva imagen del otro npc el vendedor pero no cambia y hay que mejorar el mapa del pueblo hay que hacer que sea siempre el mismo en el cual halla un camnio hacia la mina al lado de este camino unas casas y alrededor de estas si los arboles y arbustos recuarda dejar su apartados para los assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
quiero que crees las instancias de los assets de las monedas del indicador de pueblo el indicador de mina y el otro npc para yo cargar las imagenes
User prompt
ahora hay que hacer el ssitema de coins el cual tendra su propio asste para que yo agrege imagen y las coins que tenga el personaje salgan al lado del indicador de la zona y yo diria agregar un segundo npc con sus propios asets el cual tendra su interfaz en la cual nos vendera picos y espadas de distintos materiales acambio de las monedas ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
el personaje se ve por debajo del pasto del pueblo
User prompt
quiero que tengan sus propios assets el indicador de los lugares y al interactual con el npc saque 2 interfaces la primera sera una guia de presios en el cual indica el valor de cada item y la otra sera una interfaz de venta donde yo le puedo vender lo que yo tenga en mi inventario al npc ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'ReferenceError: locationStatus is not defined' in or related to this line: 'locationStatus.removeChild(locationStatus.locationSprite);' Line Number: 1086
User prompt
ahora al lado derecho del contador de pisos agregar un nuevo assets y un texto que indique donde se esta por ejemplo al estar en las minas dira minas y al estar fuera de la mina dira pueblo
User prompt
muy bien ahora vamos a retocar una cosa y es que la barra de vida sea el doble de larga ademas de cambiar de color segun el porcentaje de vida y en el indicador de pisos cambie a otro asset cuando se sale de la mina y tenga al lado el texto "pueblo pochis" ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
vale hay un problema con la entrada y salida de la mina ya que la transision es muy lenta y creo que hay fallos asi que lo que vamos hacer es que cuando el player toque la entrada y/o salida lo va spawnear 4 bloque abajo del asset de la entrada / salida
User prompt
bien ya casi solo que la entrada y salida no estan alineados cuando uno los atravieza uno esta mas abajo que otro y eso genera distorsion la ydea es que el asset simpre este en el mismo 3x3 adema quiero que el npc tambien sea un 3x3
User prompt
no funciono mejor deja solo un asset el cual sea 3x3 y ese mismo lleva del piso 0 que se le llamara ahora "pueblo pochis" al piso 1 de la mina de hay cualquier piso de la mina al entrar saldra a pueblo pochis
User prompt
bien pero sige mostrando en pantalla las 2 tanto entrada como salida la idea es que desaparezca una segun en donde se esta si esta en el posi 0 solo se debe ver la entrada y si se esta en la mina solo debe estar visible la salida
User prompt
muy bien ahora vamos hacer como un piso 0 que sera la entrada a la mina culla entrada sera un asets donde llevara al piso 1 pero ademas al rededor tendra como una ambientacion de bosque y que halla un npc que sea como un comerciante el cual nos va a comprar los items que recojemos en el juego y para volver al piso 0 luego de estar en las minas basta con entrar a la salida de la mina que ya tenemos
User prompt
vale hay que mejorar la logica y es que cuando carga un piso ya se debe definir en que mineral o piedra estara debajo la escalera y se revelara cuando el player pice el mineral y cuando este se haga pequño hay sale el sprite de la escalera
User prompt
muy bien ya tenemos gran parte de la logica del juego ahora vamos hacer que el jugador empieza ya debajo de un aset que sera como la entrada de la cueva y cuando el player encuentre la escalera para avanzar que es cuado termina de minar una roca o mineral aleatoriamente en 1 de esos materiales o rocas del mapa saldra debajo la escalera al siguiente piso
User prompt
muy bien ahora el boton del inventario la interfaz del inventario debe tener sus propios asetts para yo modificarlos por imagenes ademas el inventario debe superponerse a todo en la pantalla
User prompt
los spritedel inventario siguen sin verse asi que vamos a cambiar la logica del inventario asi que vamos hacer un boton con un sprite y yo le colocare una imagen dicho boton va abrir una interfaz tipica de inventario como de stardew valley y hay se vean los sprites o assets de los items
User prompt
no se ven los sprites de los items cuando se recojen solo se ven los numeros y la barrita de vida me encanto pero quiero que sea mas grande y en horizantal
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'set')' in or related to this line: 'inventoryText.anchor.set(1, 0);' Line Number: 718
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'set')' in or related to this line: 'floorText.anchor.set(0.5, 0);' Line Number: 715
User prompt
ahora vamos a mejorar la interfaz y es que el indicador de vida sea una barrita vertical el indicador del piso sea un sprite y al lado el numero y los items que recoja sean los sprites d elos items y al lado el numero
User prompt
que el jugador pueda traspasar los enemigos para que no lo encierren y el jugador tenga que darles 3 espadazos para derrotarlos y que el slime puedaatacar al jugador en cualquier direccion incluso en diagonales
User prompt
que ahora pegen en intervalos de 100ms
User prompt
ahora separaste mucho al enemigo y no le hace daño juntalo un poquito mas y que le haga al jugador un 5% de daño en toque con intervalos de medio segundo
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ActionButton = Container.expand(function (actionType) { var self = Container.call(this); self.actionType = actionType; var buttonGraphics = self.attachAsset(actionType, { anchorX: 0.5, anchorY: 0.5 }); // Action image is now visible without text overlay self.down = function (x, y, obj) { // Visual feedback - make button slightly darker when pressed buttonGraphics.tint = 0x666666; if (self.actionType === 'pickaxe') { // Mining action - check for adjacent rocks for (var i = 0; i < rocks.length; i++) { var rock = rocks[i]; if (!rock.destroyed) { var dx = rock.x - player.x; var dy = rock.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= 80) { rock.hit(); break; // Mine only one rock per click } } } } else if (self.actionType === 'sword') { // Attack action - check for adjacent slimes for (var i = 0; i < slimes.length; i++) { var slime = slimes[i]; if (!slime.destroyed) { var dx = slime.x - player.x; var dy = slime.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= 80 && hasLineOfSight(player.x, player.y, slime.x, slime.y)) { slime.takeDamage(34); // 3 hits to kill (100/3 = ~34 damage) LK.getSound('attack').play(); break; // Attack only one slime per click } } } } }; self.up = function (x, y, obj) { // Reset button color when released buttonGraphics.tint = 0xFFFFFF; }; return self; }); var DirectionalButton = Container.expand(function (direction) { var self = Container.call(this); self.direction = direction; self.isPressed = false; self.moveTimer = null; var buttonGraphics = self.attachAsset('arrow' + direction.charAt(0).toUpperCase() + direction.slice(1), { anchorX: 0.5, anchorY: 0.5 }); // Method to move player in the button's direction self.movePlayer = function () { var moveDistance = 20; // Increased movement distance for faster speed var newX = player.x; var newY = player.y; if (self.direction === 'Up') { newY = player.y - moveDistance; } else if (self.direction === 'Down') { newY = player.y + moveDistance; } else if (self.direction === 'Left') { newX = player.x - moveDistance; } else if (self.direction === 'Right') { newX = player.x + moveDistance; } // Keep player within bounds newX = Math.max(64, Math.min(1984, newX)); newY = Math.max(164, Math.min(2668, newY)); // Check collision before moving if (!checkCollisionWithSolids(newX, newY, 15)) { player.x = newX; player.y = newY; // Update player facing direction based on movement if (self.direction === 'Left') { player.setFacingDirection('left'); } else if (self.direction === 'Right') { player.setFacingDirection('right'); } else if (self.direction === 'Up') { player.setFacingDirection('up'); } else if (self.direction === 'Down') { player.setFacingDirection('down'); } } }; // Arrow image is now visible without text overlay self.down = function (x, y, obj) { // Visual feedback - make button slightly darker when pressed buttonGraphics.tint = 0x3A7BC8; self.isPressed = true; // Move immediately on press self.movePlayer(); // Start continuous movement timer self.moveTimer = LK.setInterval(function () { if (self.isPressed) { self.movePlayer(); } }, 80); // Move every 80ms while pressed for faster speed }; self.up = function (x, y, obj) { // Reset button color when released buttonGraphics.tint = 0xFFFFFF; self.isPressed = false; // Clear continuous movement timer if (self.moveTimer) { LK.clearInterval(self.moveTimer); self.moveTimer = null; } }; return self; }); var FloorTile = Container.expand(function () { var self = Container.call(this); var tileGraphics = self.attachAsset('floorTile', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); // Add subtle border to show grid lines tileGraphics.alpha = 0.3; return self; }); var HealthItem = Container.expand(function () { var self = Container.call(this); var heartGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5, width: 32, height: 32 }); 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 InventoryButton = Container.expand(function () { var self = Container.call(this); var buttonGraphics = self.attachAsset('inventoryButton', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { buttonGraphics.tint = 0x666666; // Toggle inventory interface if (inventoryInterface.visible) { inventoryInterface.visible = false; } else { inventoryInterface.visible = true; updateInventoryInterface(); } }; self.up = function (x, y, obj) { buttonGraphics.tint = 0xFFFFFF; }; return self; }); var InventoryInterface = Container.expand(function () { var self = Container.call(this); // Create background panel var background = self.attachAsset('inventoryBackground', { anchorX: 0.5, anchorY: 0.5 }); // Create border var border = self.attachAsset('inventoryBorder', { anchorX: 0.5, anchorY: 0.5 }); self.addChildAt(border, 0); // Title text var titleText = new Text2('Inventory', { size: 40, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 0; titleText.y = -180; self.addChild(titleText); self.itemSlots = []; // Create grid of item slots (6x4 grid) var slotSize = 80; var slotSpacing = 90; var startX = -225; var startY = -120; for (var row = 0; row < 4; row++) { for (var col = 0; col < 6; col++) { var slotContainer = new Container(); // Slot background var slotBg = LK.getAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); slotContainer.addChild(slotBg); slotContainer.x = startX + col * slotSpacing; slotContainer.y = startY + row * slotSpacing; self.addChild(slotContainer); self.itemSlots.push(slotContainer); } } self.visible = false; return self; }); var Ladder = Container.expand(function () { var self = Container.call(this); var ladderGraphics = self.attachAsset('ladder', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); self.used = false; self.use = function () { if (self.used) return; self.used = true; currentFloor++; generateFloor(); }; return self; }); var Merchant = Container.expand(function () { var self = Container.call(this); var npcGraphics = self.attachAsset('npc', { anchorX: 0.5, anchorY: 0.5, width: 192, height: 192 }); self.down = function (x, y, obj) { // Open merchant interface openMerchantInterface(); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); var playerVerticalGraphics = self.attachAsset('playerVertical', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); playerVerticalGraphics.visible = false; // Hide vertical sprite initially var playerDownGraphics = self.attachAsset('playerDown', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); playerDownGraphics.visible = false; // Hide down sprite initially self.maxHealth = 100; self.health = self.maxHealth; self.speed = 3; self.attackRange = 80; self.attackDamage = 25; self.lastAttackTime = 0; self.attackCooldown = 500; self.facingDirection = 'right'; // Track which direction player is facing self.lastX = 0; // Track last position to determine movement direction self.lastY = 0; // Method to update sprite direction based on facing self.updateSpriteDirection = function () { if (self.facingDirection === 'left') { playerGraphics.visible = true; playerVerticalGraphics.visible = false; playerDownGraphics.visible = false; playerGraphics.scale.x = -1; // Flip sprite horizontally playerGraphics.rotation = 0; // No rotation } else if (self.facingDirection === 'right') { playerGraphics.visible = true; playerVerticalGraphics.visible = false; playerDownGraphics.visible = false; playerGraphics.scale.x = 1; // Normal sprite orientation playerGraphics.rotation = 0; // No rotation } else if (self.facingDirection === 'up') { playerGraphics.visible = false; playerVerticalGraphics.visible = true; playerDownGraphics.visible = false; playerVerticalGraphics.scale.x = 1; // Normal scale playerVerticalGraphics.rotation = 0; // No rotation - use original up sprite } else if (self.facingDirection === 'down') { playerGraphics.visible = false; playerVerticalGraphics.visible = false; playerDownGraphics.visible = true; playerDownGraphics.scale.x = 1; // Normal scale playerDownGraphics.rotation = 0; // No rotation - use separate down sprite } }; // Method to set facing direction and update sprite self.setFacingDirection = function (direction) { if (direction === 'left' || direction === 'right' || direction === 'up' || direction === 'down') { self.facingDirection = direction; self.updateSpriteDirection(); } }; 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 !checkCollisionWithSolids(x, y, 15); }; self.update = function () { // Detect movement direction and update facing if (self.x !== self.lastX) { if (self.x > self.lastX) { self.setFacingDirection('right'); } else if (self.x < self.lastX) { self.setFacingDirection('left'); } } else if (self.y !== self.lastY) { if (self.y > self.lastY) { self.setFacingDirection('down'); } else if (self.y < self.lastY) { self.setFacingDirection('up'); } } // Update last position for next frame self.lastX = self.x; self.lastY = self.y; }; 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, width: 32, height: 32 }); 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, width: 64, height: 64 }); self.maxHealth = 3; self.health = self.maxHealth; self.destroyed = false; self.mined = 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.mine(); } }; self.mine = function () { if (self.mined || self.destroyed) return; self.mined = true; // Animate to half size and make collectable tween(rockGraphics, { width: 32, height: 32 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Now it becomes a collectable resource self.collectable = true; // If this rock has the ladder, reveal it underneath if (self.hasLadder && !ladder) { ladder = new Ladder(); ladder.x = self.x; ladder.y = self.y; game.addChild(ladder); } } }); }; 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 always drops a rock resource resource = new Resource('rock'); } if (resource) { resource.x = self.x; resource.y = self.y; resources.push(resource); game.addChild(resource); } // Ladder is now spawned when mining the pre-determined ladder rock, not randomly on destroy // 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); }; self.collect = function () { if (!self.collectable || self.destroyed) return; LK.getSound('collect').play(); // Update inventory if (!inventory[self.rockType]) { inventory[self.rockType] = 0; } inventory[self.rockType]++; self.destroy(); }; return self; }); var Slime = Container.expand(function () { var self = Container.call(this); var slimeGraphics = self.attachAsset('slime', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); self.maxHealth = 100; self.health = self.maxHealth; self.speed = 1; self.attackDamage = 15; self.lastAttackTime = 0; self.attackCooldown = 1000; self.attackRange = 50; self.lastDamageTime = 0; self.damageInterval = 100; // 0.1 seconds between damage ticks 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; // Always drop slime item var slimeResource = new Resource('slime'); slimeResource.x = self.x; slimeResource.y = self.y; resources.push(slimeResource); game.addChild(slimeResource); // 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 in any direction (including diagonals) 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 (only with solids and other slimes, not player) if (!checkCollisionWithSolids(newX, newY, 15) && !checkCollisionWithSlimes(newX, newY, 15, self)) { self.x = newX; self.y = newY; } // Apply damage if touching player in any direction (including diagonals) if (distance <= 50 && LK.ticks - self.lastDamageTime > self.damageInterval) { self.lastDamageTime = LK.ticks; player.takeDamage(Math.floor(player.maxHealth * 0.05)); // 5% damage } } }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); 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 = 0; // Start at floor 0 (surface) var walls = []; var floorTiles = []; var inventoryInterface; var inventoryButton; var merchant; var forestObjects = []; var merchantInterface; var isInMine = false; 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 checkCollisionWithSolids(x, y, radius) { // Check collision with walls 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; } } // Check collision with rocks for (var i = 0; i < rocks.length; i++) { var rock = rocks[i]; if (!rock.destroyed && !rock.mined) { var dx = Math.abs(x - rock.x); var dy = Math.abs(y - rock.y); if (dx < 16 + radius && dy < 16 + radius) { return true; } } } // Check collision with forest objects (trees and bushes) for (var i = 0; i < forestObjects.length; i++) { var forestObj = forestObjects[i]; var dx = Math.abs(x - forestObj.x); var dy = Math.abs(y - forestObj.y); var objRadius = forestObj.width > 64 ? 48 : 24; // Trees are bigger if (dx < objRadius + radius && dy < objRadius + radius) { return true; } } return false; } function checkCollisionWithSlimes(x, y, radius, excludeSlime) { for (var i = 0; i < slimes.length; i++) { var slime = slimes[i]; if (!slime.destroyed && slime !== excludeSlime) { var dx = Math.abs(x - slime.x); var dy = Math.abs(y - slime.y); if (dx < 50 + radius && dy < 50 + radius) { return true; } } } return false; } function checkCollisionWithPlayer(x, y, radius) { if (!player) return false; var dx = Math.abs(x - player.x); var dy = Math.abs(y - player.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 (checkCollisionWithSolids(checkX, checkY, 8)) { return false; } } return true; } // UI Elements var healthBar; var floorText; var inventoryText; function initializeGame() { player = game.addChild(new Player()); if (currentFloor === 0) { player.x = 1024; player.y = 400; // Start on surface near cave entrance } else { player.x = 1024; player.y = 300; // Start in mine near entrance } // Initialize position tracking player.lastX = player.x; player.lastY = player.y; // Create UI - Health bar as horizontal bar (larger) healthBar = new Container(); var healthBarBg = healthBar.attachAsset('wall', { anchorX: 0, anchorY: 0, width: 200, height: 30 }); healthBarBg.tint = 0x333333; // Dark background var healthBarFill = healthBar.attachAsset('wall', { anchorX: 0, anchorY: 0, width: 196, height: 26 }); healthBarFill.tint = 0xFF0000; // Red health fill healthBarFill.x = 2; healthBarFill.y = 2; healthBar.healthBarFill = healthBarFill; // Store reference for updates LK.gui.topLeft.addChild(healthBar); healthBar.x = 130; healthBar.y = 20; floorText = new Container(); var floorSprite = floorText.attachAsset('ladder', { anchorX: 0, anchorY: 0, width: 40, height: 40 }); var floorNumber = new Text2('1', { size: 40, fill: 0xFFFFFF }); floorNumber.anchor.set(0, 0); floorNumber.x = 50; floorNumber.y = 0; floorText.addChild(floorNumber); floorText.floorNumber = floorNumber; // Store reference for updates LK.gui.top.addChild(floorText); floorText.y = 20; // Create inventory button inventoryButton = new InventoryButton(); inventoryButton.x = -80; inventoryButton.y = 80; LK.gui.topRight.addChild(inventoryButton); // Create inventory interface (initially hidden) inventoryInterface = new InventoryInterface(); inventoryInterface.x = 0; inventoryInterface.y = 0; LK.gui.center.addChild(inventoryInterface); generateFloor(); // Create directional control buttons in bottom left var buttonSize = 80; var buttonSpacing = 90; var baseX = 120; var baseY = -200; // Create up arrow button var upButton = new DirectionalButton('Up'); upButton.x = baseX; upButton.y = baseY - buttonSpacing; LK.gui.bottomLeft.addChild(upButton); // Create down arrow button var downButton = new DirectionalButton('Down'); downButton.x = baseX; downButton.y = baseY + buttonSpacing; LK.gui.bottomLeft.addChild(downButton); // Create left arrow button var leftButton = new DirectionalButton('Left'); leftButton.x = baseX - buttonSpacing; leftButton.y = baseY; LK.gui.bottomLeft.addChild(leftButton); // Create right arrow button var rightButton = new DirectionalButton('Right'); rightButton.x = baseX + buttonSpacing; rightButton.y = baseY; LK.gui.bottomLeft.addChild(rightButton); // Create action buttons on the right side var actionBaseX = -120; var actionBaseY = -200; // Create pickaxe button var pickaxeButton = new ActionButton('pickaxe'); pickaxeButton.x = actionBaseX; pickaxeButton.y = actionBaseY - buttonSpacing / 2; LK.gui.bottomRight.addChild(pickaxeButton); // Create sword button var swordButton = new ActionButton('sword'); swordButton.x = actionBaseX; swordButton.y = actionBaseY + buttonSpacing / 2; LK.gui.bottomRight.addChild(swordButton); } function generateFloor() { // Clear existing objects clearFloor(); if (currentFloor === 0) { // Generate surface floor (floor 0) generateSurface(); return; } // Generate floor tiles for grid visualization for (var x = 64; x < 2048; x += 64) { for (var y = 196; y < 2700; y += 64) { var floorTile = new FloorTile(); floorTile.x = x; floorTile.y = y; floorTiles.push(floorTile); game.addChild(floorTile); } } // 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 structured maze with corridors and chambers generateMazeStructure(); // Pre-determine which rock will contain the ladder var ladderRockIndex = Math.floor(Math.random() * (15 + Math.floor(currentFloor * 2))); var ladderRock = null; // Generate rocks with different types based on floor, placed in accessible areas 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); var attempts = 0; do { // Generate grid-aligned positions (64x64 grid cells) var gridX = Math.floor(Math.random() * 26) + 3; // Grid positions 3-28 var gridY = Math.floor(Math.random() * 32) + 5; // Grid positions 5-36 rock.x = 64 + gridX * 64; // Center in grid cell rock.y = 196 + gridY * 64; // Center in grid cell attempts++; } while (checkCollisionWithSolids(rock.x, rock.y, 24) && attempts < 100); // If we couldn't find a good spot after 100 attempts, place it along corridors if (attempts >= 100) { var corridorGridX = Math.floor(Math.random() * 18) + 6; // Corridor area grid var corridorGridY = Math.floor(Math.random() * 20) + 9; // Corridor area grid rock.x = 64 + corridorGridX * 64; rock.y = 196 + corridorGridY * 64; // Try a few more times in corridor area var corridorAttempts = 0; while (checkCollisionWithSolids(rock.x, rock.y, 24) && corridorAttempts < 20) { corridorGridX = Math.floor(Math.random() * 18) + 6; corridorGridY = Math.floor(Math.random() * 20) + 9; rock.x = 64 + corridorGridX * 64; rock.y = 196 + corridorGridY * 64; corridorAttempts++; } } // Mark this rock as the ladder rock if it's the chosen one if (i === ladderRockIndex) { rock.hasLadder = true; ladderRock = rock; } rocks.push(rock); game.addChild(rock); } // Generate slimes in accessible areas var numSlimes = 3 + Math.floor(currentFloor * 1.5); for (var i = 0; i < numSlimes; i++) { var slime = new Slime(); var attempts = 0; do { slime.x = 200 + Math.random() * 1648; slime.y = 300 + Math.random() * 2132; attempts++; } while (checkCollisionWithSolids(slime.x, slime.y, 20) && attempts < 100); // If we couldn't find a good spot after 100 attempts, place it along corridors if (attempts >= 100) { slime.x = 400 + Math.random() * 1200; slime.y = 600 + Math.random() * 1400; // Try a few more times in corridor area var corridorAttempts = 0; while (checkCollisionWithSolids(slime.x, slime.y, 20) && corridorAttempts < 20) { slime.x = 400 + Math.random() * 1200; slime.y = 600 + Math.random() * 1400; corridorAttempts++; } } slime.maxHealth += Math.floor(currentFloor * 10); slime.health = slime.maxHealth; slimes.push(slime); game.addChild(slime); } // Create portal at the top center (to return to surface) var portal = LK.getAsset('portalEntrance', { anchorX: 0.5, anchorY: 0.5, width: 192, height: 192 }); portal.x = 1024; // Center horizontally portal.y = 300; // Consistent position with surface portal.isPortal = true; game.addChild(portal); // Ladder will be generated when mining rocks ladder = null; // Update floor text floorText.floorNumber.setText(currentFloor.toString()); } function clearFloor() { // Remove all floor tiles for (var i = 0; i < floorTiles.length; i++) { game.removeChild(floorTiles[i]); } floorTiles = []; // 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; } // Remove forest objects for (var i = 0; i < forestObjects.length; i++) { game.removeChild(forestObjects[i]); } forestObjects = []; // Remove merchant if (merchant) { game.removeChild(merchant); merchant = null; } } function updateInventoryInterface() { // Clear existing items from slots for (var i = 0; i < inventoryInterface.itemSlots.length; i++) { var slot = inventoryInterface.itemSlots[i]; // Remove all children except the background (first child) while (slot.children.length > 1) { slot.removeChild(slot.children[slot.children.length - 1]); } } // Add items to slots var slotIndex = 0; for (var item in inventory) { if (inventory[item] > 0 && slotIndex < inventoryInterface.itemSlots.length) { var slot = inventoryInterface.itemSlots[slotIndex]; // Add item sprite var itemSprite = LK.getAsset(item, { anchorX: 0.5, anchorY: 0.5, width: 50, height: 50 }); itemSprite.x = 0; itemSprite.y = -10; slot.addChild(itemSprite); // Add quantity text var quantityText = new Text2(inventory[item].toString(), { size: 20, fill: 0xFFFFFF }); quantityText.anchor.set(0.5, 0); quantityText.x = 0; quantityText.y = 20; slot.addChild(quantityText); slotIndex++; } } } function updateUI() { // Update health bar - scale the fill based on health percentage (horizontal) var healthPercent = player.health / player.maxHealth; healthBar.healthBarFill.width = 196 * healthPercent; // Inventory is now handled by the inventory interface when opened } 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 and rocks if (!checkCollisionWithSolids(newX, newY, 15)) { var oldX = dragNode.x; dragNode.x = newX; dragNode.y = newY; // Update player facing direction based on drag movement if (dragNode === player) { var oldY = dragNode.y; if (newX !== oldX) { if (newX > oldX) { player.setFacingDirection('right'); } else if (newX < oldX) { player.setFacingDirection('left'); } } else if (newY !== oldY) { if (newY > oldY) { player.setFacingDirection('down'); } else if (newY < oldY) { player.setFacingDirection('up'); } } } } } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = player; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { if (!player) return; // Update player player.update(); // Update slimes for (var i = 0; i < slimes.length; i++) { slimes[i].update(); } // Slimes now handle their own damage timing individually // Automatic mining removed - now controlled by left click // 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 mined rock collection for (var i = rocks.length - 1; i >= 0; i--) { var rock = rocks[i]; if (rock.collectable && !rock.destroyed) { var dx = rock.x - player.x; var dy = rock.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { rock.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 (only in mine floors) if (ladder && !ladder.used && currentFloor > 0) { 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(); } } // Check portal interactions var allChildren = game.children; for (var i = 0; i < allChildren.length; i++) { var child = allChildren[i]; if (child.isPortal) { var dx = child.x - player.x; var dy = child.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 100) { if (currentFloor === 0) { // Enter mine (go to floor 1) currentFloor = 1; isInMine = true; generateFloor(); } else { // Exit mine (go to pueblo pochis - floor 0) currentFloor = 0; isInMine = false; generateFloor(); } break; } } } // Update UI updateUI(); }; // Initialize the game initializeGame(); function generateMazeStructure() { // Create grid for maze generation (30x38 cells, each cell is 64x64 pixels) var gridWidth = 30; var gridHeight = 38; var cellSize = 64; var startX = 96; var startY = 196; // Create a grid to track where corridors are var corridorGrid = []; for (var x = 0; x < gridWidth; x++) { corridorGrid[x] = []; for (var y = 0; y < gridHeight; y++) { corridorGrid[x][y] = false; } } // Create main entrance tunnel from top-center var entranceX = Math.floor(gridWidth / 2); for (var y = 2; y < 8; y++) { corridorGrid[entranceX][y] = true; // Make entrance wider (3 tiles wide) if (entranceX - 1 >= 0) corridorGrid[entranceX - 1][y] = true; if (entranceX + 1 < gridWidth) corridorGrid[entranceX + 1][y] = true; } // Create main horizontal distribution corridor var mainCorridorY = 8; for (var x = 4; x < gridWidth - 4; x++) { corridorGrid[x][mainCorridorY] = true; // Make main corridor wider corridorGrid[x][mainCorridorY + 1] = true; } // Create realistic mining tunnels branching from main corridor var numMainTunnels = 4 + Math.floor(currentFloor / 3); var tunnelSpacing = Math.floor((gridWidth - 8) / numMainTunnels); for (var i = 0; i < numMainTunnels; i++) { var tunnelX = 4 + i * tunnelSpacing + Math.floor(Math.random() * (tunnelSpacing / 2)); var tunnelLength = 8 + Math.floor(Math.random() * 12); var tunnelStartY = mainCorridorY + 2; // Create main mining tunnel going down for (var y = tunnelStartY; y < Math.min(tunnelStartY + tunnelLength, gridHeight - 2); y++) { corridorGrid[tunnelX][y] = true; // Add slight width variation to make it more natural if (Math.random() > 0.6) { if (tunnelX - 1 >= 2) corridorGrid[tunnelX - 1][y] = true; } else if (Math.random() > 0.6) { if (tunnelX + 1 < gridWidth - 2) corridorGrid[tunnelX + 1][y] = true; } } // Create mining chambers at the end of tunnels if (tunnelStartY + tunnelLength < gridHeight - 4) { var chamberY = tunnelStartY + tunnelLength - 2; var chamberSize = 2 + Math.floor(Math.random() * 2); // 2x2 or 3x3 chamber for (var cx = -chamberSize; cx <= chamberSize; cx++) { for (var cy = -1; cy <= chamberSize; cy++) { var newX = tunnelX + cx; var newY = chamberY + cy; if (newX >= 2 && newX < gridWidth - 2 && newY >= 2 && newY < gridHeight - 2) { corridorGrid[newX][newY] = true; } } } } // Create side branches from main tunnels (like real mine shafts) var numSideBranches = 1 + Math.floor(Math.random() * 2); for (var j = 0; j < numSideBranches; j++) { var branchY = tunnelStartY + 3 + Math.floor(Math.random() * (tunnelLength - 6)); var branchDirection = Math.random() > 0.5 ? 1 : -1; var branchLength = 3 + Math.floor(Math.random() * 5); for (var k = 1; k <= branchLength; k++) { var branchX = tunnelX + k * branchDirection; if (branchX >= 2 && branchX < gridWidth - 2) { corridorGrid[branchX][branchY] = true; // Small chamber at end of side branch if (k === branchLength) { if (branchY - 1 >= 2) corridorGrid[branchX][branchY - 1] = true; if (branchY + 1 < gridHeight - 2) corridorGrid[branchX][branchY + 1] = true; } } } } } // Create connecting tunnels between some main tunnels (crosscuts) var numConnections = Math.floor(numMainTunnels / 2); for (var i = 0; i < numConnections; i++) { var connectionY = mainCorridorY + 5 + Math.floor(Math.random() * 10); var startX = 4 + Math.floor(Math.random() * (gridWidth - 12)); var endX = startX + 4 + Math.floor(Math.random() * 6); for (var x = startX; x <= Math.min(endX, gridWidth - 3); x++) { if (connectionY >= 2 && connectionY < gridHeight - 2) { corridorGrid[x][connectionY] = true; } } } // Convert corridor grid to walls (fill in non-corridor spaces) for (var x = 2; x < gridWidth - 2; x++) { for (var y = 2; y < gridHeight - 2; y++) { if (!corridorGrid[x][y]) { var wall = new Wall(); // Align wall to grid cell center (64x64 grid cells) wall.x = 64 + x * cellSize; // Center in grid cell wall.y = 196 + y * cellSize; // Center in grid cell walls.push(wall); game.addChild(wall); } } } // Add structural support pillars in wider areas var numPillars = Math.floor(currentFloor / 3); for (var i = 0; i < numPillars; i++) { var pillarX = Math.floor(6 + Math.random() * (gridWidth - 12)); var pillarY = Math.floor(mainCorridorY + 3 + Math.random() * (gridHeight - mainCorridorY - 6)); // Only place pillar if it's in a corridor and won't block paths if (corridorGrid[pillarX][pillarY]) { var canPlace = true; // Check if placing pillar would block critical paths for (var dx = -1; dx <= 1 && canPlace; dx++) { for (var dy = -1; dy <= 1 && canPlace; dy++) { var checkX = pillarX + dx; var checkY = pillarY + dy; if (checkX >= 0 && checkX < gridWidth && checkY >= 0 && checkY < gridHeight) { // Don't place if it would create a dead end if (!corridorGrid[checkX][checkY] && (dx === 0 || dy === 0)) { var adjacentCorridors = 0; if (checkX > 0 && corridorGrid[checkX - 1][checkY]) adjacentCorridors++; if (checkX < gridWidth - 1 && corridorGrid[checkX + 1][checkY]) adjacentCorridors++; if (checkY > 0 && corridorGrid[checkX][checkY - 1]) adjacentCorridors++; if (checkY < gridHeight - 1 && corridorGrid[checkX][checkY + 1]) adjacentCorridors++; if (adjacentCorridors < 2) canPlace = false; } } } } if (canPlace && Math.random() > 0.3) { var wall = new Wall(); // Align pillar wall to grid cell center (64x64 grid cells) wall.x = 64 + pillarX * cellSize; // Center in grid cell wall.y = 196 + pillarY * cellSize; // Center in grid cell walls.push(wall); game.addChild(wall); } } } } function generateSurface() { // Generate grass floor tiles for (var x = 64; x < 2048; x += 64) { for (var y = 196; y < 2700; y += 64) { var grassTile = LK.getAsset('grass', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); grassTile.x = x; grassTile.y = y; grassTile.alpha = 0.7; floorTiles.push(grassTile); game.addChild(grassTile); } } // Create portal at the center var portal = LK.getAsset('portalEntrance', { anchorX: 0.5, anchorY: 0.5, width: 192, height: 192 }); portal.x = 1024; // Center horizontally portal.y = 300; // Accessible position portal.isPortal = true; game.addChild(portal); // Create merchant NPC merchant = new Merchant(); merchant.x = 800; // Left side of cave entrance merchant.y = 400; game.addChild(merchant); // Generate forest environment // Add trees around the perimeter for (var i = 0; i < 15; i++) { var tree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, width: 128, height: 128 }); var attempts = 0; do { tree.x = 150 + Math.random() * 1748; tree.y = 250 + Math.random() * 2200; attempts++; } while (Math.abs(tree.x - 1024) < 200 && Math.abs(tree.y - 350) < 150 && attempts < 50); forestObjects.push(tree); game.addChild(tree); } // Add bushes scattered around for (var i = 0; i < 25; i++) { var bush = LK.getAsset('bush', { anchorX: 0.5, anchorY: 0.5, width: 64, height: 64 }); var attempts = 0; do { bush.x = 150 + Math.random() * 1748; bush.y = 250 + Math.random() * 2200; attempts++; } while (Math.abs(bush.x - 1024) < 150 && Math.abs(bush.y - 350) < 100 && attempts < 50); forestObjects.push(bush); game.addChild(bush); } isInMine = false; } function openMerchantInterface() { // Simple merchant interaction - sell all items var totalValue = 0; var itemsSold = []; for (var item in inventory) { if (inventory[item] > 0) { var itemValue = getItemValue(item); var itemTotal = inventory[item] * itemValue; totalValue += itemTotal; itemsSold.push(item + ' x' + inventory[item] + ' = ' + itemTotal + ' coins'); inventory[item] = 0; // Clear inventory } } if (totalValue > 0) { LK.setScore(LK.getScore() + totalValue); // Visual feedback LK.effects.flashScreen(0x00FF00, 500); } } function getItemValue(itemType) { switch (itemType) { case 'rock': return 1; case 'coal': return 3; case 'copper_ore': return 5; case 'iron_ore': return 8; case 'gold_ore': return 15; case 'gem': return 25; case 'slime': return 2; default: return 1; } }
===================================================================
--- original.js
+++ change.js
@@ -248,10 +248,10 @@
var self = Container.call(this);
var npcGraphics = self.attachAsset('npc', {
anchorX: 0.5,
anchorY: 0.5,
- width: 64,
- height: 64
+ width: 192,
+ height: 192
});
self.down = function (x, y, obj) {
// Open merchant interface
openMerchantInterface();
@@ -948,9 +948,9 @@
width: 192,
height: 192
});
portal.x = 1024; // Center horizontally
- portal.y = 260; // Just below the top wall
+ portal.y = 300; // Consistent position with surface
portal.isPortal = true;
game.addChild(portal);
// Ladder will be generated when mining rocks
ladder = null;
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