User prompt
iskeletlerin yanına gidince kill butonu cıksın
User prompt
make a hitbox bigger
User prompt
When we approach the skeletons, our character dies immediately. The hitbox of the skeletons is very large.
User prompt
The hero is very strong, he must kill the skeletons with the kill button, not by running over them
User prompt
When the character takes damage, blood should flow ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
skeletons are very small
User prompt
Now the skeletons are very small and very strong
User prompt
eep the front of the sword towards the left
User prompt
add health bars to skeletons so they have hearts
User prompt
Instead of game over, it should say you couldn't pass the dungeon in dungeon style.
User prompt
add health bars to skeletons, have animations of taking damage with our swords for every damage we deal ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
not big
User prompt
make a bigger monster
User prompt
If our character passes through the door, he will be revived.
User prompt
enlarge skeletons
User prompt
make a good health bar
User prompt
ncrease your health bar a little bit and when we take damage our health goes down
User prompt
remove the health bar on top add a health bar on top of our character like a box without hearts
User prompt
When our character encounters a monster, all characters freeze for a moment and when the monster dies, the monsters continue walking again. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
delete treasure and trap
User prompt
make a bigger skeleton
User prompt
Let nothing happen where our character spawns
User prompt
The key will come out of the chest when all the skeletons die
User prompt
and when we kill all the skeletons, when we go to the chest, the open chest text will appear
User prompt
The key will come out of the chest after killing all the skeletons.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Chest class var Chest = Container.expand(function () { var self = Container.call(this); // Attach chest asset (brown box) var chestSprite = self.attachAsset('chest', { anchorX: 0.5, anchorY: 0.5 }); self.width = chestSprite.width; self.height = chestSprite.height; self.opened = false; return self; }); // Door class (for next room) var Door = Container.expand(function () { var self = Container.call(this); // Attach door asset (purple box) var doorSprite = self.attachAsset('door', { anchorX: 0.5, anchorY: 0.5 }); self.width = doorSprite.width; self.height = doorSprite.height; return self; }); // Hero class var Hero = Container.expand(function () { var self = Container.call(this); // Attach hero asset (red box) var heroSprite = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.width = heroSprite.width; self.height = heroSprite.height; // Attach sword to hero var swordSprite = self.attachAsset('sword', { anchorX: 0.5, anchorY: 0.5 }); swordSprite.x = heroSprite.width * 0.3; // Position sword to the right of hero swordSprite.y = 0; // Center vertically with hero swordSprite.rotation = Math.PI / 4; // Angle the sword slightly // Hero stats self.maxHealth = 3; self.health = self.maxHealth; self.invincible = false; self.invincibleTimer = 0; // Flash when hit self.flash = function () { tween(heroSprite, { tint: 0xffffff }, { duration: 100, onFinish: function onFinish() { tween(heroSprite, { tint: 0xd83318 }, { duration: 200 }); } }); }; // Take damage self.takeDamage = function () { if (self.invincible) return; self.health -= 1; self.flash(); self.invincible = true; self.invincibleTimer = 60; // 1 second at 60fps LK.effects.flashObject(self, 0xff0000, 300); updateHealthDisplay(); if (self.health <= 0) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); } }; // Heal self.heal = function () { if (self.health < self.maxHealth) { self.health += 1; updateHealthDisplay(); LK.effects.flashObject(self, 0x83de44, 300); } }; // Called every tick self.update = function () { if (self.invincible) { self.invincibleTimer--; if (self.invincibleTimer <= 0) { self.invincible = false; } } }; return self; }); /**** * Asset Initialization ****/ // Hero: red box // Monster: green ellipse // Trap: yellow box // Treasure: blue ellipse // Door: purple box // Key class var Key = Container.expand(function () { var self = Container.call(this); // Attach key asset (gold ellipse) var keySprite = self.attachAsset('key', { anchorX: 0.5, anchorY: 0.5 }); self.width = keySprite.width; self.height = keySprite.height; return self; }); // Monster class var Monster = Container.expand(function () { var self = Container.call(this); // Attach monster asset (green ellipse) var monsterSprite = self.attachAsset('monster', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); // Set much smaller hitbox for more accurate collision detection self.width = monsterSprite.width * 0.3; self.height = monsterSprite.height * 0.3; // Movement direction self.vx = 0; self.vy = 0; self.speed = 1 + Math.random() * 1; // Set random direction self.setRandomDirection = function () { var angle = Math.random() * Math.PI * 2; self.vx = Math.cos(angle) * self.speed; self.vy = Math.sin(angle) * self.speed; }; self.setRandomDirection(); // Called every tick self.update = function () { // Check if hero is close to this monster (within encounter distance) var dx = hero.x - self.x; var dy = hero.y - self.y; var distToHero = Math.sqrt(dx * dx + dy * dy); // If hero is within encounter distance, stop moving if (distToHero < 200) { // Monster stays still when encountering hero return; } self.x += self.vx; self.y += self.vy; // Bounce off room walls if (self.x < roomBounds.x + self.width / 2) { self.x = roomBounds.x + self.width / 2; self.vx *= -1; } if (self.x > roomBounds.x + roomBounds.width - self.width / 2) { self.x = roomBounds.x + roomBounds.width - self.width / 2; self.vx *= -1; } if (self.y < roomBounds.y + self.height / 2) { self.y = roomBounds.y + self.height / 2; self.vy *= -1; } if (self.y > roomBounds.y + roomBounds.height - self.height / 2) { self.y = roomBounds.y + roomBounds.height - self.height / 2; self.vy *= -1; } }; return self; }); // Trap class var Trap = Container.expand(function () { var self = Container.call(this); // Attach trap asset (yellow box) var trapSprite = self.attachAsset('trap', { anchorX: 0.5, anchorY: 0.5 }); self.width = trapSprite.width; self.height = trapSprite.height; return self; }); // Treasure class var Treasure = Container.expand(function () { var self = Container.call(this); // Attach treasure asset (blue ellipse) var treasureSprite = self.attachAsset('treasure', { anchorX: 0.5, anchorY: 0.5 }); self.width = treasureSprite.width; self.height = treasureSprite.height; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Tween plugin for animations // --- Start Screen Overlay --- var startScreenOverlay = new Container(); startScreenOverlay.zIndex = 10000; // ensure on top // Title var titleText = new Text2("Dungeon Dash", { size: 180, fill: "#fff", font: "Impact, Arial Black, Tahoma" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 900; startScreenOverlay.addChild(titleText); // Subtitle var subtitleText = new Text2("Drag or tap to move. Collect treasures. Avoid monsters & traps!", { size: 70, fill: 0xB8B031 }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 2048 / 2; subtitleText.y = 1100; startScreenOverlay.addChild(subtitleText); // Play Button var playBtnWidth = 600; var playBtnHeight = 180; var playBtn = LK.getAsset('door', { width: playBtnWidth, height: playBtnHeight, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1500 }); startScreenOverlay.addChild(playBtn); var playBtnText = new Text2("PLAY", { size: 120, fill: "#fff", font: "Impact, Arial Black, Tahoma" }); playBtnText.anchor.set(0.5, 0.5); playBtnText.x = 2048 / 2; playBtnText.y = 1500; startScreenOverlay.addChild(playBtnText); // Add overlay to game game.addChild(startScreenOverlay); // Block game input until started var gameStarted = false; // Start game handler function startGame() { if (gameStarted) return; gameStarted = true; startScreenOverlay.visible = false; } // Listen for tap/click on play button startScreenOverlay.down = function (x, y, obj) { // Check if tap is inside play button var local = playBtn.toLocal(startScreenOverlay.toGlobal({ x: x, y: y })); if (local.x > -playBtnWidth / 2 && local.x < playBtnWidth / 2 && local.y > -playBtnHeight / 2 && local.y < playBtnHeight / 2) { startGame(); } }; // Intercept all input until game started var oldGameDown = game.down; game.down = function (x, y, obj) { if (!gameStarted) { if (typeof startScreenOverlay.down === "function") startScreenOverlay.down(x, y, obj); return; } if (typeof oldGameDown === "function") oldGameDown(x, y, obj); }; var oldGameMove = game.move; game.move = function (x, y, obj) { if (!gameStarted) return; if (typeof oldGameMove === "function") oldGameMove(x, y, obj); }; var oldGameUp = game.up; game.up = function (x, y, obj) { if (!gameStarted) return; if (typeof oldGameUp === "function") oldGameUp(x, y, obj); }; // Room bounds (centered, with margin) var roomMargin = 120; var roomBounds = { x: roomMargin, y: roomMargin + 100, // leave top 100px for menu width: 2048 - roomMargin * 2, height: 2732 - roomMargin * 2 - 100 }; // Game state var hero; var monsters = []; var traps = []; var treasures = []; var door; var keys = []; var chests = []; var hasKey = false; var draggingHero = false; var lastMoveX = 0, lastMoveY = 0; var currentRoom = 1; var maxRooms = 5; var treasuresCollected = 0; var monstersDefeated = 0; var roomCleared = false; // GUI elements var scoreTxt = new Text2('Score: 0', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var healthTxt = new Text2('♥♥♥', { size: 90, fill: 0xFF4444 }); healthTxt.anchor.set(0.5, 0); LK.gui.top.addChild(healthTxt); healthTxt.y = 100; // Helper to update health display function updateHealthDisplay() { var hearts = ''; for (var i = 0; i < hero.maxHealth; i++) { hearts += i < hero.health ? '♥' : '♡'; } healthTxt.setText(hearts); } // Helper to update score display function updateScoreDisplay() { var score = treasuresCollected * 10 + monstersDefeated * 5; scoreTxt.setText('Score: ' + score); } // Helper to clear room function clearRoom() { for (var i = 0; i < monsters.length; i++) monsters[i].destroy(); for (var i = 0; i < traps.length; i++) traps[i].destroy(); for (var i = 0; i < treasures.length; i++) treasures[i].destroy(); for (var i = 0; i < keys.length; i++) keys[i].destroy(); for (var i = 0; i < chests.length; i++) chests[i].destroy(); monsters = []; traps = []; treasures = []; keys = []; chests = []; if (door) { door.destroy(); door = null; } roomCleared = false; hasKey = false; } // Helper to generate a room function generateRoom(roomNum) { clearRoom(); // Place hero at entrance (bottom center) hero.x = roomBounds.x + roomBounds.width / 2; hero.y = roomBounds.y + roomBounds.height - hero.height; // Helper function to check if position is safe from hero spawn area function isPositionSafeFromHeroSpawn(x, y, heroStartX, heroStartY, safeDistance) { var dx = x - heroStartX; var dy = y - heroStartY; var dist = Math.sqrt(dx * dx + dy * dy); return dist > safeDistance; } // Place monsters var monsterCount = 2 + roomNum; var heroStartX = roomBounds.x + roomBounds.width / 2; var heroStartY = roomBounds.y + roomBounds.height - hero.height; var heroSafeDistance = 400; // Increased safe distance around hero spawn for (var i = 0; i < monsterCount; i++) { var m = new Monster(); var validPosition = false; var attempts = 0; // Try to find a position that's not too close to hero spawn while (!validPosition && attempts < 50) { m.x = roomBounds.x + 100 + Math.random() * (roomBounds.width - 200); m.y = roomBounds.y + 200 + Math.random() * (roomBounds.height - 400); if (isPositionSafeFromHeroSpawn(m.x, m.y, heroStartX, heroStartY, heroSafeDistance)) { validPosition = true; } attempts++; } monsters.push(m); game.addChild(m); } // Place traps var trapCount = 1 + Math.floor(roomNum / 2); for (var i = 0; i < trapCount; i++) { var t = new Trap(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { t.x = roomBounds.x + 100 + Math.random() * (roomBounds.width - 200); t.y = roomBounds.y + 200 + Math.random() * (roomBounds.height - 400); if (isPositionSafeFromHeroSpawn(t.x, t.y, heroStartX, heroStartY, heroSafeDistance)) { validPosition = true; } attempts++; } traps.push(t); game.addChild(t); } // Place treasures var treasureCount = 1 + Math.floor(roomNum / 2); for (var i = 0; i < treasureCount; i++) { var tr = new Treasure(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { tr.x = roomBounds.x + 100 + Math.random() * (roomBounds.width - 200); tr.y = roomBounds.y + 200 + Math.random() * (roomBounds.height - 400); if (isPositionSafeFromHeroSpawn(tr.x, tr.y, heroStartX, heroStartY, heroSafeDistance)) { validPosition = true; } attempts++; } treasures.push(tr); game.addChild(tr); } // Key will come from chest after killing all monsters, so don't place it randomly // Place chest (always one per room) var c = new Chest(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { c.x = roomBounds.x + 100 + Math.random() * (roomBounds.width - 200); c.y = roomBounds.y + 200 + Math.random() * (roomBounds.height - 400); if (isPositionSafeFromHeroSpawn(c.x, c.y, heroStartX, heroStartY, heroSafeDistance)) { validPosition = true; } attempts++; } chests.push(c); game.addChild(c); // Place door (top center) door = new Door(); door.x = roomBounds.x + roomBounds.width / 2; door.y = roomBounds.y + door.height / 2; game.addChild(door); door.visible = false; // Only show when room is cleared roomCleared = false; } // Create hero hero = new Hero(); game.addChild(hero); updateHealthDisplay(); // Start first room generateRoom(currentRoom); updateScoreDisplay(); // Dragging logic game.down = function (x, y, obj) { // Only start drag if touch is on hero var local = hero.toLocal(game.toGlobal({ x: x, y: y })); if (local.x > -hero.width / 2 && local.x < hero.width / 2 && local.y > -hero.height / 2 && local.y < hero.height / 2) { draggingHero = true; lastMoveX = x; lastMoveY = y; } }; game.up = function (x, y, obj) { draggingHero = false; }; function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } // Walk-to destination variables var walkToActive = false; var walkToX = 0; var walkToY = 0; var walkToSpeed = 22; // Kill button for attacking monsters var killButton = LK.getAsset('trap', { width: 200, height: 200, anchorX: 0.5, anchorY: 0.5, x: 2048 - 150, y: 2732 - 150 }); game.addChild(killButton); var killButtonText = new Text2("KILL", { size: 60, fill: "#fff", font: "Impact, Arial Black, Tahoma" }); killButtonText.anchor.set(0.5, 0.5); killButtonText.x = 2048 - 150; killButtonText.y = 2732 - 150; game.addChild(killButtonText); // Open chest text var openChestText = new Text2("OPEN CHEST", { size: 80, fill: 0xFFD700, font: "Impact, Arial Black, Tahoma" }); openChestText.anchor.set(0.5, 0.5); openChestText.x = 2048 / 2; openChestText.y = 2732 - 200; openChestText.visible = false; game.addChild(openChestText); // Sword swing state management var swordSwinging = false; var swordCooldown = 0; var SWORD_COOLDOWN_TIME = 30; // frames (0.5 seconds at 60fps) // Move handler game.move = function (x, y, obj) { if (draggingHero) { // Clamp hero inside room bounds var hx = clamp(x, roomBounds.x + hero.width / 2, roomBounds.x + roomBounds.width - hero.width / 2); var hy = clamp(y, roomBounds.y + hero.height / 2, roomBounds.y + roomBounds.height - hero.height / 2); hero.x = hx; hero.y = hy; walkToActive = false; // Cancel walk-to if dragging } }; // Tap-to-walk logic: on down, if not on hero, set walk-to destination var oldGameDown = game.down; game.down = function (x, y, obj) { // Only start drag if touch is on hero var local = hero.toLocal(game.toGlobal({ x: x, y: y })); // Check if kill button was tapped var killButtonLocal = killButton.toLocal(game.toGlobal({ x: x, y: y })); if (killButtonLocal.x > -killButton.width / 2 && killButtonLocal.x < killButton.width / 2 && killButtonLocal.y > -killButton.height / 2 && killButtonLocal.y < killButton.height / 2) { // Check if sword is available (not swinging and cooldown expired) if (!swordSwinging && swordCooldown <= 0) { // Get sword sprite from hero for animation var swordSprite = hero.children[1]; // Sword is the second child (index 1) // Stop any existing tweens on the sword tween.stop(swordSprite, { rotation: true }); // Set swinging state swordSwinging = true; swordCooldown = SWORD_COOLDOWN_TIME; // Create sword swing effect var originalRotation = swordSprite.rotation; tween(swordSprite, { rotation: originalRotation + Math.PI / 2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(swordSprite, { rotation: originalRotation }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { swordSwinging = false; } }); } }); // Kill button tapped - damage all monsters within 350px of hero for (var i = monsters.length - 1; i >= 0; i--) { var m = monsters[i]; var dx = hero.x - m.x; var dy = hero.y - m.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 350) { // Remove monster m.destroy(); monsters.splice(i, 1); monstersDefeated++; updateScoreDisplay(); // Optional: flash monster or hero for feedback LK.effects.flashObject(hero, 0xffffff, 120); } } } return; // Don't process other touch logic } if (local.x > -hero.width / 2 && local.x < hero.width / 2 && local.y > -hero.height / 2 && local.y < hero.height / 2) { draggingHero = true; lastMoveX = x; lastMoveY = y; walkToActive = false; } else { // Set walk-to destination if tap is inside room var hx = clamp(x, roomBounds.x + hero.width / 2, roomBounds.x + roomBounds.width - hero.width / 2); var hy = clamp(y, roomBounds.y + hero.height / 2, roomBounds.y + roomBounds.height - hero.height / 2); walkToX = hx; walkToY = hy; walkToActive = true; } if (typeof oldGameDown === "function") oldGameDown(x, y, obj); }; // In update, move hero toward walk-to destination if active var oldGameUpdate = game.update; game.update = function () { // Walk-to logic if (walkToActive && !draggingHero) { var dx = walkToX - hero.x; var dy = walkToY - hero.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > walkToSpeed) { hero.x += dx / dist * walkToSpeed; hero.y += dy / dist * walkToSpeed; } else { hero.x = walkToX; hero.y = walkToY; walkToActive = false; } } if (typeof oldGameUpdate === "function") oldGameUpdate(); }; // Main update loop game.update = function () { if (!gameStarted) return; // Update sword cooldown if (swordCooldown > 0) { swordCooldown--; } // Update hero hero.update(); // Update monsters for (var i = 0; i < monsters.length; i++) { monsters[i].update(); } // Check if hero is close to any monster to show/hide kill button var nearMonster = false; for (var i = 0; i < monsters.length; i++) { var m = monsters[i]; var dx = hero.x - m.x; var dy = hero.y - m.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 350) { nearMonster = true; break; } } // Show/hide kill button based on proximity killButton.visible = nearMonster; killButtonText.visible = nearMonster; // Check if hero is close to chest and all monsters are defeated var nearChest = false; if (monsters.length === 0) { for (var i = 0; i < chests.length; i++) { var c = chests[i]; if (!c.opened) { var dx = hero.x - c.x; var dy = hero.y - c.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 200) { nearChest = true; break; } } } } // Show/hide open chest text based on proximity and game state openChestText.visible = nearChest; // Check collisions: hero vs monsters for (var i = monsters.length - 1; i >= 0; i--) { var m = monsters[i]; if (hero.intersects(m)) { hero.takeDamage(); // Knockback var dx = hero.x - m.x; var dy = hero.y - m.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; hero.x += dx / dist * 60; hero.y += dy / dist * 60; // Remove monster m.destroy(); monsters.splice(i, 1); monstersDefeated++; updateScoreDisplay(); } } // Check collisions: hero vs traps for (var i = 0; i < traps.length; i++) { var t = traps[i]; if (hero.intersects(t)) { hero.takeDamage(); // Move hero away from trap var dx = hero.x - t.x; var dy = hero.y - t.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; hero.x += dx / dist * 40; hero.y += dy / dist * 40; } } // Check collisions: hero vs treasures for (var i = treasures.length - 1; i >= 0; i--) { var tr = treasures[i]; if (hero.intersects(tr)) { tr.destroy(); treasures.splice(i, 1); treasuresCollected++; updateScoreDisplay(); hero.heal(); } } // Check collisions: hero vs keys for (var i = keys.length - 1; i >= 0; i--) { var k = keys[i]; if (hero.intersects(k)) { k.destroy(); keys.splice(i, 1); hasKey = true; LK.effects.flashObject(hero, 0xFFD700, 300); } } // Check collisions: hero vs chests for (var i = 0; i < chests.length; i++) { var c = chests[i]; if (hero.intersects(c) && monsters.length === 0 && !c.opened) { c.opened = true; LK.effects.flashObject(c, 0x83de44, 600); // Add treasure from chest treasuresCollected += 2; updateScoreDisplay(); // Spawn key from chest after all monsters are defeated var k = new Key(); k.x = c.x; k.y = c.y; keys.push(k); game.addChild(k); } } // Room clear check - need to defeat all monsters first, then open chest, then collect key if (!roomCleared && monsters.length === 0 && chests.length > 0 && chests[0].opened && hasKey) { roomCleared = true; door.visible = true; LK.effects.flashObject(door, 0x83de44, 600); } // Check hero at door to next room if (roomCleared && door && hero.intersects(door)) { if (currentRoom < maxRooms) { currentRoom++; generateRoom(currentRoom); } else { // Win! LK.setScore(treasuresCollected * 10 + monstersDefeated * 5); LK.showYouWin(); } } };
===================================================================
--- original.js
+++ change.js
@@ -127,9 +127,11 @@
var self = Container.call(this);
// Attach monster asset (green ellipse)
var monsterSprite = self.attachAsset('monster', {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 0.5,
+ scaleX: 1.5,
+ scaleY: 1.5
});
// Set much smaller hitbox for more accurate collision detection
self.width = monsterSprite.width * 0.3;
self.height = monsterSprite.height * 0.3;
dungeon door. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
png
dungeon hero sword. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
dungeon key. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
dungeon chest. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
dungeon demon. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
dungeon wizard. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a mage who throws fireballs. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
big dungeon snake. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a spider. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat