User prompt
place floor should not be the same as the game menu
User prompt
add a menu to the game and have a menu suitable for this character
User prompt
the writings should not overlap each other but all the writings should be side by side
User prompt
show how many enemies we need to capture for the next wave and how many waves we are in.
User prompt
make the background and floor like a Turkish palace
User prompt
draw me pictures of characters, swords and enemies
User prompt
when the character attacks, hit everywhere within an area
User prompt
when pressed on the right side of the screen it will attack, when pressed on the left side I can move the character left and right, up and down
User prompt
have different rounds in the game and increase the number of enemies in each round, as well as a shop system and random power-ups with different features that we will add to the sword at the end of each round DeepL ile çevrildi https://www.deepl.com/app/?utm_source=android&utm_medium=app&utm_campaign=share-translation
Code edit (1 edits merged)
Please save this source code
User prompt
Blade Rush: Endless Slash
Initial prompt
I want a pixel art mobile game with a camera angle where you look from above in a 2d unlimited area and many enemies are constantly coming wave after wave and we only cut them with a sword.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); // Enemy body (red ellipse) var enemyBody = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); // Enemy eyes (black ellipses) var eyeLeft = self.attachAsset('enemy_eye', { anchorX: 0.5, anchorY: 0.5, x: -18, y: -10 }); var eyeRight = self.attachAsset('enemy_eye', { anchorX: 0.5, anchorY: 0.5, x: 18, y: -10 }); self.speed = 4 + Math.random() * 2; // base speed, will be set on spawn self.dir = 0; // direction in radians, will be set on spawn // For hit flash self.isHit = false; self.hitTicks = 0; self.update = function () { // Move towards direction self.x += Math.cos(self.dir) * self.speed; self.y += Math.sin(self.dir) * self.speed; // Hit flash if (self.isHit) { self.hitTicks--; if (self.hitTicks <= 0) { enemyBody.tint = 0xe74c3c; self.isHit = false; } } }; self.flashHit = function () { self.isHit = true; self.hitTicks = 6; enemyBody.tint = 0xffffff; }; return self; }); // Hero class var Hero = Container.expand(function () { var self = Container.call(this); // Hero body (blue box) var heroBody = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); // Hero face (white ellipse) var heroFace = self.attachAsset('hero_face', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -10 }); // Hero hair (brown box) var heroHair = self.attachAsset('hero_hair', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -36 }); // Sword blade (yellow) var swordBlade = self.attachAsset('sword_blade', { anchorX: 0.0, anchorY: 0.5, x: 60, y: 0 }); // Sword handle (brown) var swordHandle = self.attachAsset('sword_handle', { anchorX: 0.0, anchorY: 0.5, x: 48, y: 0 }); swordBlade.rotation = 0; swordHandle.rotation = 0; swordBlade.visible = false; swordHandle.visible = false; // Slash effect (white ellipse) var slash = self.attachAsset('slash', { anchorX: 0.0, anchorY: 0.5, x: 80, y: 0 }); slash.alpha = 0; slash.visible = false; // State self.sword = swordBlade; self.swordHandle = swordHandle; self.slash = slash; self.slashCooldown = 0; // ticks until next slash allowed self.slashActive = false; self.slashDir = 0; // radians, direction of last slash // Slash method self.doSlash = function (dir) { if (self.slashCooldown > 0) return false; self.slashCooldown = 18; // 0.3s at 60fps self.slashActive = true; self.slashDir = dir; // Sword swing animation self.sword.visible = true; self.swordHandle.visible = true; self.sword.rotation = dir - Math.PI / 2 - 0.5; self.swordHandle.rotation = dir - Math.PI / 2 - 0.5; tween(self.sword, { rotation: dir - Math.PI / 2 + 0.5 }, { duration: 120, easing: tween.cubicOut, onFinish: function onFinish() { self.sword.visible = false; self.swordHandle.visible = false; } }); tween(self.swordHandle, { rotation: dir - Math.PI / 2 + 0.5 }, { duration: 120, easing: tween.cubicOut }); // Slash effect self.slash.visible = true; self.slash.rotation = dir - Math.PI / 2; self.slash.alpha = 0.7; tween(self.slash, { alpha: 0 }, { duration: 180, easing: tween.linear, onFinish: function onFinish() { self.slash.visible = false; } }); // Play swing sound LK.getSound('swing').play(); return true; }; // Update self.update = function () { if (self.slashCooldown > 0) { self.slashCooldown--; if (self.slashCooldown === 0) { self.slashActive = false; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Palace floor image for Turkish palace background (replace id with actual palace floor tile image asset) // Sounds // Enemy: red ellipse with black eyes (pixel art style) // Slash: white ellipse (pixel art style) // Sword: yellow blade, brown handle (pixel art style) // Hero: blue box with white face and brown hair (pixel art style) // Game constants // Hero: blue box, 120x120 // Sword: yellow box, 80x24 // Enemy: red ellipse, 100x100 // Slash effect: white ellipse, 90x40 // Sound: enemy hit // Sound: sword swing // --- MENU UI --- var menuGroup = new Container(); game.addChild(menuGroup); // Palace floor background for menu var palaceFloor = LK.getAsset('palace_floor', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); menuGroup.addChild(palaceFloor); // Palace floor background for game arena (separate from menu) var arenaFloor = LK.getAsset('palace_floor', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChildAt(arenaFloor, 0); // Always behind hero/enemies arenaFloor.visible = false; // Hero pixel art for menu (centered, larger) var menuHero = LK.getAsset('hero', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 900, width: 220, height: 220 }); menuGroup.addChild(menuHero); // Sword pixel art for menu (angled, next to hero) var menuSword = LK.getAsset('sword_blade', { anchorX: 0.1, anchorY: 0.5, x: 2048 / 2 + 120, y: 900, width: 140, height: 28, rotation: -0.3 }); menuGroup.addChild(menuSword); // Game title in Turkish palace style var menuTitle = new Text2("Palace Arena", { size: 160, fill: 0xE6C200, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); menuTitle.anchor.set(0.5, 0.5); menuTitle.x = 2048 / 2; menuTitle.y = 350; menuGroup.addChild(menuTitle); // Subtitle var menuSubtitle = new Text2("Endless Sword Survival", { size: 70, fill: "#fff" }); menuSubtitle.anchor.set(0.5, 0.5); menuSubtitle.x = 2048 / 2; menuSubtitle.y = 500; menuGroup.addChild(menuSubtitle); // Start button var startBtn = new Text2("Start", { size: 120, fill: "#0f0" }); startBtn.anchor.set(0.5, 0.5); startBtn.x = 2048 / 2; startBtn.y = 1300; startBtn.interactive = true; startBtn.buttonMode = true; menuGroup.addChild(startBtn); // Hide menu and start game function startGameFromMenu() { menuGroup.visible = false; gameStarted = true; } startBtn.down = function (x, y, obj) { startGameFromMenu(); }; // Prevent game from running until menu is dismissed var gameStarted = false; var ARENA_MARGIN = 60; // px, keep enemies from spawning too close to edge var HERO_START_X = 2048 / 2; var HERO_START_Y = 2732 / 2; var HERO_SPEED = 18; // px per move var ENEMY_SPAWN_INTERVAL = 60; // ticks (1s) var ENEMY_MIN_DIST = 220; // min distance from hero to spawn var ENEMY_MAX_BASE = 8; // base max enemies per round var ENEMY_MAX = ENEMY_MAX_BASE; // will increase per round // Game state var hero = new Hero(); game.addChild(hero); hero.x = HERO_START_X; hero.y = HERO_START_Y; var enemies = []; var score = 0; var wave = 1; var roundKills = 0; // kills in current round var roundActive = true; // is round ongoing var ticksSinceSpawn = 0; var isDragging = false; var dragOffsetX = 0; var dragOffsetY = 0; var lastTouchX = hero.x; var lastTouchY = hero.y; // Shop/Power-up system state var shopActive = false; var availablePowerups = []; var selectedPowerup = null; // Power-up definitions (add more as needed) var POWERUPS = [{ id: "longer_sword", name: "Longer Sword", desc: "Sword range +30%", apply: function apply() { hero.sword.width *= 1.3; } }, { id: "faster_slash", name: "Faster Slash", desc: "Slash cooldown -20%", apply: function apply() { hero.slashCooldown = Math.max(1, Math.floor(hero.slashCooldown * 0.8)); } }, { id: "move_speed", name: "Move Speed Up", desc: "Hero moves faster", apply: function apply() { HERO_SPEED += 3; } }]; // Score text var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); // Score text (left side) scoreTxt.anchor.set(0, 0); scoreTxt.x = 120; scoreTxt.y = 0; LK.gui.top.addChild(scoreTxt); // Round text (center) var roundTxt = new Text2('Round 1', { size: 80, fill: "#ff0" }); roundTxt.anchor.set(0.5, 0); roundTxt.x = 2048 / 2; roundTxt.y = 0; LK.gui.top.addChild(roundTxt); // Enemies left text (right side) var enemiesLeftTxt = new Text2('', { size: 70, fill: "#fff" }); enemiesLeftTxt.anchor.set(1, 0); enemiesLeftTxt.x = 2048 - 120; enemiesLeftTxt.y = 0; LK.gui.top.addChild(enemiesLeftTxt); // Shop/Power-up UI var shopTxt = null; var powerupBtns = []; // Show shop and power-up selection at end of round function showShop() { // Update round text roundTxt.setText("Round " + wave + " Complete!"); // Pick 2 random powerups availablePowerups = []; var pool = POWERUPS.slice(); for (var i = 0; i < 2; i++) { if (pool.length === 0) break; var idx = Math.floor(Math.random() * pool.length); availablePowerups.push(pool[idx]); pool.splice(idx, 1); } // Show shop text if (!shopTxt) { shopTxt = new Text2("Choose a Power-Up!", { size: 90, fill: "#fff" }); shopTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(shopTxt); } shopTxt.setText("Choose a Power-Up!"); shopTxt.visible = true; // Show powerup buttons for (var b = 0; b < powerupBtns.length; b++) { LK.gui.center.removeChild(powerupBtns[b]); } powerupBtns = []; for (var i = 0; i < availablePowerups.length; i++) { (function (i) { var p = availablePowerups[i]; var btn = new Text2(p.name + "\n" + p.desc, { size: 70, fill: "#0f0" }); btn.anchor.set(0.5, 0.5); btn.x = 0; btn.y = 180 + i * 220; btn.interactive = true; btn.buttonMode = true; btn.down = function (x, y, obj) { selectPowerup(i); }; LK.gui.center.addChild(btn); powerupBtns.push(btn); })(i); } } // Handle power-up selection function selectPowerup(idx) { var p = availablePowerups[idx]; if (!p) return; // Apply powerup effect if (typeof p.apply === "function") p.apply(); // Hide shop UI if (shopTxt) shopTxt.visible = false; for (var b = 0; b < powerupBtns.length; b++) { LK.gui.center.removeChild(powerupBtns[b]); } powerupBtns = []; // Start next round wave++; ENEMY_MAX = ENEMY_MAX_BASE + (wave - 1) * 4; roundKills = 0; roundActive = true; shopActive = false; roundTxt.setText("Round " + wave); } // Helper: spawn enemy at random edge, moving toward hero function spawnEnemy() { // Pick random edge: 0=top,1=bottom,2=left,3=right var edge = Math.floor(Math.random() * 4); var ex, ey; if (edge === 0) { // top ex = ARENA_MARGIN + Math.random() * (2048 - 2 * ARENA_MARGIN); ey = ARENA_MARGIN; } else if (edge === 1) { // bottom ex = ARENA_MARGIN + Math.random() * (2048 - 2 * ARENA_MARGIN); ey = 2732 - ARENA_MARGIN; } else if (edge === 2) { // left ex = ARENA_MARGIN; ey = ARENA_MARGIN + Math.random() * (2732 - 2 * ARENA_MARGIN); } else { // right ex = 2048 - ARENA_MARGIN; ey = ARENA_MARGIN + Math.random() * (2732 - 2 * ARENA_MARGIN); } // Don't spawn too close to hero var dx = ex - hero.x, dy = ey - hero.y; if (Math.sqrt(dx * dx + dy * dy) < ENEMY_MIN_DIST) { // Try again return; } var enemy = new Enemy(); enemy.x = ex; enemy.y = ey; // Direction toward hero var dir = Math.atan2(hero.y - ey, hero.x - ex); enemy.dir = dir; // Speed increases with wave enemy.speed = 3.5 + Math.random() * 1.5 + (wave - 1) * 0.25; enemies.push(enemy); game.addChild(enemy); } // Helper: check collision between two objects (circle approx) function isColliding(a, b, rA, rB) { var dx = a.x - b.x; var dy = a.y - b.y; var dist = Math.sqrt(dx * dx + dy * dy); return dist < rA + rB; } // Helper: check if point is inside sword slash arc function isInSlashArc(enemy, hero, dir) { // Sword arc: 90deg (PI/2) in direction dir, radius 180px from hero center var dx = enemy.x - hero.x; var dy = enemy.y - hero.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 180 || dist < 60) return false; var angle = Math.atan2(dy, dx); var diff = Math.abs((angle - dir + Math.PI * 3) % (Math.PI * 2) - Math.PI); return diff < Math.PI / 4; // 45deg to either side } // Touch controls: drag to move, tap/hold to slash in direction var dragNode = null; var dragStartX = 0, dragStartY = 0; var dragHeroStartX = 0, dragHeroStartY = 0; var lastMoveDir = 0; // Move handler: drag to move hero, tap/hold to slash function handleMove(x, y, obj) { if (!gameStarted) return; // Don't allow hero to move into top left 100x100 if (x < 120 && y < 120) return; // Only move hero if dragging (left side touch) if (isDragging) { var nx = x - dragOffsetX; var ny = y - dragOffsetY; // Clamp to arena nx = Math.max(ARENA_MARGIN, Math.min(2048 - ARENA_MARGIN, nx)); ny = Math.max(ARENA_MARGIN, Math.min(2732 - ARENA_MARGIN, ny)); hero.x = nx; hero.y = ny; lastTouchX = nx; lastTouchY = ny; } } game.move = handleMove; game.down = function (x, y, obj) { // Block all input except menu start until game is started if (!gameStarted) return; // Divide screen: left half for movement, right half for attack if (x < 2048 / 2) { // Left side: start dragging hero isDragging = true; dragOffsetX = x - hero.x; dragOffsetY = y - hero.y; } else { // Right side: attack in direction from hero to touch var dir = Math.atan2(y - hero.y, x - hero.x); lastMoveDir = dir; hero.doSlash(dir); } }; game.up = function (x, y, obj) { if (!gameStarted) return; isDragging = false; }; // Main update loop game.update = function () { // Block all gameplay until menu is dismissed if (!gameStarted) { // Only show menu, do not update game menuGroup.visible = true; arenaFloor.visible = false; return; } else { menuGroup.visible = false; arenaFloor.visible = true; } // Update hero hero.update(); // Update round and enemies left display roundTxt.setText("Wave " + wave); if (roundActive) { enemiesLeftTxt.setText("Enemies left: " + Math.max(ENEMY_MAX - roundKills, 0)); enemiesLeftTxt.visible = true; } else { enemiesLeftTxt.setText(""); enemiesLeftTxt.visible = false; } // Show round/wave info (optional, can be improved with GUI) if (!shopActive && !roundActive) { // Show "Round X Complete!" and trigger shop shopActive = true; showShop(); return; } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // If enemy off screen, remove if (enemy.x < -120 || enemy.x > 2048 + 120 || enemy.y < -120 || enemy.y > 2732 + 120) { enemy.destroy(); enemies.splice(i, 1); continue; } // If enemy collides with hero, game over if (isColliding(enemy, hero, 50, 50)) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } // If hero is slashing and enemy is within slash radius, destroy enemy if (hero.slashActive) { // Hit everywhere in a circular area (e.g. 180px radius) var dx = enemy.x - hero.x; var dy = enemy.y - hero.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist <= 180) { // Only allow one hit per slash per enemy if (!enemy.isHit) { enemy.flashHit(); LK.getSound('hit').play(); // Remove after short delay for flash (function (e, idx) { LK.setTimeout(function () { if (enemies.indexOf(e) !== -1) { e.destroy(); enemies.splice(enemies.indexOf(e), 1); // Score score++; roundKills++; scoreTxt.setText(score); // Check if round is complete if (roundKills >= ENEMY_MAX) { roundActive = false; } } }, 80); })(enemy, i); } } } } // Only spawn enemies if round is active and shop is not open if (roundActive && !shopActive) { ticksSinceSpawn++; var spawnRate = Math.max(ENEMY_SPAWN_INTERVAL - (wave - 1) * 4, 24); // faster per wave if (ticksSinceSpawn >= spawnRate && enemies.length < ENEMY_MAX) { spawnEnemy(); ticksSinceSpawn = 0; } } // If round is not active and shop is not open, trigger shop if (!roundActive && !shopActive) { shopActive = true; showShop(); } // Show wave/round info (optional, can be improved with GUI) };
===================================================================
--- original.js
+++ change.js
@@ -199,8 +199,19 @@
width: 2048,
height: 2732
});
menuGroup.addChild(palaceFloor);
+// Palace floor background for game arena (separate from menu)
+var arenaFloor = LK.getAsset('palace_floor', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0,
+ width: 2048,
+ height: 2732
+});
+game.addChildAt(arenaFloor, 0); // Always behind hero/enemies
+arenaFloor.visible = false;
// Hero pixel art for menu (centered, larger)
var menuHero = LK.getAsset('hero', {
anchorX: 0.5,
anchorY: 0.5,
@@ -521,11 +532,13 @@
// Block all gameplay until menu is dismissed
if (!gameStarted) {
// Only show menu, do not update game
menuGroup.visible = true;
+ arenaFloor.visible = false;
return;
} else {
menuGroup.visible = false;
+ arenaFloor.visible = true;
}
// Update hero
hero.update();
// Update round and enemies left display
Give me an animation of a hit.. In-Game asset. 2d. High contrast. No shadows
Create a pixel art turkish character. In-Game asset. 2d. High contrast. No shadows
draw me zombie enemie. In-Game asset. 2d. High contrast. No shadows
draw me pixel art sword. In-Game asset. 2d. High contrast. No shadows
place floor draw me. In-Game asset. 2d. High contrast. No shadows