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