User prompt
Opposite, show it always
User prompt
Make the menu button at the bottom right of the screen, and make it disappear once entered menu, and btw, if not enough money for a skin or upgrade or ship, make a notification saying "Not Enough Money!"
User prompt
During GamePlay ONLY (not on title screen) add a menu button ("MENU") that redirects to the title screen
User prompt
The money and score doesn't work
User prompt
Make it so you can't die
User prompt
Keep the menu button before, I ment remove the one in the title screen
User prompt
Please fix the bug: 'menuBtn is not defined' in or related to this line: 'menuBtn.down = function (x, y, obj) {' Line Number: 396
User prompt
Please fix the bug: 'menuBtn is not defined' in or related to this line: 'menuBtn.down = function (x, y, obj) {' Line Number: 386
User prompt
Fix the issue when you first play the game it automatically shows the skins tab,mane also remove the menu button
User prompt
Make settings implemented and make skins ONLY OPEN IF THE SKINS BUTTON IS CLICKED
User prompt
Not what I mean, I mean DURING GAMEPLAY that appears, and title screen appears when "Menu" is clicked, and if you click close on a button on the title screen, redirect to the title screen not remove the whole menu
User prompt
Make it so if on the menu/titlescreen you click close it brings you back to the title screen (e.g. you click skins and then click close and then you go back and you can click other things, you can also access during in-game time by clicking "Menu" and ADD MOR
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'shoot')' in or related to this line: 'player.shoot();' Line Number: 492
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var px = player.x,' Line Number: 461
User prompt
Make it so enemy's don't shoot bullets, and you have to shoot 10 bullets to win, and make there be a menu, and a title screen saying "Settings", "Skins", and "Play" and make it also have notifications
Code edit (1 edits merged)
Please save this source code
User prompt
Galactic Skins: Space Shooter
Initial prompt
Make a space shooting game with mobile support, characters, different skins, menu, player, money, upgrades, and moe
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { money: 0, unlockedSkins: ["ship_default"], selectedSkin: "ship_default", upgrades: { fireRate: 1, speed: 1, shield: 1 } }); /**** * Classes ****/ // Coin (Money) var Coin = Container.expand(function () { var self = Container.call(this); var g = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.update = function () { self.y += self.speed; }; return self; }); // Enemy Bullet var EnemyBullet = Container.expand(function () { var self = Container.call(this); var g = self.attachAsset('enemy_bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 22; self.update = function () { self.y += self.speed; }; return self; }); // Enemy Ship var EnemyShip = Container.expand(function () { var self = Container.call(this); var g = self.attachAsset('enemy_ship', { anchorX: 0.5, anchorY: 0.5 }); self.width = g.width; self.height = g.height; self.speed = 6 + Math.random() * 4 + wave * 0.5; self.fireCooldown = 30 + Math.floor(Math.random() * 30); self.hp = 1 + Math.floor(wave / 3); self.update = function () { self.y += self.speed; if (self.fireCooldown > 0) { self.fireCooldown--; } else { self.shoot(); self.fireCooldown = 60 + Math.floor(Math.random() * 60); } }; self.shoot = function () { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + self.height / 2 + bullet.height / 2; enemyBullets.push(bullet); game.addChild(bullet); }; self.takeHit = function () { self.hp--; if (self.hp <= 0) { LK.getSound('enemy_explode').play(); spawnCoin(self.x, self.y); LK.setScore(LK.getScore() + 1); updateScoreText(); self.destroy(); var idx = enemies.indexOf(self); if (idx !== -1) enemies.splice(idx, 1); } else { LK.effects.flashObject(self, 0xffffff, 200); } }; return self; }); // Player Bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var g = self.attachAsset('player_bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -36; self.update = function () { self.y += self.speed; }; return self; }); // Player Ship var PlayerShip = Container.expand(function () { var self = Container.call(this); // Attach current skin asset self.skinId = storage.selectedSkin || 'ship_default'; self.skin = self.attachAsset(self.skinId, { anchorX: 0.5, anchorY: 0.5 }); self.width = self.skin.width; self.height = self.skin.height; self.speed = 18 + 6 * (storage.upgrades.speed - 1); // base speed + upgrade self.fireCooldown = 0; self.fireRate = 18 - 3 * (storage.upgrades.fireRate - 1); // lower is faster self.shield = storage.upgrades.shield; self.invulnTicks = 0; self.setSkin = function (skinId) { if (self.skin) self.removeChild(self.skin); self.skinId = skinId; self.skin = self.attachAsset(skinId, { anchorX: 0.5, anchorY: 0.5 }); self.width = self.skin.width; self.height = self.skin.height; }; self.update = function () { if (self.invulnTicks > 0) { self.invulnTicks--; if (self.invulnTicks % 6 < 3) { self.skin.alpha = 0.4; } else { self.skin.alpha = 1; } } else { self.skin.alpha = 1; } if (self.fireCooldown > 0) self.fireCooldown--; }; self.shoot = function () { if (self.fireCooldown > 0) return; var bullet = new PlayerBullet(); bullet.x = self.x; bullet.y = self.y - self.height / 2 - bullet.height / 2; playerBullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); self.fireCooldown = self.fireRate; }; self.takeHit = function () { if (self.invulnTicks > 0) return; self.shield--; if (self.shield <= 0) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } else { self.invulnTicks = 60; LK.effects.flashObject(self, 0xff0000, 500); } updateShieldText(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000010 }); /**** * Game Code ****/ // Music // Sounds // Coin (money) // Enemy bullet // Enemy ship // Player bullet // Spaceship skin 3 (unlockable) // Spaceship skin 2 (unlockable) // Spaceship base skin (default) // Game state variables var player; var playerBullets = []; var enemies = []; var enemyBullets = []; var coins = []; var dragNode = null; var wave = 1; var waveTicks = 0; var waveCooldown = 120; var scoreTxt, moneyTxt, shieldTxt; var menuOpen = false; // GUI scoreTxt = new Text2('0', { size: 100, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); moneyTxt = new Text2('$0', { size: 80, fill: 0xFFE066 }); moneyTxt.anchor.set(1, 0); LK.gui.topRight.addChild(moneyTxt); shieldTxt = new Text2('🛡️3', { size: 80, fill: 0x66CCFF }); shieldTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(shieldTxt); // Menu button (top right, not top left) var menuBtn = new Text2('≡', { size: 100, fill: "#fff" }); menuBtn.anchor.set(1, 0); menuBtn.x = -20; menuBtn.y = 20; LK.gui.topRight.addChild(menuBtn); // Menu overlay var menuOverlay = new Container(); menuOverlay.visible = false; LK.gui.center.addChild(menuOverlay); // Menu background var menuBg = LK.getAsset('ship_default', { width: 1200, height: 1600, color: 0x222233, anchorX: 0.5, anchorY: 0.5 }); menuBg.alpha = 0.98; menuOverlay.addChild(menuBg); // Menu title var menuTitle = new Text2('Upgrades & Skins', { size: 100, fill: "#fff" }); menuTitle.anchor.set(0.5, 0); menuTitle.y = -700; menuOverlay.addChild(menuTitle); // Money display in menu var menuMoney = new Text2('$0', { size: 80, fill: 0xFFE066 }); menuMoney.anchor.set(0.5, 0); menuMoney.y = -600; menuOverlay.addChild(menuMoney); // Skins section var skinTitle = new Text2('Skins', { size: 80, fill: "#fff" }); skinTitle.anchor.set(0.5, 0); skinTitle.y = -500; menuOverlay.addChild(skinTitle); var skinBtns = []; var skinIds = ['ship_default', 'ship_red', 'ship_green']; var skinCosts = { ship_default: 0, ship_red: 30, ship_green: 60 }; for (var i = 0; i < skinIds.length; i++) { (function (i) { var sid = skinIds[i]; var btn = new Container(); btn.x = -300 + i * 300; btn.y = -350; var skinAsset = btn.attachAsset(sid, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7 }); var label = new Text2('', { size: 40, fill: "#fff" }); label.anchor.set(0.5, 0); label.y = 80; btn.addChild(label); btn.down = function (x, y, obj) { if (storage.unlockedSkins.indexOf(sid) !== -1) { storage.selectedSkin = sid; player.setSkin(sid); updateMenu(); } else if (storage.money >= skinCosts[sid]) { storage.money -= skinCosts[sid]; storage.unlockedSkins.push(sid); storage.selectedSkin = sid; player.setSkin(sid); updateMenu(); updateMoneyText(); } }; menuOverlay.addChild(btn); skinBtns.push({ btn: btn, label: label, sid: sid }); })(i); } // Upgrades section var upgradeTitle = new Text2('Upgrades', { size: 80, fill: "#fff" }); upgradeTitle.anchor.set(0.5, 0); upgradeTitle.y = -150; menuOverlay.addChild(upgradeTitle); var upgradeNames = ['fireRate', 'speed', 'shield']; var upgradeLabels = ['Fire Rate', 'Speed', 'Shield']; var upgradeCosts = { fireRate: 20, speed: 20, shield: 25 }; var upgradeMax = { fireRate: 5, speed: 5, shield: 5 }; var upgradeBtns = []; for (var i = 0; i < upgradeNames.length; i++) { (function (i) { var upg = upgradeNames[i]; var btn = new Container(); btn.x = -300 + i * 300; btn.y = 0; var label = new Text2('', { size: 40, fill: "#fff" }); label.anchor.set(0.5, 0); btn.addChild(label); btn.down = function (x, y, obj) { if (storage.upgrades[upg] < upgradeMax[upg] && storage.money >= upgradeCosts[upg]) { storage.money -= upgradeCosts[upg]; storage.upgrades[upg]++; updateMenu(); updateMoneyText(); if (upg === 'fireRate') player.fireRate = 18 - 3 * (storage.upgrades.fireRate - 1); if (upg === 'speed') player.speed = 18 + 6 * (storage.upgrades.speed - 1); if (upg === 'shield') { player.shield = storage.upgrades.shield; updateShieldText(); } } }; btn.y = 100; btn.x = -300 + i * 300; menuOverlay.addChild(btn); upgradeBtns.push({ btn: btn, label: label, upg: upg }); })(i); } // Menu close button var closeBtn = new Text2('Close', { size: 80, fill: "#fff" }); closeBtn.anchor.set(0.5, 0); closeBtn.y = 600; closeBtn.down = function (x, y, obj) { menuOverlay.visible = false; menuOpen = false; }; menuOverlay.addChild(closeBtn); // Menu button event menuBtn.down = function (x, y, obj) { menuOverlay.visible = true; menuOpen = true; updateMenu(); }; // Update menu info function updateMenu() { menuMoney.setText('$' + storage.money); for (var i = 0; i < skinBtns.length; i++) { var sid = skinBtns[i].sid; if (storage.unlockedSkins.indexOf(sid) !== -1) { skinBtns[i].label.setText(storage.selectedSkin === sid ? 'Selected' : 'Unlocked'); } else { skinBtns[i].label.setText('Unlock: $' + skinCosts[sid]); } } for (var i = 0; i < upgradeBtns.length; i++) { var upg = upgradeBtns[i].upg; var lvl = storage.upgrades[upg]; if (lvl >= upgradeMax[upg]) { upgradeBtns[i].label.setText(upgradeLabels[i] + ': MAX'); } else { upgradeBtns[i].label.setText(upgradeLabels[i] + ': ' + lvl + ' ($' + upgradeCosts[upg] + ')'); } } } // Update score, money, shield function updateScoreText() { scoreTxt.setText(LK.getScore()); } function updateMoneyText() { moneyTxt.setText('$' + storage.money); } function updateShieldText() { shieldTxt.setText('🛡️' + player.shield); } // Spawn coin function spawnCoin(x, y) { var coin = new Coin(); coin.x = x; coin.y = y; coins.push(coin); game.addChild(coin); } // Start game function startGame() { // Reset state LK.setScore(0); updateScoreText(); wave = 1; waveTicks = 0; playerBullets = []; enemies = []; enemyBullets = []; coins = []; menuOverlay.visible = false; menuOpen = false; // Remove all children except GUI for (var i = game.children.length - 1; i >= 0; i--) { game.children[i].destroy(); } // Create player player = new PlayerShip(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); updateShieldText(); updateMoneyText(); } // Touch controls game.down = function (x, y, obj) { if (menuOpen) return; // Only drag if touch is on player var px = player.x, py = player.y; var dx = x - px, dy = y - py; if (dx * dx + dy * dy < player.width / 2 * (player.width / 2)) { dragNode = player; } }; game.up = function (x, y, obj) { dragNode = null; }; game.move = function (x, y, obj) { if (menuOpen) return; if (dragNode === player) { // Clamp to screen var nx = Math.max(player.width / 2, Math.min(2048 - player.width / 2, x)); var ny = Math.max(player.height / 2 + 100, Math.min(2732 - player.height / 2, y)); player.x = nx; player.y = ny; } }; // Tap to shoot game.tap = function (x, y, obj) { if (menuOpen) return; player.shoot(); }; // Main update loop game.update = function () { if (menuOpen) return; // Player update if (player) player.update(); // Player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; b.update(); // Remove if off screen if (b.y < -b.height) { b.destroy(); playerBullets.splice(i, 1); continue; } // Collide with enemies for (var j = enemies.length - 1; j >= 0; j--) { var e = enemies[j]; if (b.intersects(e)) { e.takeHit(); b.destroy(); playerBullets.splice(i, 1); break; } } } // Enemy update for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.update(); if (e.y > 2732 + e.height) { e.destroy(); enemies.splice(i, 1); continue; } // Collide with player if (player && e.intersects(player)) { e.destroy(); enemies.splice(i, 1); player.takeHit(); continue; } } // Enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var b = enemyBullets[i]; b.update(); if (b.y > 2732 + b.height) { b.destroy(); enemyBullets.splice(i, 1); continue; } if (player && b.intersects(player)) { b.destroy(); enemyBullets.splice(i, 1); player.takeHit(); continue; } } // Coins for (var i = coins.length - 1; i >= 0; i--) { var c = coins[i]; c.update(); if (c.y > 2732 + c.height) { c.destroy(); coins.splice(i, 1); continue; } if (player && c.intersects(player)) { LK.getSound('coin').play(); storage.money += 1; updateMoneyText(); c.destroy(); coins.splice(i, 1); continue; } } // Spawn enemies in waves if (enemies.length === 0 && waveCooldown === 0) { wave++; waveTicks = 0; waveCooldown = 60; } if (waveCooldown > 0) { waveCooldown--; if (waveCooldown === 0) { // Spawn new wave var n = 2 + Math.floor(wave * 0.7); for (var i = 0; i < n; i++) { var e = new EnemyShip(); e.x = 200 + Math.random() * (2048 - 400); e.y = -200 - i * 120; enemies.push(e); game.addChild(e); } } } }; // Start game and music startGame(); LK.playMusic('bgmusic', { fade: { start: 0, end: 1, duration: 1000 } }); // Reset game on game over LK.on('gameover', function () { startGame(); }); // Reset game on win (not used in this endless shooter, but for completeness) LK.on('youwin', function () { startGame(); });
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,594 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ money: 0,
+ unlockedSkins: ["ship_default"],
+ selectedSkin: "ship_default",
+ upgrades: {
+ fireRate: 1,
+ speed: 1,
+ shield: 1
+ }
+});
+
+/****
+* Classes
+****/
+// Coin (Money)
+var Coin = Container.expand(function () {
+ var self = Container.call(this);
+ var g = self.attachAsset('coin', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Enemy Bullet
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var g = self.attachAsset('enemy_bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 22;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Enemy Ship
+var EnemyShip = Container.expand(function () {
+ var self = Container.call(this);
+ var g = self.attachAsset('enemy_ship', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = g.width;
+ self.height = g.height;
+ self.speed = 6 + Math.random() * 4 + wave * 0.5;
+ self.fireCooldown = 30 + Math.floor(Math.random() * 30);
+ self.hp = 1 + Math.floor(wave / 3);
+ self.update = function () {
+ self.y += self.speed;
+ if (self.fireCooldown > 0) {
+ self.fireCooldown--;
+ } else {
+ self.shoot();
+ self.fireCooldown = 60 + Math.floor(Math.random() * 60);
+ }
+ };
+ self.shoot = function () {
+ var bullet = new EnemyBullet();
+ bullet.x = self.x;
+ bullet.y = self.y + self.height / 2 + bullet.height / 2;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ };
+ self.takeHit = function () {
+ self.hp--;
+ if (self.hp <= 0) {
+ LK.getSound('enemy_explode').play();
+ spawnCoin(self.x, self.y);
+ LK.setScore(LK.getScore() + 1);
+ updateScoreText();
+ self.destroy();
+ var idx = enemies.indexOf(self);
+ if (idx !== -1) enemies.splice(idx, 1);
+ } else {
+ LK.effects.flashObject(self, 0xffffff, 200);
+ }
+ };
+ return self;
+});
+// Player Bullet
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var g = self.attachAsset('player_bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -36;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Player Ship
+var PlayerShip = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach current skin asset
+ self.skinId = storage.selectedSkin || 'ship_default';
+ self.skin = self.attachAsset(self.skinId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = self.skin.width;
+ self.height = self.skin.height;
+ self.speed = 18 + 6 * (storage.upgrades.speed - 1); // base speed + upgrade
+ self.fireCooldown = 0;
+ self.fireRate = 18 - 3 * (storage.upgrades.fireRate - 1); // lower is faster
+ self.shield = storage.upgrades.shield;
+ self.invulnTicks = 0;
+ self.setSkin = function (skinId) {
+ if (self.skin) self.removeChild(self.skin);
+ self.skinId = skinId;
+ self.skin = self.attachAsset(skinId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = self.skin.width;
+ self.height = self.skin.height;
+ };
+ self.update = function () {
+ if (self.invulnTicks > 0) {
+ self.invulnTicks--;
+ if (self.invulnTicks % 6 < 3) {
+ self.skin.alpha = 0.4;
+ } else {
+ self.skin.alpha = 1;
+ }
+ } else {
+ self.skin.alpha = 1;
+ }
+ if (self.fireCooldown > 0) self.fireCooldown--;
+ };
+ self.shoot = function () {
+ if (self.fireCooldown > 0) return;
+ var bullet = new PlayerBullet();
+ bullet.x = self.x;
+ bullet.y = self.y - self.height / 2 - bullet.height / 2;
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('shoot').play();
+ self.fireCooldown = self.fireRate;
+ };
+ self.takeHit = function () {
+ if (self.invulnTicks > 0) return;
+ self.shield--;
+ if (self.shield <= 0) {
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ } else {
+ self.invulnTicks = 60;
+ LK.effects.flashObject(self, 0xff0000, 500);
+ }
+ updateShieldText();
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ backgroundColor: 0x000010
+});
+
+/****
+* Game Code
+****/
+// Music
+// Sounds
+// Coin (money)
+// Enemy bullet
+// Enemy ship
+// Player bullet
+// Spaceship skin 3 (unlockable)
+// Spaceship skin 2 (unlockable)
+// Spaceship base skin (default)
+// Game state variables
+var player;
+var playerBullets = [];
+var enemies = [];
+var enemyBullets = [];
+var coins = [];
+var dragNode = null;
+var wave = 1;
+var waveTicks = 0;
+var waveCooldown = 120;
+var scoreTxt, moneyTxt, shieldTxt;
+var menuOpen = false;
+// GUI
+scoreTxt = new Text2('0', {
+ size: 100,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+moneyTxt = new Text2('$0', {
+ size: 80,
+ fill: 0xFFE066
+});
+moneyTxt.anchor.set(1, 0);
+LK.gui.topRight.addChild(moneyTxt);
+shieldTxt = new Text2('🛡️3', {
+ size: 80,
+ fill: 0x66CCFF
+});
+shieldTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(shieldTxt);
+// Menu button (top right, not top left)
+var menuBtn = new Text2('≡', {
+ size: 100,
+ fill: "#fff"
+});
+menuBtn.anchor.set(1, 0);
+menuBtn.x = -20;
+menuBtn.y = 20;
+LK.gui.topRight.addChild(menuBtn);
+// Menu overlay
+var menuOverlay = new Container();
+menuOverlay.visible = false;
+LK.gui.center.addChild(menuOverlay);
+// Menu background
+var menuBg = LK.getAsset('ship_default', {
+ width: 1200,
+ height: 1600,
+ color: 0x222233,
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+menuBg.alpha = 0.98;
+menuOverlay.addChild(menuBg);
+// Menu title
+var menuTitle = new Text2('Upgrades & Skins', {
+ size: 100,
+ fill: "#fff"
+});
+menuTitle.anchor.set(0.5, 0);
+menuTitle.y = -700;
+menuOverlay.addChild(menuTitle);
+// Money display in menu
+var menuMoney = new Text2('$0', {
+ size: 80,
+ fill: 0xFFE066
+});
+menuMoney.anchor.set(0.5, 0);
+menuMoney.y = -600;
+menuOverlay.addChild(menuMoney);
+// Skins section
+var skinTitle = new Text2('Skins', {
+ size: 80,
+ fill: "#fff"
+});
+skinTitle.anchor.set(0.5, 0);
+skinTitle.y = -500;
+menuOverlay.addChild(skinTitle);
+var skinBtns = [];
+var skinIds = ['ship_default', 'ship_red', 'ship_green'];
+var skinCosts = {
+ ship_default: 0,
+ ship_red: 30,
+ ship_green: 60
+};
+for (var i = 0; i < skinIds.length; i++) {
+ (function (i) {
+ var sid = skinIds[i];
+ var btn = new Container();
+ btn.x = -300 + i * 300;
+ btn.y = -350;
+ var skinAsset = btn.attachAsset(sid, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.7,
+ scaleY: 0.7
+ });
+ var label = new Text2('', {
+ size: 40,
+ fill: "#fff"
+ });
+ label.anchor.set(0.5, 0);
+ label.y = 80;
+ btn.addChild(label);
+ btn.down = function (x, y, obj) {
+ if (storage.unlockedSkins.indexOf(sid) !== -1) {
+ storage.selectedSkin = sid;
+ player.setSkin(sid);
+ updateMenu();
+ } else if (storage.money >= skinCosts[sid]) {
+ storage.money -= skinCosts[sid];
+ storage.unlockedSkins.push(sid);
+ storage.selectedSkin = sid;
+ player.setSkin(sid);
+ updateMenu();
+ updateMoneyText();
+ }
+ };
+ menuOverlay.addChild(btn);
+ skinBtns.push({
+ btn: btn,
+ label: label,
+ sid: sid
+ });
+ })(i);
+}
+// Upgrades section
+var upgradeTitle = new Text2('Upgrades', {
+ size: 80,
+ fill: "#fff"
+});
+upgradeTitle.anchor.set(0.5, 0);
+upgradeTitle.y = -150;
+menuOverlay.addChild(upgradeTitle);
+var upgradeNames = ['fireRate', 'speed', 'shield'];
+var upgradeLabels = ['Fire Rate', 'Speed', 'Shield'];
+var upgradeCosts = {
+ fireRate: 20,
+ speed: 20,
+ shield: 25
+};
+var upgradeMax = {
+ fireRate: 5,
+ speed: 5,
+ shield: 5
+};
+var upgradeBtns = [];
+for (var i = 0; i < upgradeNames.length; i++) {
+ (function (i) {
+ var upg = upgradeNames[i];
+ var btn = new Container();
+ btn.x = -300 + i * 300;
+ btn.y = 0;
+ var label = new Text2('', {
+ size: 40,
+ fill: "#fff"
+ });
+ label.anchor.set(0.5, 0);
+ btn.addChild(label);
+ btn.down = function (x, y, obj) {
+ if (storage.upgrades[upg] < upgradeMax[upg] && storage.money >= upgradeCosts[upg]) {
+ storage.money -= upgradeCosts[upg];
+ storage.upgrades[upg]++;
+ updateMenu();
+ updateMoneyText();
+ if (upg === 'fireRate') player.fireRate = 18 - 3 * (storage.upgrades.fireRate - 1);
+ if (upg === 'speed') player.speed = 18 + 6 * (storage.upgrades.speed - 1);
+ if (upg === 'shield') {
+ player.shield = storage.upgrades.shield;
+ updateShieldText();
+ }
+ }
+ };
+ btn.y = 100;
+ btn.x = -300 + i * 300;
+ menuOverlay.addChild(btn);
+ upgradeBtns.push({
+ btn: btn,
+ label: label,
+ upg: upg
+ });
+ })(i);
+}
+// Menu close button
+var closeBtn = new Text2('Close', {
+ size: 80,
+ fill: "#fff"
+});
+closeBtn.anchor.set(0.5, 0);
+closeBtn.y = 600;
+closeBtn.down = function (x, y, obj) {
+ menuOverlay.visible = false;
+ menuOpen = false;
+};
+menuOverlay.addChild(closeBtn);
+// Menu button event
+menuBtn.down = function (x, y, obj) {
+ menuOverlay.visible = true;
+ menuOpen = true;
+ updateMenu();
+};
+// Update menu info
+function updateMenu() {
+ menuMoney.setText('$' + storage.money);
+ for (var i = 0; i < skinBtns.length; i++) {
+ var sid = skinBtns[i].sid;
+ if (storage.unlockedSkins.indexOf(sid) !== -1) {
+ skinBtns[i].label.setText(storage.selectedSkin === sid ? 'Selected' : 'Unlocked');
+ } else {
+ skinBtns[i].label.setText('Unlock: $' + skinCosts[sid]);
+ }
+ }
+ for (var i = 0; i < upgradeBtns.length; i++) {
+ var upg = upgradeBtns[i].upg;
+ var lvl = storage.upgrades[upg];
+ if (lvl >= upgradeMax[upg]) {
+ upgradeBtns[i].label.setText(upgradeLabels[i] + ': MAX');
+ } else {
+ upgradeBtns[i].label.setText(upgradeLabels[i] + ': ' + lvl + ' ($' + upgradeCosts[upg] + ')');
+ }
+ }
+}
+// Update score, money, shield
+function updateScoreText() {
+ scoreTxt.setText(LK.getScore());
+}
+function updateMoneyText() {
+ moneyTxt.setText('$' + storage.money);
+}
+function updateShieldText() {
+ shieldTxt.setText('🛡️' + player.shield);
+}
+// Spawn coin
+function spawnCoin(x, y) {
+ var coin = new Coin();
+ coin.x = x;
+ coin.y = y;
+ coins.push(coin);
+ game.addChild(coin);
+}
+// Start game
+function startGame() {
+ // Reset state
+ LK.setScore(0);
+ updateScoreText();
+ wave = 1;
+ waveTicks = 0;
+ playerBullets = [];
+ enemies = [];
+ enemyBullets = [];
+ coins = [];
+ menuOverlay.visible = false;
+ menuOpen = false;
+ // Remove all children except GUI
+ for (var i = game.children.length - 1; i >= 0; i--) {
+ game.children[i].destroy();
+ }
+ // Create player
+ player = new PlayerShip();
+ player.x = 2048 / 2;
+ player.y = 2732 - 300;
+ game.addChild(player);
+ updateShieldText();
+ updateMoneyText();
+}
+// Touch controls
+game.down = function (x, y, obj) {
+ if (menuOpen) return;
+ // Only drag if touch is on player
+ var px = player.x,
+ py = player.y;
+ var dx = x - px,
+ dy = y - py;
+ if (dx * dx + dy * dy < player.width / 2 * (player.width / 2)) {
+ dragNode = player;
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+game.move = function (x, y, obj) {
+ if (menuOpen) return;
+ if (dragNode === player) {
+ // Clamp to screen
+ var nx = Math.max(player.width / 2, Math.min(2048 - player.width / 2, x));
+ var ny = Math.max(player.height / 2 + 100, Math.min(2732 - player.height / 2, y));
+ player.x = nx;
+ player.y = ny;
+ }
+};
+// Tap to shoot
+game.tap = function (x, y, obj) {
+ if (menuOpen) return;
+ player.shoot();
+};
+// Main update loop
+game.update = function () {
+ if (menuOpen) return;
+ // Player update
+ if (player) player.update();
+ // Player bullets
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var b = playerBullets[i];
+ b.update();
+ // Remove if off screen
+ if (b.y < -b.height) {
+ b.destroy();
+ playerBullets.splice(i, 1);
+ continue;
+ }
+ // Collide with enemies
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var e = enemies[j];
+ if (b.intersects(e)) {
+ e.takeHit();
+ b.destroy();
+ playerBullets.splice(i, 1);
+ break;
+ }
+ }
+ }
+ // Enemy update
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var e = enemies[i];
+ e.update();
+ if (e.y > 2732 + e.height) {
+ e.destroy();
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Collide with player
+ if (player && e.intersects(player)) {
+ e.destroy();
+ enemies.splice(i, 1);
+ player.takeHit();
+ continue;
+ }
+ }
+ // Enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var b = enemyBullets[i];
+ b.update();
+ if (b.y > 2732 + b.height) {
+ b.destroy();
+ enemyBullets.splice(i, 1);
+ continue;
+ }
+ if (player && b.intersects(player)) {
+ b.destroy();
+ enemyBullets.splice(i, 1);
+ player.takeHit();
+ continue;
+ }
+ }
+ // Coins
+ for (var i = coins.length - 1; i >= 0; i--) {
+ var c = coins[i];
+ c.update();
+ if (c.y > 2732 + c.height) {
+ c.destroy();
+ coins.splice(i, 1);
+ continue;
+ }
+ if (player && c.intersects(player)) {
+ LK.getSound('coin').play();
+ storage.money += 1;
+ updateMoneyText();
+ c.destroy();
+ coins.splice(i, 1);
+ continue;
+ }
+ }
+ // Spawn enemies in waves
+ if (enemies.length === 0 && waveCooldown === 0) {
+ wave++;
+ waveTicks = 0;
+ waveCooldown = 60;
+ }
+ if (waveCooldown > 0) {
+ waveCooldown--;
+ if (waveCooldown === 0) {
+ // Spawn new wave
+ var n = 2 + Math.floor(wave * 0.7);
+ for (var i = 0; i < n; i++) {
+ var e = new EnemyShip();
+ e.x = 200 + Math.random() * (2048 - 400);
+ e.y = -200 - i * 120;
+ enemies.push(e);
+ game.addChild(e);
+ }
+ }
+ }
+};
+// Start game and music
+startGame();
+LK.playMusic('bgmusic', {
+ fade: {
+ start: 0,
+ end: 1,
+ duration: 1000
+ }
+});
+// Reset game on game over
+LK.on('gameover', function () {
+ startGame();
+});
+// Reset game on win (not used in this endless shooter, but for completeness)
+LK.on('youwin', function () {
+ startGame();
});
\ No newline at end of file
Make it a ship for a space shooting game with intense designing. In-Game asset. 2d. High contrast. No shadows
Make it a bullet for a space shooting game with intense designing. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Make it a coin for a space shooting game with intense designing. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Make it a ship for a space shooting game with intense designing. In-Game asset. 2d. High contrast. No shadows