User prompt
Now make a shop button with items different ships and Upgrades ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
I CANT SHOOT
User prompt
Now the player can't shoot and there's no shop
User prompt
The enemies should be able to move left and right and make a shop with good ui and items
Code edit (1 edits merged)
Please save this source code
User prompt
Arcade Space Shooter
Initial prompt
Make a Spaceshooter game like one of those in a arcade
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
selectedShip: 0,
fireRate: 0,
shield: 0,
damage: 0
});
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.horizontalSpeed = 2;
self.shootChance = 0.02;
self.health = 1;
self.direction = Math.random() > 0.5 ? 1 : -1;
self.update = function () {
self.y += self.speed;
self.x += self.horizontalSpeed * self.direction;
if (self.x < 50 || self.x > 1998) {
self.direction *= -1;
}
};
self.takeDamage = function () {
self.health--;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var shipTypes = [{
width: 60,
height: 80,
color: 0x00ff00
}, {
width: 70,
height: 90,
color: 0x0088ff
}, {
width: 80,
height: 100,
color: 0xffaa00
}];
var selectedShipType = storage.selectedShip || 0;
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5,
width: shipTypes[selectedShipType].width,
height: shipTypes[selectedShipType].height,
color: shipTypes[selectedShipType].color
});
self.speed = 15;
self.health = 1;
self.canShoot = true;
self.shootCooldown = 10;
self.baseShootCooldown = 10;
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
self.shoot = function () {
if (self.canShoot && self.shootCooldown <= 0) {
return true;
}
return false;
};
self.takeDamage = function () {
var shieldReduction = upgrades.shield > 0 ? 0.5 : 1;
if (Math.random() < shieldReduction) {
self.health--;
}
LK.effects.flashObject(self, 0xff0000, 200);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
var player = null;
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var score = 0;
var wave = 1;
var waveTimer = 0;
var enemySpawnTimer = 0;
var enemySpawnRate = 120;
var difficultyMultiplier = 1;
var gameActive = true;
var dragNode = null;
// Create score display
var scoreText = new Text2('Score: 0', {
size: 80,
fill: '#ffffff'
});
scoreText.anchor.set(0, 0);
LK.gui.top.addChild(scoreText);
// Shop and upgrade system
var shopOpen = false;
var shopContainer = null;
var upgrades = {
fireRate: storage.fireRate || 0,
shield: storage.shield || 0,
damage: storage.damage || 0
};
var shopButton = null;
var shopBackgroundOverlay = null;
function createShopUI() {
if (shopContainer) return;
shopBackgroundOverlay = new Container();
var overlay = LK.getAsset('shopOverlay', {
width: 2048,
height: 2732,
color: 0x000000
});
overlay.alpha = 0.7;
shopBackgroundOverlay.addChild(overlay);
game.addChild(shopBackgroundOverlay);
shopContainer = new Container();
var shopBg = LK.getAsset('shopBackground', {
width: 1400,
height: 1400,
color: 0x1a1a4d
});
shopBg.x = 324;
shopBg.y = 666;
shopContainer.addChild(shopBg);
var shopTitle = new Text2('SHOP', {
size: 120,
fill: '#00ff00'
});
shopTitle.anchor.set(0.5, 0);
shopTitle.x = 700 + 324;
shopTitle.y = 100 + 666;
shopContainer.addChild(shopTitle);
var shipsTitle = new Text2('SHIPS', {
size: 80,
fill: '#ffff00'
});
shipsTitle.anchor.set(0, 0);
shipsTitle.x = 324;
shipsTitle.y = 150 + 666;
shopContainer.addChild(shipsTitle);
var shipYStart = 250 + 666;
var ship1 = createShipItem('SCOUT', 0, shipYStart, 0);
var ship2 = createShipItem('FIGHTER', 1, shipYStart + 160, 0);
var ship3 = createShipItem('TANK', 2, shipYStart + 320, 0);
shopContainer.addChild(ship1);
shopContainer.addChild(ship2);
shopContainer.addChild(ship3);
var upgradesTitle = new Text2('UPGRADES', {
size: 80,
fill: '#ffff00'
});
upgradesTitle.anchor.set(0, 0);
upgradesTitle.x = 324;
upgradesTitle.y = 800 + 666;
shopContainer.addChild(upgradesTitle);
var itemYStart = 900 + 666;
var itemSpacing = 220;
var fireRateItem = createShopItem('FIRE RATE', 0, itemYStart, 50);
var shieldItem = createShopItem('SHIELD', 1, itemYStart + itemSpacing, 75);
var damageItem = createShopItem('DAMAGE', 2, itemYStart + itemSpacing * 2, 100);
shopContainer.addChild(fireRateItem);
shopContainer.addChild(shieldItem);
shopContainer.addChild(damageItem);
var closeButton = new Container();
var closeBg = LK.getAsset('closeButton', {
width: 150,
height: 150,
color: 0xff0000
});
closeBg.x = 1200 + 324;
closeBg.y = 100 + 666;
closeButton.addChild(closeBg);
var closeText = new Text2('X', {
size: 80,
fill: '#ffffff'
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 75;
closeText.y = 75;
closeButton.addChild(closeText);
closeButton.interactive = true;
closeButton.down = function (x, y, obj) {
closeShop();
};
shopContainer.addChild(closeButton);
game.addChild(shopContainer);
}
function createShipItem(name, shipIndex, yPos, cost) {
var itemContainer = new Container();
var itemBg = LK.getAsset('itemBg', {
width: 900,
height: 140,
color: storage.selectedShip === shipIndex ? 0x4a4aaa : 0x2a2a7a
}); //{ship_bg}
itemBg.x = 274;
itemBg.y = yPos;
itemContainer.addChild(itemBg);
var itemName = new Text2(name, {
size: 60,
fill: '#00ffff'
}); //{ship_name}
itemName.anchor.set(0, 0.5);
itemName.x = 374;
itemName.y = yPos + 70;
itemContainer.addChild(itemName);
var selectText = new Text2(storage.selectedShip === shipIndex ? 'SELECTED' : 'SELECT', {
size: 50,
fill: storage.selectedShip === shipIndex ? '#00ff00' : '#ffffff'
}); //{ship_select}
selectText.anchor.set(0.5, 0.5);
selectText.x = 1074;
selectText.y = yPos + 70;
itemContainer.addChild(selectText);
itemContainer.interactive = true;
itemContainer.down = function (x, y, obj) {
selectShip(shipIndex, itemBg, selectText);
}; //{ship_down}
itemContainer.shipIndex = shipIndex;
return itemContainer;
} //{ship_item_end}
function createShopItem(name, type, yPos, cost) {
var itemContainer = new Container();
var itemBg = LK.getAsset('itemBg', {
width: 1000,
height: 200,
color: 0x2a2a7a
});
itemBg.x = 224;
itemBg.y = yPos;
itemContainer.addChild(itemBg);
var itemName = new Text2(name, {
size: 70,
fill: '#00ffff'
});
itemName.anchor.set(0, 0.5);
itemName.x = 324;
itemName.y = yPos + 100;
itemContainer.addChild(itemName);
var costText = new Text2('Cost: ' + cost, {
size: 60,
fill: '#ffff00'
});
costText.anchor.set(0, 0.5);
costText.x = 324;
costText.y = yPos + 150;
itemContainer.addChild(costText);
var levelText = new Text2('Lv: ' + upgrades[['fireRate', 'shield', 'damage'][type]], {
size: 60,
fill: '#ffffff'
});
levelText.anchor.set(1, 0.5);
levelText.x = 1124;
levelText.y = yPos + 100;
itemContainer.addChild(levelText);
var buyButton = new Container();
var buyBg = LK.getAsset('buyButton', {
width: 200,
height: 120,
color: 0x00aa00
});
buyBg.x = 1024;
buyBg.y = yPos + 40;
buyButton.addChild(buyBg);
var buyText = new Text2('BUY', {
size: 50,
fill: '#ffffff'
});
buyText.anchor.set(0.5, 0.5);
buyText.x = 100;
buyText.y = 60;
buyButton.addChild(buyText);
buyButton.interactive = true;
buyButton.buttonMode = true;
var upgradeIndex = type;
buyButton.down = function (x, y, obj) {
purchaseUpgrade(upgradeIndex, cost, levelText);
};
itemContainer.addChild(buyButton);
return itemContainer;
}
function selectShip(shipIndex, itemBg, selectText) {
storage.selectedShip = shipIndex;
selectText.setText('SELECTED');
selectText.fill = '#00ff00';
itemBg.color = 0x4a4aaa;
} //{select_ship_end}
function purchaseUpgrade(type, cost, levelText) {
if (LK.getScore() >= cost) {
LK.setScore(LK.getScore() - cost);
scoreText.setText('Score: ' + LK.getScore());
var upgradeKeys = ['fireRate', 'shield', 'damage'];
upgrades[upgradeKeys[type]]++;
storage[upgradeKeys[type]] = upgrades[upgradeKeys[type]];
levelText.setText('Lv: ' + upgrades[upgradeKeys[type]]);
}
}
function openShop() {
shopOpen = true;
createShopUI();
}
function closeShop() {
shopOpen = false;
if (shopContainer) {
shopContainer.destroy();
shopContainer = null;
}
if (shopBackgroundOverlay) {
shopBackgroundOverlay.destroy();
shopBackgroundOverlay = null;
}
}
var shopButton = new Container();
var shopButtonBg = LK.getAsset('shopButtonShape', {
width: 120,
height: 120,
color: 0x00aa00
});
shopButton.addChild(shopButtonBg);
var shopButtonText = new Text2('SHOP', {
size: 30,
fill: '#ffffff'
});
shopButtonText.anchor.set(0.5, 0.5);
shopButtonText.x = 60;
shopButtonText.y = 60;
shopButton.addChild(shopButtonText);
shopButton.interactive = true;
shopButton.buttonMode = true;
shopButton.x = 1850;
shopButton.y = 100;
LK.gui.top.addChild(shopButton);
shopButton.down = function (x, y, obj) {
if (!shopOpen) openShop();
};
// Initialize player
player = game.addChild(new PlayerShip());
player.x = 2048 / 2;
player.y = 2500;
// Music
LK.playMusic('bgMusic', {
loop: true
});
// Game update loop
game.update = function () {
if (!gameActive) return;
// Update player
player.update();
// Auto shoot with fire rate upgrade
var fireRateBonus = 1 + upgrades.fireRate * 0.15;
if (player.shoot()) {
var newBullet = new PlayerBullet();
newBullet.x = player.x;
newBullet.y = player.y - 40;
playerBullets.push(newBullet);
game.addChild(newBullet);
LK.getSound('playerShoot').play();
player.shootCooldown = Math.max(2, player.baseShootCooldown / fireRateBonus);
}
// Spawn enemies in waves
waveTimer++;
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
var newEnemy = new Enemy();
newEnemy.x = Math.random() * 1800 + 124;
newEnemy.y = -50;
newEnemy.speed = 1.5 + wave * 0.3;
enemies.push(newEnemy);
game.addChild(newEnemy);
enemySpawnTimer = 0;
}
// Increase wave every 20 seconds
if (waveTimer >= 1200) {
wave++;
enemySpawnRate = Math.max(60, 120 - wave * 5);
waveTimer = 0;
}
// Update and manage player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
bullet.update();
// Remove bullet if off screen
if (bullet.y < -50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
var damageBonus = 1 + upgrades.damage * 0.5;
for (var d = 0; d < damageBonus; d++) {
enemy.takeDamage();
}
bullet.destroy();
playerBullets.splice(i, 1);
if (enemy.health <= 0) {
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
LK.getSound('enemyDestroyed').play();
enemy.destroy();
enemies.splice(j, 1);
}
break;
}
}
}
// Update and manage enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Remove enemy if off screen
if (enemy.y > 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shoots
if (Math.random() < enemy.shootChance) {
var newEnemyBullet = new EnemyBullet();
newEnemyBullet.x = enemy.x;
newEnemyBullet.y = enemy.y;
enemyBullets.push(newEnemyBullet);
game.addChild(newEnemyBullet);
}
// Check enemy-player collision
if (enemy.intersects(player)) {
player.takeDamage();
LK.getSound('playerHit').play();
if (player.health <= 0) {
gameActive = false;
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
}
}
}
// Update and manage enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
bullet.update();
// Remove bullet if off screen
if (bullet.y > 2800) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check enemy bullet-player collision
if (bullet.intersects(player)) {
player.takeDamage();
bullet.destroy();
enemyBullets.splice(i, 1);
LK.getSound('playerHit').play();
if (player.health <= 0) {
gameActive = false;
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
}
}
}
};
// Handle player movement
function handleMove(x, y, obj) {
if (gameActive && dragNode) {
dragNode.x = Math.max(50, Math.min(1998, x));
dragNode.y = Math.max(2400, Math.min(2650, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (gameActive) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
selectedShip: 0,
fireRate: 0,
shield: 0,
damage: 0
});
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.horizontalSpeed = 2;
self.shootChance = 0.02;
self.health = 1;
self.direction = Math.random() > 0.5 ? 1 : -1;
self.update = function () {
self.y += self.speed;
self.x += self.horizontalSpeed * self.direction;
if (self.x < 50 || self.x > 1998) {
self.direction *= -1;
}
};
self.takeDamage = function () {
self.health--;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var shipTypes = [{
width: 60,
height: 80,
color: 0x00ff00
}, {
width: 70,
height: 90,
color: 0x0088ff
}, {
width: 80,
height: 100,
color: 0xffaa00
}];
var selectedShipType = storage.selectedShip || 0;
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5,
width: shipTypes[selectedShipType].width,
height: shipTypes[selectedShipType].height,
color: shipTypes[selectedShipType].color
});
self.speed = 15;
self.health = 1;
self.canShoot = true;
self.shootCooldown = 10;
self.baseShootCooldown = 10;
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
self.shoot = function () {
if (self.canShoot && self.shootCooldown <= 0) {
return true;
}
return false;
};
self.takeDamage = function () {
var shieldReduction = upgrades.shield > 0 ? 0.5 : 1;
if (Math.random() < shieldReduction) {
self.health--;
}
LK.effects.flashObject(self, 0xff0000, 200);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
var player = null;
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var score = 0;
var wave = 1;
var waveTimer = 0;
var enemySpawnTimer = 0;
var enemySpawnRate = 120;
var difficultyMultiplier = 1;
var gameActive = true;
var dragNode = null;
// Create score display
var scoreText = new Text2('Score: 0', {
size: 80,
fill: '#ffffff'
});
scoreText.anchor.set(0, 0);
LK.gui.top.addChild(scoreText);
// Shop and upgrade system
var shopOpen = false;
var shopContainer = null;
var upgrades = {
fireRate: storage.fireRate || 0,
shield: storage.shield || 0,
damage: storage.damage || 0
};
var shopButton = null;
var shopBackgroundOverlay = null;
function createShopUI() {
if (shopContainer) return;
shopBackgroundOverlay = new Container();
var overlay = LK.getAsset('shopOverlay', {
width: 2048,
height: 2732,
color: 0x000000
});
overlay.alpha = 0.7;
shopBackgroundOverlay.addChild(overlay);
game.addChild(shopBackgroundOverlay);
shopContainer = new Container();
var shopBg = LK.getAsset('shopBackground', {
width: 1400,
height: 1400,
color: 0x1a1a4d
});
shopBg.x = 324;
shopBg.y = 666;
shopContainer.addChild(shopBg);
var shopTitle = new Text2('SHOP', {
size: 120,
fill: '#00ff00'
});
shopTitle.anchor.set(0.5, 0);
shopTitle.x = 700 + 324;
shopTitle.y = 100 + 666;
shopContainer.addChild(shopTitle);
var shipsTitle = new Text2('SHIPS', {
size: 80,
fill: '#ffff00'
});
shipsTitle.anchor.set(0, 0);
shipsTitle.x = 324;
shipsTitle.y = 150 + 666;
shopContainer.addChild(shipsTitle);
var shipYStart = 250 + 666;
var ship1 = createShipItem('SCOUT', 0, shipYStart, 0);
var ship2 = createShipItem('FIGHTER', 1, shipYStart + 160, 0);
var ship3 = createShipItem('TANK', 2, shipYStart + 320, 0);
shopContainer.addChild(ship1);
shopContainer.addChild(ship2);
shopContainer.addChild(ship3);
var upgradesTitle = new Text2('UPGRADES', {
size: 80,
fill: '#ffff00'
});
upgradesTitle.anchor.set(0, 0);
upgradesTitle.x = 324;
upgradesTitle.y = 800 + 666;
shopContainer.addChild(upgradesTitle);
var itemYStart = 900 + 666;
var itemSpacing = 220;
var fireRateItem = createShopItem('FIRE RATE', 0, itemYStart, 50);
var shieldItem = createShopItem('SHIELD', 1, itemYStart + itemSpacing, 75);
var damageItem = createShopItem('DAMAGE', 2, itemYStart + itemSpacing * 2, 100);
shopContainer.addChild(fireRateItem);
shopContainer.addChild(shieldItem);
shopContainer.addChild(damageItem);
var closeButton = new Container();
var closeBg = LK.getAsset('closeButton', {
width: 150,
height: 150,
color: 0xff0000
});
closeBg.x = 1200 + 324;
closeBg.y = 100 + 666;
closeButton.addChild(closeBg);
var closeText = new Text2('X', {
size: 80,
fill: '#ffffff'
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 75;
closeText.y = 75;
closeButton.addChild(closeText);
closeButton.interactive = true;
closeButton.down = function (x, y, obj) {
closeShop();
};
shopContainer.addChild(closeButton);
game.addChild(shopContainer);
}
function createShipItem(name, shipIndex, yPos, cost) {
var itemContainer = new Container();
var itemBg = LK.getAsset('itemBg', {
width: 900,
height: 140,
color: storage.selectedShip === shipIndex ? 0x4a4aaa : 0x2a2a7a
}); //{ship_bg}
itemBg.x = 274;
itemBg.y = yPos;
itemContainer.addChild(itemBg);
var itemName = new Text2(name, {
size: 60,
fill: '#00ffff'
}); //{ship_name}
itemName.anchor.set(0, 0.5);
itemName.x = 374;
itemName.y = yPos + 70;
itemContainer.addChild(itemName);
var selectText = new Text2(storage.selectedShip === shipIndex ? 'SELECTED' : 'SELECT', {
size: 50,
fill: storage.selectedShip === shipIndex ? '#00ff00' : '#ffffff'
}); //{ship_select}
selectText.anchor.set(0.5, 0.5);
selectText.x = 1074;
selectText.y = yPos + 70;
itemContainer.addChild(selectText);
itemContainer.interactive = true;
itemContainer.down = function (x, y, obj) {
selectShip(shipIndex, itemBg, selectText);
}; //{ship_down}
itemContainer.shipIndex = shipIndex;
return itemContainer;
} //{ship_item_end}
function createShopItem(name, type, yPos, cost) {
var itemContainer = new Container();
var itemBg = LK.getAsset('itemBg', {
width: 1000,
height: 200,
color: 0x2a2a7a
});
itemBg.x = 224;
itemBg.y = yPos;
itemContainer.addChild(itemBg);
var itemName = new Text2(name, {
size: 70,
fill: '#00ffff'
});
itemName.anchor.set(0, 0.5);
itemName.x = 324;
itemName.y = yPos + 100;
itemContainer.addChild(itemName);
var costText = new Text2('Cost: ' + cost, {
size: 60,
fill: '#ffff00'
});
costText.anchor.set(0, 0.5);
costText.x = 324;
costText.y = yPos + 150;
itemContainer.addChild(costText);
var levelText = new Text2('Lv: ' + upgrades[['fireRate', 'shield', 'damage'][type]], {
size: 60,
fill: '#ffffff'
});
levelText.anchor.set(1, 0.5);
levelText.x = 1124;
levelText.y = yPos + 100;
itemContainer.addChild(levelText);
var buyButton = new Container();
var buyBg = LK.getAsset('buyButton', {
width: 200,
height: 120,
color: 0x00aa00
});
buyBg.x = 1024;
buyBg.y = yPos + 40;
buyButton.addChild(buyBg);
var buyText = new Text2('BUY', {
size: 50,
fill: '#ffffff'
});
buyText.anchor.set(0.5, 0.5);
buyText.x = 100;
buyText.y = 60;
buyButton.addChild(buyText);
buyButton.interactive = true;
buyButton.buttonMode = true;
var upgradeIndex = type;
buyButton.down = function (x, y, obj) {
purchaseUpgrade(upgradeIndex, cost, levelText);
};
itemContainer.addChild(buyButton);
return itemContainer;
}
function selectShip(shipIndex, itemBg, selectText) {
storage.selectedShip = shipIndex;
selectText.setText('SELECTED');
selectText.fill = '#00ff00';
itemBg.color = 0x4a4aaa;
} //{select_ship_end}
function purchaseUpgrade(type, cost, levelText) {
if (LK.getScore() >= cost) {
LK.setScore(LK.getScore() - cost);
scoreText.setText('Score: ' + LK.getScore());
var upgradeKeys = ['fireRate', 'shield', 'damage'];
upgrades[upgradeKeys[type]]++;
storage[upgradeKeys[type]] = upgrades[upgradeKeys[type]];
levelText.setText('Lv: ' + upgrades[upgradeKeys[type]]);
}
}
function openShop() {
shopOpen = true;
createShopUI();
}
function closeShop() {
shopOpen = false;
if (shopContainer) {
shopContainer.destroy();
shopContainer = null;
}
if (shopBackgroundOverlay) {
shopBackgroundOverlay.destroy();
shopBackgroundOverlay = null;
}
}
var shopButton = new Container();
var shopButtonBg = LK.getAsset('shopButtonShape', {
width: 120,
height: 120,
color: 0x00aa00
});
shopButton.addChild(shopButtonBg);
var shopButtonText = new Text2('SHOP', {
size: 30,
fill: '#ffffff'
});
shopButtonText.anchor.set(0.5, 0.5);
shopButtonText.x = 60;
shopButtonText.y = 60;
shopButton.addChild(shopButtonText);
shopButton.interactive = true;
shopButton.buttonMode = true;
shopButton.x = 1850;
shopButton.y = 100;
LK.gui.top.addChild(shopButton);
shopButton.down = function (x, y, obj) {
if (!shopOpen) openShop();
};
// Initialize player
player = game.addChild(new PlayerShip());
player.x = 2048 / 2;
player.y = 2500;
// Music
LK.playMusic('bgMusic', {
loop: true
});
// Game update loop
game.update = function () {
if (!gameActive) return;
// Update player
player.update();
// Auto shoot with fire rate upgrade
var fireRateBonus = 1 + upgrades.fireRate * 0.15;
if (player.shoot()) {
var newBullet = new PlayerBullet();
newBullet.x = player.x;
newBullet.y = player.y - 40;
playerBullets.push(newBullet);
game.addChild(newBullet);
LK.getSound('playerShoot').play();
player.shootCooldown = Math.max(2, player.baseShootCooldown / fireRateBonus);
}
// Spawn enemies in waves
waveTimer++;
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
var newEnemy = new Enemy();
newEnemy.x = Math.random() * 1800 + 124;
newEnemy.y = -50;
newEnemy.speed = 1.5 + wave * 0.3;
enemies.push(newEnemy);
game.addChild(newEnemy);
enemySpawnTimer = 0;
}
// Increase wave every 20 seconds
if (waveTimer >= 1200) {
wave++;
enemySpawnRate = Math.max(60, 120 - wave * 5);
waveTimer = 0;
}
// Update and manage player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
bullet.update();
// Remove bullet if off screen
if (bullet.y < -50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
var damageBonus = 1 + upgrades.damage * 0.5;
for (var d = 0; d < damageBonus; d++) {
enemy.takeDamage();
}
bullet.destroy();
playerBullets.splice(i, 1);
if (enemy.health <= 0) {
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
LK.getSound('enemyDestroyed').play();
enemy.destroy();
enemies.splice(j, 1);
}
break;
}
}
}
// Update and manage enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Remove enemy if off screen
if (enemy.y > 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shoots
if (Math.random() < enemy.shootChance) {
var newEnemyBullet = new EnemyBullet();
newEnemyBullet.x = enemy.x;
newEnemyBullet.y = enemy.y;
enemyBullets.push(newEnemyBullet);
game.addChild(newEnemyBullet);
}
// Check enemy-player collision
if (enemy.intersects(player)) {
player.takeDamage();
LK.getSound('playerHit').play();
if (player.health <= 0) {
gameActive = false;
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
}
}
}
// Update and manage enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
bullet.update();
// Remove bullet if off screen
if (bullet.y > 2800) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check enemy bullet-player collision
if (bullet.intersects(player)) {
player.takeDamage();
bullet.destroy();
enemyBullets.splice(i, 1);
LK.getSound('playerHit').play();
if (player.health <= 0) {
gameActive = false;
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
}
}
}
};
// Handle player movement
function handleMove(x, y, obj) {
if (gameActive && dragNode) {
dragNode.x = Math.max(50, Math.min(1998, x));
dragNode.y = Math.max(2400, Math.min(2650, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (gameActive) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};