User prompt
hid gui when battle screen is up, both the top and bototm
User prompt
Add animation when ballte screen appears. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add more options, not only attach on battle screen
User prompt
Still seing other elelemtenon ballet screen.
User prompt
Nice! Make sure that when battle screen is up, only battle screen is seen..
User prompt
Lets add a battle system when the player touched on an enemy cell. Instead of just attacking it, let open a new screen where the player can fight it in a turn based battle, like pokemon.
User prompt
make sure upgrades work, since damage is not being increased neither max hp
User prompt
Improve the graphics of the grid cells when covered and uncovered, should stillbe squares, not green circles. Use a dungeon vibe color.
User prompt
Clicking the levle up button choices is not working. lets put the on a overlay an make sure they are clickable
User prompt
I do not see the update level button
User prompt
level up button should be on the top center of the screen
User prompt
When player has enough EXP, they can click the button to level up.
User prompt
when player has enought EXP to level up, enable the button to level up. it should be greyed out when he has not enough hp. On level up, payer will recover all hp.
User prompt
center the grid in the center of the screen
User prompt
Nice! Lets make the intiial grid 8 by 8
User prompt
Better, but its still cut off. Maybe try center them.
User prompt
Better, but I just see the values, the name of them is cut out on the left of the screen
User prompt
Still HP DMG and EXP are not displayed in the bottom of the screen
User prompt
HP DMG and EXP do not appera in the screen now.
User prompt
move hp exp and damage of player to the bottom of the screen
User prompt
when player touches on an enemy, instead of just killing it, open a new overlpa with the fight between the player and the enemy
User prompt
show enemy hp in 0/1 or whatever it is
User prompt
show the monsters hp and daamage
User prompt
Make sure enemies also generate damage to player
User prompt
Rearragne hud and indicators since everything is overlapping.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // EmptyTile: Represents a safe tile (no monster) var EmptyTile = Container.expand(function () { var self = Container.call(this); self.revealed = false; self.adjacentMonsters = 0; self.cover = self.attachAsset('emptyTileCover', { anchorX: 0.5, anchorY: 0.5 }); self.bg = self.attachAsset('emptyTileBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0 // Hidden until revealed }); self.adjText = new Text2('', { size: 48, fill: "#fff" }); self.adjText.anchor.set(0.5, 0.5); self.adjText.alpha = 0; self.addChild(self.adjText); self.reveal = function () { if (self.revealed) return; self.revealed = true; self.cover.alpha = 0.2; self.bg.alpha = 1; if (self.adjacentMonsters > 0) { self.adjText.setText(self.adjacentMonsters + ''); self.adjText.alpha = 1; } }; return self; }); // MonsterTile: Represents a monster hidden under a tile var MonsterTile = Container.expand(function () { var self = Container.call(this); // Monster stats self.hp = 1; self.maxHp = 1; self.damage = 1; self.exp = 1; self.revealed = false; self.defeated = false; // Visuals self.cover = self.attachAsset('monsterTileCover', { anchorX: 0.5, anchorY: 0.5 }); self.monster = self.attachAsset('monsterTileMonster', { anchorX: 0.5, anchorY: 0.5, alpha: 0 // Hidden until revealed }); // Show monster stats as text (hidden until revealed) self.statText = new Text2('', { size: 48, fill: "#fff" }); self.statText.anchor.set(0.5, 0.5); self.statText.alpha = 0; self.addChild(self.statText); // Reveal the monster self.reveal = function () { if (self.revealed) return; self.revealed = true; self.cover.alpha = 0.2; self.monster.alpha = 1; self.statText.setText('HP:' + self.hp + '/' + self.maxHp + ' DMG:' + self.damage); self.statText.y = -40; // Move stat text above monster graphic self.statText.alpha = 1; }; // Mark as defeated self.defeat = function () { self.defeated = true; self.monster.alpha = 0.3; self.cover.alpha = 0.1; self.statText.setText('HP:0/' + self.maxHp + ' DMG:' + self.damage + '\nDEFEATED'); self.statText.y = -40; self.statText.alpha = 1; }; return self; }); // Player: Holds player stats and methods var Player = Container.expand(function () { var self = Container.call(this); self.maxHp = 10; self.hp = 10; self.damage = 2; self.exp = 0; self.level = 1; self.expToLevel = 5; // Level up: spend exp to increase stats or heal self.levelUp = function (choice) { if (self.exp < self.expToLevel) return false; self.exp -= self.expToLevel; self.level += 1; self.expToLevel = Math.floor(self.expToLevel * 1.5); if (choice === 'hp') { self.maxHp += 3; self.hp = self.maxHp; } else if (choice === 'damage') { self.damage += 1; } else if (choice === 'heal') { self.hp = self.maxHp; } return true; }; // Take damage self.takeDamage = function (amount) { self.hp -= amount; if (self.hp < 0) self.hp = 0; }; // Gain exp self.gainExp = function (amount) { self.exp += amount; }; // Heal self.heal = function (amount) { self.hp += amount; if (self.hp > self.maxHp) self.hp = self.maxHp; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x22223a }); /**** * Game Code ****/ // --- Game Constants --- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } var GRID_COLS = 8; var GRID_ROWS = 8; var TILE_SIZE = 180; var GRID_OFFSET_X = Math.floor((2048 - GRID_COLS * TILE_SIZE) / 2); var GRID_OFFSET_Y = 300; var MONSTER_COUNT = 12; // --- Asset Initialization --- // --- Game State --- var player = new Player(); var grid = []; // 2D array [row][col] var tileObjs = []; // Flat array of all tile objects for easy iteration var monstersLeft = MONSTER_COUNT; var revealedTiles = 0; var totalSafeTiles = GRID_COLS * GRID_ROWS - MONSTER_COUNT; var gameOver = false; // --- GUI Elements --- var hpText = new Text2('', { size: 80, fill: 0xFF6666 }); hpText.anchor.set(0.5, 1); // Anchor to bottom-center hpText.x = 0; // Center horizontally relative to LK.gui.bottom hpText.y = -40; LK.gui.bottom.addChild(hpText); var dmgText = new Text2('', { size: 80, fill: "#fff" }); dmgText.anchor.set(0.5, 1); // Anchor to bottom-center dmgText.x = 0; // Center horizontally relative to LK.gui.bottom dmgText.y = -140; LK.gui.bottom.addChild(dmgText); var expText = new Text2('', { size: 80, fill: 0xFFE066 }); expText.anchor.set(0.5, 1); // Anchor to bottom-center expText.x = 0; // Center horizontally relative to LK.gui.bottom expText.y = -240; LK.gui.bottom.addChild(expText); var levelText = new Text2('', { size: 80, fill: 0xA3E635 }); levelText.anchor.set(1, 0); LK.gui.topRight.addChild(levelText); var monstersLeftText = new Text2('', { size: 60, fill: "#fff" }); monstersLeftText.anchor.set(1, 0); LK.gui.topRight.addChild(monstersLeftText); var levelUpBtn = new Text2('LEVEL UP', { size: 70, fill: "#fff", font: "Impact" }); levelUpBtn.anchor.set(0.5, 0.5); levelUpBtn.alpha = 0.7; levelUpBtn.visible = false; LK.gui.bottom.addChild(levelUpBtn); var levelUpChoiceBtns = []; var levelUpChoices = [{ label: "Max HP +3 & Heal", value: "hp" }, { label: "Damage +1", value: "damage" }, { label: "Heal to Max", value: "heal" }]; for (var i = 0; i < levelUpChoices.length; i++) { var btn = new Text2(levelUpChoices[i].label, { size: 60, fill: "#fff", font: "Impact" }); btn.anchor.set(0.5, 0.5); btn.visible = false; btn.alpha = 0.9; LK.gui.bottom.addChild(btn); levelUpChoiceBtns.push(btn); } // --- Helper Functions --- function updateGUI() { hpText.setText('HP: ' + player.hp + '/' + player.maxHp); hpText.x = 0; // Center horizontally relative to LK.gui.bottom hpText.y = -40; dmgText.setText('DMG: ' + player.damage); dmgText.x = 0; // Center horizontally relative to LK.gui.bottom dmgText.y = -140; expText.setText('EXP: ' + player.exp + '/' + player.expToLevel); expText.x = 0; // Center horizontally relative to LK.gui.bottom expText.y = -240; // Move levelText to top right, below monstersLeftText levelText.setText('LVL: ' + player.level); levelText.x = -120; levelText.y = 120; monstersLeftText.setText('Monsters: ' + monstersLeft); monstersLeftText.x = -120; monstersLeftText.y = 20; // Show level up button if enough exp if (!gameOver && player.exp >= player.expToLevel) { levelUpBtn.visible = true; levelUpBtn.alpha = 1; } else { levelUpBtn.visible = false; } } // Returns true if (row, col) is inside grid function inBounds(row, col) { return row >= 0 && row < GRID_ROWS && col >= 0 && col < GRID_COLS; } // Get all adjacent tile positions function getAdjacent(row, col) { var adj = []; for (var dr = -1; dr <= 1; dr++) { for (var dc = -1; dc <= 1; dc++) { if (dr === 0 && dc === 0) continue; var nr = row + dr, nc = col + dc; if (inBounds(nr, nc)) adj.push([nr, nc]); } } return adj; } // Reveal empty tiles recursively (flood fill) function revealEmptyTiles(row, col) { var tile = grid[row][col]; if (tile.revealed) return; tile.reveal(); revealedTiles++; if (tile.adjacentMonsters === 0) { var adj = getAdjacent(row, col); for (var i = 0; i < adj.length; i++) { var _adj$i = _slicedToArray(adj[i], 2), nr = _adj$i[0], nc = _adj$i[1]; var t = grid[nr][nc]; if (t instanceof EmptyTile && !t.revealed) { revealEmptyTiles(nr, nc); } } } } // Reveal all monsters (on game over) function revealAllMonsters() { for (var i = 0; i < tileObjs.length; i++) { var t = tileObjs[i]; if (t instanceof MonsterTile && !t.revealed) { t.reveal(); } } } // --- Board Generation --- function generateBoard() { // Clear previous for (var i = 0; i < tileObjs.length; i++) { tileObjs[i].destroy(); } grid = []; tileObjs = []; monstersLeft = MONSTER_COUNT; revealedTiles = 0; totalSafeTiles = GRID_COLS * GRID_ROWS - MONSTER_COUNT; gameOver = false; // Place monsters var monsterPositions = []; while (monsterPositions.length < MONSTER_COUNT) { var r = Math.floor(Math.random() * GRID_ROWS); var c = Math.floor(Math.random() * GRID_COLS); var key = r + ',' + c; var found = false; for (var i = 0; i < monsterPositions.length; i++) { if (monsterPositions[i][0] === r && monsterPositions[i][1] === c) { found = true; break; } } if (!found) monsterPositions.push([r, c]); } // Build grid for (var row = 0; row < GRID_ROWS; row++) { grid[row] = []; for (var col = 0; col < GRID_COLS; col++) { var isMonster = false; for (var i = 0; i < monsterPositions.length; i++) { if (monsterPositions[i][0] === row && monsterPositions[i][1] === col) { isMonster = true; break; } } var tile; if (isMonster) { tile = new MonsterTile(); // Randomize monster stats a bit tile.maxHp = tile.hp = 1 + Math.floor(Math.random() * (1 + player.level)); tile.damage = 1 + Math.floor(Math.random() * (1 + Math.floor(player.level / 2))); tile.exp = 1 + Math.floor(Math.random() * 2); } else { tile = new EmptyTile(); } tile.x = GRID_OFFSET_X + col * TILE_SIZE + TILE_SIZE / 2; tile.y = GRID_OFFSET_Y + row * TILE_SIZE + TILE_SIZE / 2; game.addChild(tile); grid[row][col] = tile; tileObjs.push(tile); } } // Set adjacent monster counts for empty tiles for (var row = 0; row < GRID_ROWS; row++) { for (var col = 0; col < GRID_COLS; col++) { var tile = grid[row][col]; if (tile instanceof EmptyTile) { var adj = getAdjacent(row, col); var count = 0; for (var i = 0; i < adj.length; i++) { var _adj$i2 = _slicedToArray(adj[i], 2), nr = _adj$i2[0], nc = _adj$i2[1]; if (grid[nr][nc] instanceof MonsterTile) count++; } tile.adjacentMonsters = count; } } } } // --- Game Logic --- function handleTileDown(x, y, obj) { if (gameOver) return; // Find which tile was pressed for (var i = 0; i < tileObjs.length; i++) { var tile = tileObjs[i]; if (tile.revealed) continue; if (tile.cover && tile.cover.alpha > 0.1) { // Check if (x, y) is inside tile var dx = x - tile.x; var dy = y - tile.y; if (Math.abs(dx) < TILE_SIZE / 2 && Math.abs(dy) < TILE_SIZE / 2) { // Reveal tile if (tile instanceof EmptyTile) { revealEmptyTiles(Math.floor((tile.y - GRID_OFFSET_Y) / TILE_SIZE), Math.floor((tile.x - GRID_OFFSET_X) / TILE_SIZE)); updateGUI(); // Win check if (revealedTiles >= totalSafeTiles) { LK.showYouWin(); gameOver = true; revealAllMonsters(); } } else if (tile instanceof MonsterTile) { // Reveal monster and start battle tile.reveal(); // Player attacks first tile.hp -= player.damage; LK.effects.flashObject(tile.monster, 0xffe066, 300); // Monster always deals damage back if not already defeated if (!tile.defeated) { player.takeDamage(tile.damage); LK.effects.flashObject(tile.monster, 0xff0000, 300); LK.effects.flashObject(hpText, 0xff0000, 300); updateGUI(); if (player.hp <= 0) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); gameOver = true; revealAllMonsters(); return; } } if (tile.hp <= 0 && !tile.defeated) { tile.defeat(); monstersLeft--; player.gainExp(tile.exp); updateGUI(); // Win check if (monstersLeft <= 0) { LK.showYouWin(); gameOver = true; } } } break; } } } } // --- Level Up UI --- function showLevelUpChoices() { levelUpBtn.visible = false; for (var i = 0; i < levelUpChoiceBtns.length; i++) { var btn = levelUpChoiceBtns[i]; btn.visible = true; btn.x = 2048 / 2 + (i - 1) * 400; btn.y = -200; btn.alpha = 1; } } function hideLevelUpChoices() { for (var i = 0; i < levelUpChoiceBtns.length; i++) { levelUpChoiceBtns[i].visible = false; } } // --- Event Handlers --- game.down = function (x, y, obj) { // Level up choice? if (levelUpBtn.visible) { // Check if pressed on level up button var btnX = 2048 / 2, btnY = 2732 - 200; if (Math.abs(x - btnX) < 200 && Math.abs(y - btnY) < 80) { showLevelUpChoices(); return; } } // Level up choices for (var i = 0; i < levelUpChoiceBtns.length; i++) { var btn = levelUpChoiceBtns[i]; if (btn.visible) { var bx = 2048 / 2 + (i - 1) * 400; var by = 2732 - 400; if (Math.abs(x - bx) < 200 && Math.abs(y - by) < 80) { // Apply level up player.levelUp(levelUpChoices[i].value); hideLevelUpChoices(); updateGUI(); return; } } } // Otherwise, check tiles handleTileDown(x, y, obj); }; game.update = function () { // Animate level up button if (levelUpBtn.visible) { levelUpBtn.x = 2048 / 2; levelUpBtn.y = 2732 - 200; levelUpBtn.alpha = 0.8 + 0.2 * Math.sin(LK.ticks / 20); } // Animate level up choices for (var i = 0; i < levelUpChoiceBtns.length; i++) { var btn = levelUpChoiceBtns[i]; if (btn.visible) { btn.x = 2048 / 2 + (i - 1) * 400; btn.y = 2732 - 400; btn.alpha = 0.9 + 0.1 * Math.sin(LK.ticks / 15 + i); } } }; // --- Start Game --- generateBoard(); updateGUI();
===================================================================
--- original.js
+++ change.js
@@ -189,9 +189,9 @@
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
var GRID_COLS = 8;
-var GRID_ROWS = 10;
+var GRID_ROWS = 8;
var TILE_SIZE = 180;
var GRID_OFFSET_X = Math.floor((2048 - GRID_COLS * TILE_SIZE) / 2);
var GRID_OFFSET_Y = 300;
var MONSTER_COUNT = 12;