User prompt
Make longer platforms
User prompt
Make more platforms show lifes on the up give me a background
User prompt
Give 5 lifes
User prompt
More platforms add
User prompt
Player can jump the platforms make platforms more close
User prompt
Add More platforms
User prompt
Do more slow bats
User prompt
Can you add more platforms
Code edit (1 edits merged)
Please save this source code
User prompt
Evanasense: Moonlit Spellbound
Initial prompt
Create a 2D arcade platformer game inspired by Snow Bros. The main character is a witch named Evanasense, who uses magical spells to freeze or trap enemies. The player must defeat all enemies in each level to proceed. Enemies can be immobilized with magic, then pushed or shattered to clear the area. Levels scroll vertically, with increasing difficulty and boss fights every 5 stages. Include power-ups like speed boosts, stronger magic, or temporary shields. The game should have a pixel art style with dark fantasy and gothic elements, glowing spells, and eerie backgrounds. > Add magical traps and floating platforms. Include a "full moon mode" where Evanasense becomes more powerful for a short time. Support single-player mode, with plans for local co-op in future updates.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy: Bat var Bat = Container.expand(function (x, y) { var self = Container.call(this); var bat = self.attachAsset('bat', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.vx = (Math.random() > 0.5 ? 1 : -1) * (12 + Math.random() * 8); self.vy = Math.random() > 0.5 ? 2 : -2; self.frozen = false; self.frozenTimer = 0; self.trapped = false; self.trapTimer = 0; self.update = function () { if (self.trapped) { self.trapTimer--; if (self.trapTimer <= 0) { self.trapped = false; self.alpha = 1; } return; } if (self.frozen) { self.frozenTimer--; if (self.frozenTimer <= 0) { self.frozen = false; bat.tint = 0x2a2a2a; } return; } self.x += self.vx; self.y += self.vy; if (self.x < 60 || self.x > 2048 - 60) self.vx *= -1; if (self.y < 200 || self.y > 2732 - 200) self.vy *= -1; }; // Freeze effect self.freeze = function () { self.frozen = true; self.frozenTimer = 60; bat.tint = 0x7fdfff; }; // Trap effect self.trap = function () { self.trapped = true; self.trapTimer = 90; self.alpha = 0.4; }; // Shatter (destroy) self.shatter = function () { LK.getSound('shatter').play(); self.destroy(); var idx = enemies.indexOf(self); if (idx >= 0) enemies.splice(idx, 1); LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); }; return self; }); // Evanasense (player) class var Evanasense = Container.expand(function () { var self = Container.call(this); // Body var body = self.attachAsset('evana', { anchorX: 0.5, anchorY: 0.5 }); // Hat var hat = self.attachAsset('evana_hat', { anchorX: 0.5, anchorY: 1.1, y: -60 }); // Physics self.vx = 0; self.vy = 0; self.isOnGround = false; self.facing = 1; // 1: right, -1: left self.canShoot = true; self.shootCooldown = 0; self.shielded = false; self.speedBoost = 0; self.fullMoon = false; self.fullMoonTimer = 0; // For power-up visuals self.shieldSprite = null; // Freeze spell self.castFreeze = function () { if (!self.canShoot) return; self.canShoot = false; self.shootCooldown = 30; // 0.5s cooldown var orb = new FreezeOrb(self.x, self.y - 60, self.facing); game.addChild(orb); freezeOrbs.push(orb); LK.getSound('freeze').play(); }; // Trap spell (ice block, only in full moon mode) self.castTrap = function () { if (!self.fullMoon) return; var trap = new IceBlock(self.x + 100 * self.facing, self.y - 40); game.addChild(trap); iceBlocks.push(trap); LK.getSound('trap').play(); }; // Power-up: Shield self.gainShield = function () { self.shielded = true; if (!self.shieldSprite) { self.shieldSprite = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); } self.shieldSprite.visible = true; }; self.loseShield = function () { self.shielded = false; if (self.shieldSprite) self.shieldSprite.visible = false; }; // Power-up: Speed self.gainSpeed = function () { self.speedBoost = 180; LK.effects.flashObject(self, 0xffe066, 400); }; // Power-up: Full Moon self.activateFullMoon = function () { self.fullMoon = true; self.fullMoonTimer = 360; // 6 seconds LK.effects.flashObject(self, 0xf6f1c7, 600); }; // Update self.update = function () { // Gravity self.vy += 2.2; if (self.vy > 40) self.vy = 40; // Movement var moveSpeed = 18 + (self.speedBoost > 0 ? 10 : 0); if (self.moveDir) { self.vx = moveSpeed * self.moveDir; self.facing = self.moveDir; } else { self.vx *= 0.7; if (Math.abs(self.vx) < 1) self.vx = 0; } // Apply position self.x += self.vx; self.y += self.vy; // Clamp to screen if (self.x < 60) self.x = 60; if (self.x > 2048 - 60) self.x = 2048 - 60; if (self.y > 2732 - 60) { self.y = 2732 - 60; self.vy = 0; self.isOnGround = true; } // Platform collision self.isOnGround = false; for (var i = 0; i < platforms.length; i++) { var p = platforms[i]; if (self.y + 60 > p.y - p.height / 2 && self.y + 60 < p.y + p.height / 2 && self.x > p.x - p.width / 2 + 30 && self.x < p.x + p.width / 2 - 30 && self.vy >= 0) { self.y = p.y - p.height / 2 - 60; self.vy = 0; self.isOnGround = true; } } // Shooting cooldown if (!self.canShoot) { self.shootCooldown--; if (self.shootCooldown <= 0) { self.canShoot = true; } } // Speed boost timer if (self.speedBoost > 0) { self.speedBoost--; } // Full moon timer if (self.fullMoon) { self.fullMoonTimer--; if (self.fullMoonTimer <= 0) { self.fullMoon = false; } } }; return self; }); // Freeze orb spell var FreezeOrb = Container.expand(function (x, y, dir) { var self = Container.call(this); var orb = self.attachAsset('freeze_orb', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.vx = 32 * dir; self.lifetime = 60; self.update = function () { self.x += self.vx; self.lifetime--; if (self.lifetime <= 0) { self.destroy(); var idx = freezeOrbs.indexOf(self); if (idx >= 0) freezeOrbs.splice(idx, 1); } }; return self; }); // Enemy: Ghost var Ghost = Container.expand(function (x, y) { var self = Container.call(this); var ghost = self.attachAsset('ghost', { anchorX: 0.5, anchorY: 0.5, alpha: 0.85 }); self.x = x; self.y = y; self.vx = (Math.random() > 0.5 ? 1 : -1) * (8 + Math.random() * 6); self.vy = 0; self.frozen = false; self.frozenTimer = 0; self.trapped = false; self.trapTimer = 0; self.update = function () { if (self.trapped) { self.trapTimer--; if (self.trapTimer <= 0) { self.trapped = false; self.alpha = 0.85; } return; } if (self.frozen) { self.frozenTimer--; if (self.frozenTimer <= 0) { self.frozen = false; ghost.tint = 0xcfd6e6; } return; } self.x += self.vx; if (self.x < 80 || self.x > 2048 - 80) self.vx *= -1; }; // Freeze effect self.freeze = function () { self.frozen = true; self.frozenTimer = 60; ghost.tint = 0x7fdfff; }; // Trap effect self.trap = function () { self.trapped = true; self.trapTimer = 90; self.alpha = 0.4; }; // Shatter (destroy) self.shatter = function () { LK.getSound('shatter').play(); self.destroy(); var idx = enemies.indexOf(self); if (idx >= 0) enemies.splice(idx, 1); LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); }; return self; }); // Ice block trap (full moon mode) var IceBlock = Container.expand(function (x, y) { var self = Container.call(this); var block = self.attachAsset('ice_block', { anchorX: 0.5, anchorY: 0.5, alpha: 0.85 }); self.x = x; self.y = y; self.lifetime = 120; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.destroy(); var idx = iceBlocks.indexOf(self); if (idx >= 0) iceBlocks.splice(idx, 1); } }; return self; }); // Power-up: Moon (full moon mode) var MoonPower = Container.expand(function (x, y) { var self = Container.call(this); var moon = self.attachAsset('moon', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.type = 'moon'; self.update = function () {}; return self; }); // Platform var Platform = Container.expand(function (x, y, w) { var self = Container.call(this); var plat = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5, width: w || 320 }); self.x = x; self.y = y; self.width = w || 320; self.height = 40; return self; }); // Power-up: Shield var ShieldPower = Container.expand(function (x, y) { var self = Container.call(this); var shield = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.type = 'shield'; self.update = function () {}; return self; }); // Power-up: Speed var SpeedPower = Container.expand(function (x, y) { var self = Container.call(this); var speed = self.attachAsset('speed', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.type = 'speed'; self.update = function () {}; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x18141e }); /**** * Game Code ****/ // Game state // Main character: Evanasense (witch) // Witch body // Witch hat // Enemy: Ghost // Enemy: Bat // Platform // Spell: Freeze orb // Spell: Trap (ice block) // Power-up: Moon // Power-up: Shield // Power-up: Speed // Sound effects // Music var player; var platforms = []; var enemies = []; var freezeOrbs = []; var iceBlocks = []; var powerups = []; var stage = 1; var stageCleared = false; var stageTimer = 0; var dragNode = null; var moveStartX = 0; var moveDir = 0; var scoreTxt; // Score display scoreTxt = new Text2('0', { size: 120, fill: 0xF6F1C7 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Stage display var stageTxt = new Text2('Stage 1', { size: 70, fill: 0xB8E6FF }); stageTxt.anchor.set(0.5, 0); LK.gui.top.addChild(stageTxt); stageTxt.y = 120; // Helper: spawn platforms function spawnPlatforms() { // Clear old for (var i = 0; i < platforms.length; i++) platforms[i].destroy(); platforms = []; // Floor var floor = new Platform(1024, 2732 - 40, 2048); game.addChild(floor); platforms.push(floor); // Floating platforms var platCount = 12 + Math.floor(stage / 1.2); // Further increase number of platforms for (var i = 0; i < platCount; i++) { // Stagger platforms vertically and horizontally for more variety var px = 150 + Math.random() * (2048 - 300); var py = 400 + i * 180 - Math.random() * 80; var w = 180 + Math.random() * 220; var plat = new Platform(px, py, w); game.addChild(plat); platforms.push(plat); } } // Helper: spawn enemies function spawnEnemies() { for (var i = 0; i < enemies.length; i++) enemies[i].destroy(); enemies = []; var ghostCount = 2 + Math.floor(stage / 2); var batCount = 3 + Math.floor(stage / 2); // Increased number of bats for more slow bats for (var i = 0; i < ghostCount; i++) { var px = 200 + Math.random() * (2048 - 400); var py = 400 + Math.random() * 1200; var g = new Ghost(px, py); game.addChild(g); enemies.push(g); } for (var i = 0; i < batCount; i++) { var px = 200 + Math.random() * (2048 - 400); var py = 300 + Math.random() * 1000; var b = new Bat(px, py); game.addChild(b); enemies.push(b); } } // Helper: spawn powerups function spawnPowerups() { for (var i = 0; i < powerups.length; i++) powerups[i].destroy(); powerups = []; // Always one moon per stage var moon = new MoonPower(200 + Math.random() * (2048 - 400), 400 + Math.random() * 1200); game.addChild(moon); powerups.push(moon); // 50% chance for shield if (Math.random() < 0.5) { var shield = new ShieldPower(200 + Math.random() * (2048 - 400), 400 + Math.random() * 1200); game.addChild(shield); powerups.push(shield); } // 50% chance for speed if (Math.random() < 0.5) { var speed = new SpeedPower(200 + Math.random() * (2048 - 400), 400 + Math.random() * 1200); game.addChild(speed); powerups.push(speed); } } // Start new stage function startStage() { stageCleared = false; stageTimer = 0; stageTxt.setText('Stage ' + stage); LK.setScore(0); scoreTxt.setText('0'); spawnPlatforms(); spawnEnemies(); spawnPowerups(); // Place player if (player) player.destroy(); player = new Evanasense(); player.x = 1024; player.y = 2732 - 200; game.addChild(player); } // Begin first stage startStage(); // Touch controls game.down = function (x, y, obj) { // If touch is on left or right half, move if (y > 2732 - 400) { if (x < 1024) { player.moveDir = -1; } else { player.moveDir = 1; } dragNode = null; } else { // Tap above: jump or cast if (player.isOnGround) { player.vy = -38; LK.getSound('jump').play(); } else { // Cast freeze player.castFreeze(); } dragNode = null; } moveStartX = x; }; game.up = function (x, y, obj) { player.moveDir = 0; dragNode = null; }; game.move = function (x, y, obj) { // Swipe left/right to move if (y > 2732 - 400) { if (x < 1024) { player.moveDir = -1; } else { player.moveDir = 1; } } else { player.moveDir = 0; } }; // Main update loop game.update = function () { // Update player if (player) player.update(); // Update freeze orbs for (var i = freezeOrbs.length - 1; i >= 0; i--) { var orb = freezeOrbs[i]; orb.update(); // Collide with enemies for (var j = 0; j < enemies.length; j++) { var e = enemies[j]; if (!e.frozen && !e.trapped && orb.intersects(e)) { e.freeze(); orb.destroy(); freezeOrbs.splice(i, 1); break; } } } // Update ice blocks for (var i = iceBlocks.length - 1; i >= 0; i--) { var block = iceBlocks[i]; block.update(); // Collide with enemies for (var j = 0; j < enemies.length; j++) { var e = enemies[j]; if (!e.trapped && block.intersects(e)) { e.trap(); block.destroy(); iceBlocks.splice(i, 1); break; } } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.update(); // If frozen or trapped, can be shattered by touching again if ((e.frozen || e.trapped) && player && player.intersects(e)) { e.shatter(); } // If not frozen/trapped, collision with player if (!e.frozen && !e.trapped && player && player.intersects(e)) { if (player.shielded) { player.loseShield(); LK.getSound('hit').play(); LK.effects.flashObject(player, 0x8fffd6, 400); } else { LK.effects.flashScreen(0x7e4a9c, 900); LK.showGameOver(); return; } } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; if (player && player.intersects(p)) { if (p.type === 'moon') { player.activateFullMoon(); } else if (p.type === 'shield') { player.gainShield(); } else if (p.type === 'speed') { player.gainSpeed(); } LK.getSound('powerup').play(); p.destroy(); powerups.splice(i, 1); } } // Full moon: allow trap spell by tap with two fingers (simulate by double tap) if (player && player.fullMoon && LK.ticks % 60 === 0) { // For MVP, allow trap spell every second in full moon player.castTrap(); } // Stage clear if (!stageCleared && enemies.length === 0) { stageCleared = true; stageTimer = 90; LK.effects.flashScreen(0xb8e6ff, 600); } if (stageCleared) { stageTimer--; if (stageTimer <= 0) { stage++; if (stage % 5 === 0) { // Boss stage MVP: just spawn more enemies stageTxt.setText('Boss Stage!'); for (var i = 0; i < 3; i++) { var px = 200 + Math.random() * (2048 - 400); var py = 400 + Math.random() * 1200; var g = new Ghost(px, py); game.addChild(g); enemies.push(g); } for (var i = 0; i < 2; i++) { var px = 200 + Math.random() * (2048 - 400); var py = 300 + Math.random() * 1000; var b = new Bat(px, py); game.addChild(b); enemies.push(b); } stageCleared = false; } else { startStage(); } } } }; // Play music LK.playMusic('gothic_theme', { fade: { start: 0, end: 1, duration: 1200 } });
===================================================================
--- original.js
+++ change.js
@@ -411,14 +411,14 @@
var floor = new Platform(1024, 2732 - 40, 2048);
game.addChild(floor);
platforms.push(floor);
// Floating platforms
- var platCount = 7 + Math.floor(stage / 1.5); // Increase number of platforms
+ var platCount = 12 + Math.floor(stage / 1.2); // Further increase number of platforms
for (var i = 0; i < platCount; i++) {
// Stagger platforms vertically and horizontally for more variety
- var px = 200 + Math.random() * (2048 - 400);
- var py = 500 + i * 260 - Math.random() * 100;
- var w = 200 + Math.random() * 200;
+ var px = 150 + Math.random() * (2048 - 300);
+ var py = 400 + i * 180 - Math.random() * 80;
+ var w = 180 + Math.random() * 220;
var plat = new Platform(px, py, w);
game.addChild(plat);
platforms.push(plat);
}
Ghost. In-Game asset. 2d. High contrast. No shadows
One life potion. In-Game asset. 2d. High contrast. No shadows
Change
Witch boiler. In-Game asset. 2d. High contrast. No shadows
Diffrent colour
Broom. In-Game asset. 2d. High contrast. No shadows
Snake. In-Game asset. 2d. High contrast. No shadows
Add legs
Snowball. In-Game asset. 2d. High contrast. No shadows
Bat closed wings
Behind
Flying boss. In-Game asset. 2d. High contrast. No shadows
Fireball. In-Game asset. 2d. High contrast. No shadows
Moon. In-Game asset. 2d. High contrast. No shadows
Dark forrest. In-Game asset. 2d. High contrast. No shadows
Ice block. In-Game asset. 2d. High contrast. No shadows
Ice wall. In-Game asset. 2d. High contrast. No shadows
Portal. In-Game asset. 2d. High contrast. No shadows