User prompt
perbaiki asset background tidak muncul
User prompt
tambah asset background jadi sembilan asset. background berubah rubah setiap permainan awal muncul
User prompt
musuh mati berputar putar saat ditembak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'var bgRock1 = gameContainer.addChild(LK.getAsset('bgRock1', {' Line Number: 490
User prompt
add 7 background asset
User prompt
buat swipe kearah target untuk menembak
User prompt
buat aturan tap hanya untuk berjalan
User prompt
rubah aturan. tap layar ke target untuk bergerak. swipe untuk menembak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
player bisa berbalik kekanan dan kiri
User prompt
player bisa bergerak kekanan dan kekiri juga ke atas dan bawa tanpa haru berputar
User prompt
bua animasi bulat merah meledak saat enemy mati ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
perbaiki untuk karakter orc yang bolak balik jangan tiba tiba menghilang
User prompt
buat animasi untuk orc yang menunggu terlihat seperi meloncat loncat ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
hilangkan bercak bercak pada background
User prompt
buat animasi ledakkan merah saat orc mati ditembak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make player control to swipe dan hold
User prompt
fix background music ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fix lag game play
User prompt
make background detailed and sharp
User prompt
add background
User prompt
player bisa berbalik ke kanan, bisa berbalik ke kiri, bisa berbalik ke atas, bisa berbalik ke bawah ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat musuh menyerang player berulang saat bertemu ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat peluru player menyebar tiga penjuru didepan ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
musuh mencoba mendekat saat melihat player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
player ada kemampuan auto target musub ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.direction = { x: 0, y: 0 }; self.lifetime = 0; self.maxLifetime = 120; // 2 seconds at 60fps self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; self.lifetime++; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFFFF }); self.speed = 1; self.health = 2; self.attackRange = 40; self.attackCooldown = 0; self.attackInterval = 60; // Attack every second at 60fps self.patrolDirection = Math.random() > 0.5 ? 1 : -1; // Random initial direction self.patrolAxis = Math.random() > 0.5 ? 'x' : 'y'; // Random patrol axis (horizontal or vertical) self.patrolDistance = CELL_SIZE * 3; // Patrol 3 cells distance self.startPosition = { x: 0, y: 0 }; // Will be set when enemy is placed self.isMoving = false; self.lastPlayerDistance = Infinity; self.startPatrol = function () { if (self.isMoving) return; self.isMoving = true; var targetX = self.x; var targetY = self.y; // Calculate target position based on patrol axis if (self.patrolAxis === 'x') { targetX = self.startPosition.x + self.patrolDirection * self.patrolDistance; } else { targetY = self.startPosition.y + self.patrolDirection * self.patrolDistance; } // Check if target position is valid if (canMoveTo(targetX, targetY)) { // Move to target position using tween tween(self, { x: targetX, y: targetY }, { duration: 2000, easing: tween.linear, onFinish: function onFinish() { self.isMoving = false; self.patrolDirection *= -1; // Reverse direction } }); } else { // If can't move in current direction, reverse immediately self.isMoving = false; self.patrolDirection *= -1; } }; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var detectionRange = CELL_SIZE * 4; // Enemy can see player from 4 cells away // Check if player is within detection range and line of sight var canSeePlayer = false; if (distance < detectionRange) { // Simple line of sight check - check if there are walls between enemy and player var steps = Math.ceil(distance / 20); var stepX = dx / steps; var stepY = dy / steps; canSeePlayer = true; for (var step = 1; step < steps; step++) { var checkX = self.x + stepX * step; var checkY = self.y + stepY * step; if (!canMoveTo(checkX, checkY)) { canSeePlayer = false; break; } } } // If can see player and not in attack range, move towards player if (canSeePlayer && distance > self.attackRange) { if (!self.isMoving) { self.isMoving = true; // Stop current patrol movement tween.stop(self); // Calculate next position towards player (one cell at a time) var moveDistance = CELL_SIZE; var normalizedDx = dx / distance; var normalizedDy = dy / distance; var targetX = self.x + normalizedDx * moveDistance; var targetY = self.y + normalizedDy * moveDistance; // Try to move towards player, prioritize the axis with larger distance if (Math.abs(dx) > Math.abs(dy)) { // Try horizontal movement first var horizontalTarget = self.x + (dx > 0 ? moveDistance : -moveDistance); if (canMoveTo(horizontalTarget, self.y)) { targetX = horizontalTarget; targetY = self.y; } else if (canMoveTo(self.x, self.y + (dy > 0 ? moveDistance : -moveDistance))) { // If horizontal blocked, try vertical targetX = self.x; targetY = self.y + (dy > 0 ? moveDistance : -moveDistance); } else { // Can't move towards player targetX = self.x; targetY = self.y; } } else { // Try vertical movement first var verticalTarget = self.y + (dy > 0 ? moveDistance : -moveDistance); if (canMoveTo(self.x, verticalTarget)) { targetX = self.x; targetY = verticalTarget; } else if (canMoveTo(self.x + (dx > 0 ? moveDistance : -moveDistance), self.y)) { // If vertical blocked, try horizontal targetX = self.x + (dx > 0 ? moveDistance : -moveDistance); targetY = self.y; } else { // Can't move towards player targetX = self.x; targetY = self.y; } } // Move towards calculated target if (targetX !== self.x || targetY !== self.y) { tween(self, { x: targetX, y: targetY }, { duration: 1000, easing: tween.linear, onFinish: function onFinish() { self.isMoving = false; } }); } else { self.isMoving = false; } } } else if (!canSeePlayer) { // Start patrol movement if not already moving and can't see player if (!self.isMoving) { self.startPatrol(); } } // Attack player if in range if (distance < self.attackRange) { // Stop patrolling when in attack range if (!self.lastPlayerDistance || self.lastPlayerDistance >= self.attackRange) { tween.stop(self); self.isMoving = false; } // Continuously attack while in range if (self.attackCooldown <= 0) { // Perform melee attack playerHealth--; LK.effects.flashObject(player, 0xFF0000, 500); // Visual attack feedback - enemy briefly grows and turns red tween(self, { tint: 0xFF0000, scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Return to normal appearance tween(self, { tint: 0xFFFFFF, scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); } }); // Reset attack cooldown self.attackCooldown = self.attackInterval; } } // Update attack cooldown if (self.attackCooldown > 0) { self.attackCooldown--; } self.lastPlayerDistance = distance; }; return self; }); var Ore = Container.expand(function () { var self = Container.call(this); var oreGraphics = self.attachAsset('ore', { anchorX: 0.5, anchorY: 0.5 }); self.value = 1; self.bobTimer = 0; self.baseY = self.y; self.update = function () { self.bobTimer++; self.y = self.baseY + Math.sin(self.bobTimer * 0.1) * 3; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2C1810 }); /**** * Game Code ****/ // Game constants var MAZE_WIDTH = 13; var MAZE_HEIGHT = 17; var CELL_SIZE = 80; var MAZE_OFFSET_X = (2048 - MAZE_WIDTH * CELL_SIZE) / 2; var MAZE_OFFSET_Y = 100; // Game variables var maze = []; var player; var enemies = []; var ores = []; var bullets = []; var playerHealth = 3; var oreCollected = 0; var oreTarget = 10; var level = 1; var exit; var gameContainer; // UI elements var healthText = new Text2('Health: 3', { size: 60, fill: 0xFF4444 }); healthText.anchor.set(0, 0); LK.gui.topLeft.addChild(healthText); var oreText = new Text2('Ore: 0/10', { size: 60, fill: 0xFFD700 }); oreText.anchor.set(0.5, 0); LK.gui.top.addChild(oreText); var levelText = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(1, 0); LK.gui.topRight.addChild(levelText); // Initialize maze array function initializeMaze() { maze = []; for (var y = 0; y < MAZE_HEIGHT; y++) { maze[y] = []; for (var x = 0; x < MAZE_WIDTH; x++) { maze[y][x] = 1; // 1 = wall, 0 = floor } } } // Simple maze generation using recursive backtracking function generateMaze() { initializeMaze(); var stack = []; var startX = 1; var startY = 1; maze[startY][startX] = 0; stack.push({ x: startX, y: startY }); while (stack.length > 0) { var current = stack[stack.length - 1]; var neighbors = []; // Check all four directions var directions = [{ x: 0, y: -2 }, { x: 2, y: 0 }, { x: 0, y: 2 }, { x: -2, y: 0 }]; for (var i = 0; i < directions.length; i++) { var nx = current.x + directions[i].x; var ny = current.y + directions[i].y; if (nx > 0 && nx < MAZE_WIDTH - 1 && ny > 0 && ny < MAZE_HEIGHT - 1 && maze[ny][nx] === 1) { neighbors.push({ x: nx, y: ny, dir: directions[i] }); } } if (neighbors.length > 0) { var chosen = neighbors[Math.floor(Math.random() * neighbors.length)]; // Remove wall between current and chosen maze[current.y + chosen.dir.y / 2][current.x + chosen.dir.x / 2] = 0; maze[chosen.y][chosen.x] = 0; stack.push(chosen); } else { stack.pop(); } } } // Create visual maze function createMazeVisual() { gameContainer = game.addChild(new Container()); for (var y = 0; y < MAZE_HEIGHT; y++) { for (var x = 0; x < MAZE_WIDTH; x++) { var cellX = MAZE_OFFSET_X + x * CELL_SIZE; var cellY = MAZE_OFFSET_Y + y * CELL_SIZE; if (maze[y][x] === 1) { // Wall var wall = LK.getAsset('wall', { x: cellX, y: cellY }); gameContainer.addChild(wall); } else { // Floor var floor = LK.getAsset('floor', { x: cellX, y: cellY }); gameContainer.addChild(floor); } } } } // Place ore in maze function placeOre() { var oreCount = oreTarget + Math.floor(level / 2); var placed = 0; while (placed < oreCount) { var x = Math.floor(Math.random() * MAZE_WIDTH); var y = Math.floor(Math.random() * MAZE_HEIGHT); if (maze[y][x] === 0 && (x !== 1 || y !== 1)) { var ore = gameContainer.addChild(new Ore()); ore.x = MAZE_OFFSET_X + x * CELL_SIZE + CELL_SIZE / 2; ore.y = MAZE_OFFSET_Y + y * CELL_SIZE + CELL_SIZE / 2; ore.baseY = ore.y; ores.push(ore); placed++; } } } // Place enemies in maze function placeEnemies() { var enemyCount = 3 + level; var placed = 0; while (placed < enemyCount) { var x = Math.floor(Math.random() * MAZE_WIDTH); var y = Math.floor(Math.random() * MAZE_HEIGHT); if (maze[y][x] === 0 && (x !== 1 || y !== 1) && Math.sqrt((x - 1) * (x - 1) + (y - 1) * (y - 1)) > 5) { var enemy = gameContainer.addChild(new Enemy()); enemy.x = MAZE_OFFSET_X + x * CELL_SIZE + CELL_SIZE / 2; enemy.y = MAZE_OFFSET_Y + y * CELL_SIZE + CELL_SIZE / 2; enemy.startPosition.x = enemy.x; enemy.startPosition.y = enemy.y; enemies.push(enemy); placed++; } } } // Place exit function placeExit() { // Find a position far from start var placed = false; while (!placed) { var x = Math.floor(Math.random() * MAZE_WIDTH); var y = Math.floor(Math.random() * MAZE_HEIGHT); if (maze[y][x] === 0 && Math.sqrt((x - 1) * (x - 1) + (y - 1) * (y - 1)) > 10) { exit = gameContainer.addChild(LK.getAsset('exit', { x: MAZE_OFFSET_X + x * CELL_SIZE, y: MAZE_OFFSET_Y + y * CELL_SIZE })); placed = true; } } } // Check if position is valid for movement function canMoveTo(x, y) { var mazeX = Math.floor((x - MAZE_OFFSET_X) / CELL_SIZE); var mazeY = Math.floor((y - MAZE_OFFSET_Y) / CELL_SIZE); if (mazeX < 0 || mazeX >= MAZE_WIDTH || mazeY < 0 || mazeY >= MAZE_HEIGHT) { return false; } return maze[mazeY][mazeX] === 0; } // Initialize level function initializeLevel() { // Clear existing game objects if (gameContainer) { gameContainer.destroy(); } enemies = []; ores = []; bullets = []; oreCollected = 0; // Generate new maze generateMaze(); createMazeVisual(); // Create player player = gameContainer.addChild(LK.getAsset('player', { anchorX: 0.5, anchorY: 0.5, x: MAZE_OFFSET_X + 1 * CELL_SIZE + CELL_SIZE / 2, y: MAZE_OFFSET_Y + 1 * CELL_SIZE + CELL_SIZE / 2 })); // Place game objects placeOre(); placeEnemies(); placeExit(); // Update UI updateUI(); } // Update UI function updateUI() { healthText.setText('Health: ' + playerHealth); oreText.setText('Ore: ' + oreCollected + '/' + oreTarget); levelText.setText('Level: ' + level); } // Shooting system var dragNode = null; var shootCooldown = 0; function shoot(targetX, targetY) { if (shootCooldown > 0) return; var dx = targetX - player.x; var dy = targetY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 50) return; // Don't shoot if too close // Calculate base direction var baseDirectionX = dx / distance; var baseDirectionY = dy / distance; // Create three bullets with spread angles var spreadAngles = [-0.3, 0, 0.3]; // Left, center, right (in radians, about 17 degrees each side) for (var i = 0; i < spreadAngles.length; i++) { var angle = Math.atan2(baseDirectionY, baseDirectionX) + spreadAngles[i]; var bullet = gameContainer.addChild(new Bullet()); bullet.x = player.x; bullet.y = player.y; bullet.direction.x = Math.cos(angle); bullet.direction.y = Math.sin(angle); bullets.push(bullet); } shootCooldown = 15; // Quarter second cooldown LK.getSound('shoot').play(); } // Main game loop game.update = function () { if (shootCooldown > 0) shootCooldown--; // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Check bullet lifetime if (bullet.lifetime >= bullet.maxLifetime) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check wall collision if (!canMoveTo(bullet.x, bullet.y)) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check enemy collision var hitEnemy = false; for (var j = enemies.length - 1; j >= 0; j--) { if (bullet.intersects(enemies[j])) { enemies[j].health--; LK.getSound('enemyHit').play(); if (enemies[j].health <= 0) { // Create explosion effect before destroying enemy tween(enemies[j], { scaleX: 2, scaleY: 2, alpha: 0, tint: 0xFF6600 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Enemy is destroyed after explosion animation } }); enemies[j].destroy(); enemies.splice(j, 1); } bullet.destroy(); bullets.splice(i, 1); hitEnemy = true; break; } } if (hitEnemy) continue; } // Check ore collection for (var i = ores.length - 1; i >= 0; i--) { if (player.intersects(ores[i])) { oreCollected++; LK.getSound('oreCollect').play(); ores[i].destroy(); ores.splice(i, 1); updateUI(); } } // Check exit condition if (exit && player.intersects(exit) && oreCollected >= oreTarget) { level++; oreTarget += 2; initializeLevel(); return; } // Check game over if (playerHealth <= 0) { LK.showGameOver(); return; } // Check win condition (survive 10 levels) if (level > 10) { LK.showYouWin(); return; } }; // Swipe-based movement system var swipeStart = { x: 0, y: 0 }; var swipeEnd = { x: 0, y: 0 }; var isTracking = false; var playerSpeed = 80; // Full cell movement var swipeThreshold = 50; // Minimum distance for swipe detection var lastMoveTime = 0; var moveDelay = 200; // Delay between moves in milliseconds var isPlayerMoving = false; game.down = function (x, y, obj) { swipeStart.x = x; swipeStart.y = y; isTracking = true; }; game.move = function (x, y, obj) { if (isTracking) { swipeEnd.x = x; swipeEnd.y = y; } }; game.up = function (x, y, obj) { if (!isTracking) return; isTracking = false; var dx = swipeEnd.x - swipeStart.x; var dy = swipeEnd.y - swipeStart.y; var swipeDistance = Math.sqrt(dx * dx + dy * dy); // Check if swipe is long enough if (swipeDistance < swipeThreshold) { // Short tap - shoot in that direction shoot(x, y); return; } // Prevent too frequent moves and simultaneous movements var currentTime = Date.now(); if (currentTime - lastMoveTime < moveDelay || isPlayerMoving) return; // Determine swipe direction var moveX = 0; var moveY = 0; if (Math.abs(dx) > Math.abs(dy)) { // Horizontal swipe moveX = dx > 0 ? playerSpeed : -playerSpeed; } else { // Vertical swipe moveY = dy > 0 ? playerSpeed : -playerSpeed; } // Calculate new position var newX = player.x + moveX; var newY = player.y + moveY; // Check if movement is valid and animate smoothly if (canMoveTo(newX, player.y) && Math.abs(moveX) > 0) { isPlayerMoving = true; tween(player, { x: newX }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { isPlayerMoving = false; } }); lastMoveTime = currentTime; } else if (canMoveTo(player.x, newY) && Math.abs(moveY) > 0) { isPlayerMoving = true; tween(player, { y: newY }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { isPlayerMoving = false; } }); lastMoveTime = currentTime; } }; // Initialize the first level initializeLevel();
===================================================================
--- original.js
+++ change.js
@@ -35,8 +35,10 @@
});
self.speed = 1;
self.health = 2;
self.attackRange = 40;
+ self.attackCooldown = 0;
+ self.attackInterval = 60; // Attack every second at 60fps
self.patrolDirection = Math.random() > 0.5 ? 1 : -1; // Random initial direction
self.patrolAxis = Math.random() > 0.5 ? 'x' : 'y'; // Random patrol axis (horizontal or vertical)
self.patrolDistance = CELL_SIZE * 3; // Patrol 3 cells distance
self.startPosition = {
@@ -165,10 +167,16 @@
}
}
// Attack player if in range
if (distance < self.attackRange) {
+ // Stop patrolling when in attack range
if (!self.lastPlayerDistance || self.lastPlayerDistance >= self.attackRange) {
- // Just entered attack range - perform melee attack
+ tween.stop(self);
+ self.isMoving = false;
+ }
+ // Continuously attack while in range
+ if (self.attackCooldown <= 0) {
+ // Perform melee attack
playerHealth--;
LK.effects.flashObject(player, 0xFF0000, 500);
// Visual attack feedback - enemy briefly grows and turns red
tween(self, {
@@ -189,13 +197,16 @@
easing: tween.easeOut
});
}
});
- // Stop patrolling when attacking
- tween.stop(self);
- self.isMoving = false;
+ // Reset attack cooldown
+ self.attackCooldown = self.attackInterval;
}
}
+ // Update attack cooldown
+ if (self.attackCooldown > 0) {
+ self.attackCooldown--;
+ }
self.lastPlayerDistance = distance;
};
return self;
});
2d sprites old dwarf hold shootgun. In-Game asset. 2d. High contrast. No shadows
2d chibi green evil underground fat ork. In-Game asset. 2d. High contrast. No shadows
2d golds ors brigh stone. In-Game asset. 2d. High contrast. No shadows
2d cave tunnel corridor. In-Game asset. 2d. High contrast. No shadows