User prompt
If I press the buttons it is not working
User prompt
Is not working the modes
User prompt
Make the normal mode and the multiplayer mode buttons bigger
User prompt
Fix the multiplayer mode and the normal mode button because I can't start the game
User prompt
And then after 100 waves add the final boss fight after you beat it you win and there is a play again button if you press it you get back to the starting screen over and over again ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'statusText.style.fill = 0x00FF00;' Line Number: 807
User prompt
Now add the portals that changes your mode into a fastest spaceship mode and another portal that makes you back to normal ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
And when the you chose the multiplayer mode the other players shows their accounts name also my account ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Now make the normal mode and the multiplayer mode and when the game starts you have to chose the difficultys before the game starts
User prompt
Now make the enemy's five you 10 points when they die
User prompt
Add the skins to buy it use points to buy the skin and each skin has a powers ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make a start screen
Remix started
Copy Cosmic Defender: Space Shooter
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
coins: 0,
currentSkin: "basic",
ownedSkins: ["basic"],
playerName: "Player"
});
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroid = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.speed = {
y: 2 + Math.random() * 2,
x: (Math.random() - 0.5) * 2
};
self.rotation = Math.random() * 0.1 - 0.05;
self.scoreValue = 15;
// Random size variation
var scale = 0.7 + Math.random() * 0.8;
asteroid.scale.set(scale, scale);
self.damage = function (amount) {
self.health -= amount || 1;
tween(asteroid, {
tint: 0xffffff
}, {
duration: 200,
onFinish: function onFinish() {
asteroid.tint = 0x95a5a6;
}
});
return self.health <= 0;
};
self.update = function () {
self.y += self.speed.y;
self.x += self.speed.x;
asteroid.rotation += self.rotation;
};
return self;
});
var Boss = Container.expand(function (level) {
var self = Container.call(this);
var ship = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.level = level || 1;
self.maxHealth = 20 * self.level;
self.health = self.maxHealth;
self.scoreValue = 200 * self.level;
self.phase = 0;
self.phaseTime = 0;
self.patterns = ['side-to-side', 'charge', 'retreat'];
self.currentPattern = 0;
self.targetX = 0;
self.targetY = 0;
// Adjust boss based on level
if (self.level > 1) {
ship.tint = 0xcc00cc;
}
// Health bar
self.healthBar = new Container();
self.addChild(self.healthBar);
var healthBarBg = self.healthBar.attachAsset('playerLaser', {
anchorX: 0,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
healthBarBg.tint = 0x333333;
healthBarBg.width = 200;
self.healthBarFill = self.healthBar.attachAsset('playerLaser', {
anchorX: 0,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.4
});
self.healthBarFill.tint = 0xff3333;
self.healthBarFill.width = 200;
self.healthBar.y = -120;
self.damage = function (amount) {
self.health -= amount || 1;
// Update health bar
var healthPercent = self.health / self.maxHealth;
self.healthBarFill.width = 200 * healthPercent;
tween(ship, {
tint: 0xffffff
}, {
duration: 100,
onFinish: function onFinish() {
ship.tint = self.level > 1 ? 0xcc00cc : 0x9b59b6;
}
});
// Change patterns more quickly when damaged
if (self.health < self.maxHealth * 0.5 && self.phaseTime > 150) {
self.changePattern();
}
return self.health <= 0;
};
self.changePattern = function () {
self.currentPattern = (self.currentPattern + 1) % self.patterns.length;
self.phaseTime = 0;
self.phase = 0;
};
self.update = function () {
self.phaseTime++;
// Change pattern every so often
if (self.phaseTime > 300) {
self.changePattern();
}
var pattern = self.patterns[self.currentPattern];
switch (pattern) {
case 'side-to-side':
// Move side to side
self.targetX = 1024 + Math.sin(self.phaseTime * 0.02) * 800;
if (self.phaseTime < 60) {
self.targetY = Math.min(self.y + 2, 400);
} else {
self.targetY = 400;
}
break;
case 'charge':
// Charge down then back up
if (self.phase === 0) {
self.targetY = self.y + 5;
if (self.y > 800) {
self.phase = 1;
}
} else {
self.targetY = Math.max(self.y - 3, 300);
if (self.y <= 300) {
self.phase = 0;
}
}
self.targetX = 1024 + Math.sin(self.phaseTime * 0.03) * 500;
break;
case 'retreat':
// Stay near top and move quickly
self.targetY = 300;
self.targetX = 1024 + Math.sin(self.phaseTime * 0.05) * 900;
break;
}
// Move toward target position
self.x += (self.targetX - self.x) * 0.05;
self.y += (self.targetY - self.y) * 0.05;
};
return self;
});
var Enemy = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'basic';
var assetType = self.type === 'fast' ? 'enemy' : 'enemy';
var ship = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
// Different enemy types
if (self.type === 'basic') {
self.health = 1;
self.speed = 2;
self.scoreValue = 10;
self.shootChance = 0.01;
} else if (self.type === 'fast') {
self.health = 1;
self.speed = 3.5;
self.scoreValue = 15;
ship.scaleX = 0.8;
ship.scaleY = 0.8;
self.shootChance = 0.005;
ship.tint = 0xff9966;
} else if (self.type === 'tank') {
self.health = 3;
self.speed = 1.5;
self.scoreValue = 25;
ship.scaleX = 1.2;
ship.scaleY = 1.2;
self.shootChance = 0.015;
ship.tint = 0x66ff66;
}
self.movement = {
pattern: 'straight',
phase: Math.random() * Math.PI * 2,
amplitude: 60 + Math.random() * 60
};
self.initialX = 0;
self.damage = function (amount) {
self.health -= amount || 1;
tween(ship, {
tint: 0xffffff
}, {
duration: 200,
onFinish: function onFinish() {
ship.tint = self.type === 'fast' ? 0xff9966 : self.type === 'tank' ? 0x66ff66 : 0xe74c3c;
}
});
return self.health <= 0;
};
self.update = function () {
// Basic movement
self.y += self.speed;
// Pattern movement
if (self.movement.pattern === 'sine') {
self.x = self.initialX + Math.sin(LK.ticks * 0.05 + self.movement.phase) * self.movement.amplitude;
} else if (self.movement.pattern === 'zigzag') {
var timeScale = 0.02;
var t = LK.ticks * timeScale + self.movement.phase;
var triangleWave = Math.abs(t % 2 - 1) * 2 - 1;
self.x = self.initialX + triangleWave * self.movement.amplitude;
}
};
return self;
});
var EnemyLaser = Container.expand(function () {
var self = Container.call(this);
var laser = self.attachAsset('enemyLaser', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosion = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
// Set up fade and scale
tween(explosion, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
var Player = Container.expand(function (skinType) {
var self = Container.call(this);
self.skinType = skinType || storage.currentSkin || 'basic';
// Choose asset based on skin type
var assetName = 'player';
if (self.skinType === 'fast') assetName = 'playerFast';else if (self.skinType === 'tank') assetName = 'playerTank';else if (self.skinType === 'elite') assetName = 'playerElite';
var ship = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply skin-specific visual effects
if (self.skinType === 'fast') {
ship.tint = 0x00ff88; // Green tint for speed
} else if (self.skinType === 'tank') {
ship.tint = 0xff6600; // Orange tint for armor
ship.scaleX = 1.2;
ship.scaleY = 1.2;
} else if (self.skinType === 'elite') {
ship.tint = 0x9966ff; // Purple tint for elite
}
self.shield = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Set skin-specific stats
if (self.skinType === 'basic') {
self.lives = 3;
self.fireRate = 20;
self.power = 1;
} else if (self.skinType === 'fast') {
self.lives = 2;
self.fireRate = 12; // Faster shooting
self.power = 1;
} else if (self.skinType === 'tank') {
self.lives = 5; // More lives
self.fireRate = 25; // Slower shooting
self.power = 2; // More damage
} else if (self.skinType === 'elite') {
self.lives = 4;
self.fireRate = 15;
self.power = 2;
}
self.shieldActive = false;
self.lastShot = 0;
self.canShoot = true;
self.invulnerable = false;
self.activateShield = function (duration) {
self.shieldActive = true;
self.shield.alpha = 0.4;
LK.setTimeout(function () {
self.shieldActive = false;
tween(self.shield, {
alpha: 0
}, {
duration: 500
});
}, duration);
};
self.damage = function () {
if (self.invulnerable || self.shieldActive) {
return;
}
self.lives--;
LK.getSound('playerDamage').play();
// Make player temporarily invulnerable
self.invulnerable = true;
// Flash the player to show invulnerability
var flashCount = 0;
var flashInterval = LK.setInterval(function () {
ship.alpha = ship.alpha === 0.3 ? 1 : 0.3;
flashCount++;
if (flashCount >= 10) {
LK.clearInterval(flashInterval);
ship.alpha = 1;
self.invulnerable = false;
}
}, 150);
};
self.upgrade = function (type) {
LK.getSound('powerup').play();
if (type === 'shield') {
self.activateShield(8000);
} else if (type === 'power') {
self.power = Math.min(self.power + 1, 3);
// Reset power after some time
LK.setTimeout(function () {
self.power = Math.max(1, self.power - 1);
}, 10000);
} else if (type === 'life') {
self.lives = Math.min(self.lives + 1, 5);
} else if (type === 'speed') {
var oldFireRate = self.fireRate;
self.fireRate = Math.max(self.fireRate - 5, 10);
// Reset fire rate after some time
LK.setTimeout(function () {
self.fireRate = oldFireRate;
}, 10000);
}
};
return self;
});
var PlayerLaser = Container.expand(function () {
var self = Container.call(this);
var laser = self.attachAsset('playerLaser', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.power = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Portal = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'speed'; // 'speed' or 'normal'
var assetName = self.type === 'speed' ? 'speedPortal' : 'normalPortal';
var portal = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Set visual effects based on type
if (self.type === 'speed') {
portal.tint = 0x00ffff; // Cyan for speed
} else {
portal.tint = 0xff8800; // Orange for normal
}
self.speed = 2;
self.rotationSpeed = 0.08;
self.pulsePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.speed;
portal.rotation += self.rotationSpeed;
// Pulsing effect
self.pulsePhase += 0.1;
var pulse = 1 + Math.sin(self.pulsePhase) * 0.3;
portal.scale.set(pulse, pulse);
};
return self;
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || ['shield', 'power', 'life', 'speed'][Math.floor(Math.random() * 4)];
var powerup = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
// Set color based on type
if (self.type === 'shield') {
powerup.tint = 0x3498db; // Blue
} else if (self.type === 'power') {
powerup.tint = 0xe74c3c; // Red
} else if (self.type === 'life') {
powerup.tint = 0x2ecc71; // Green
} else if (self.type === 'speed') {
powerup.tint = 0xf1c40f; // Yellow
}
self.speed = 3;
self.update = function () {
self.y += self.speed;
powerup.rotation += 0.05;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game variables
var player;
var playerLasers = [];
var enemies = [];
var enemyLasers = [];
var asteroids = [];
var powerups = [];
var portals = [];
var explosions = [];
var boss = null;
var isSpeedMode = false;
var speedModeTimer = 0;
var speedModeDuration = 8000; // 8 seconds
var gameState = 'start';
var shopState = 'closed';
var difficultyState = 'hidden';
var score = 0;
var waveNumber = 1;
var enemiesThisWave = 0;
var enemiesDefeated = 0;
var waveDelay = 0;
var bossWave = false;
var dragStartPosition = {
x: 0,
y: 0
};
var gameDifficulty = 'normal';
var playerName = storage.playerName || 'Player';
var multiplayerPlayers = [];
// UI elements
var scoreTxt = new Text2('SCORE: 0', {
size: 40,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -250;
scoreTxt.y = 50;
scoreTxt.visible = false;
var waveText = new Text2('WAVE: 1', {
size: 40,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
waveText.y = 50;
waveText.visible = false;
var livesText = new Text2('LIVES: 3', {
size: 40,
fill: 0xFFFFFF
});
livesText.anchor.set(0, 0);
LK.gui.topLeft.addChild(livesText);
livesText.x = 150; // Keep away from the top-left menu icon
livesText.y = 50;
livesText.visible = false;
// Start screen UI elements
var startScreenContainer = new Container();
game.addChild(startScreenContainer);
var titleText = new Text2('COSMIC DEFENDER', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
startScreenContainer.addChild(titleText);
var subtitleText = new Text2('Space Shooter', {
size: 60,
fill: 0xAAAAAAA
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 920;
startScreenContainer.addChild(subtitleText);
var instructionText = new Text2('TAP TO START', {
size: 80,
fill: 0x00FF00
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 1400;
startScreenContainer.addChild(instructionText);
var controlsText = new Text2('DRAG TO MOVE • TAP TO SHOOT', {
size: 40,
fill: 0xCCCCCC
});
controlsText.anchor.set(0.5, 0.5);
controlsText.x = 1024;
controlsText.y = 1600;
startScreenContainer.addChild(controlsText);
var highScoreText = new Text2('HIGH SCORE: ' + storage.highScore, {
size: 50,
fill: 0xFFD700
});
highScoreText.anchor.set(0.5, 0.5);
highScoreText.x = 1024;
highScoreText.y = 1200;
startScreenContainer.addChild(highScoreText);
// Coins display
var coinsText = new Text2('COINS: ' + storage.coins, {
size: 40,
fill: 0xFFD700
});
coinsText.anchor.set(0.5, 0.5);
coinsText.x = 1024;
coinsText.y = 1100;
startScreenContainer.addChild(coinsText);
// Skin shop button
var shopButton = new Text2('SKIN SHOP', {
size: 60,
fill: 0x00AAFF
});
shopButton.anchor.set(0.5, 0.5);
shopButton.x = 1024;
shopButton.y = 1800;
startScreenContainer.addChild(shopButton);
// Current skin display
var currentSkinText = new Text2('CURRENT: ' + storage.currentSkin.toUpperCase(), {
size: 35,
fill: 0xAAAAAAA
});
currentSkinText.anchor.set(0.5, 0.5);
currentSkinText.x = 1024;
currentSkinText.y = 1000;
startScreenContainer.addChild(currentSkinText);
// Difficulty selection container
var difficultyContainer = new Container();
game.addChild(difficultyContainer);
difficultyContainer.visible = false;
// Difficulty background
var difficultyBg = difficultyContainer.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 15
});
difficultyBg.x = 1024;
difficultyBg.y = 1366;
difficultyBg.tint = 0x001122;
difficultyBg.alpha = 0.9;
// Difficulty title
var difficultyTitle = new Text2('SELECT DIFFICULTY', {
size: 80,
fill: 0xFFFFFF
});
difficultyTitle.anchor.set(0.5, 0.5);
difficultyTitle.x = 1024;
difficultyTitle.y = 600;
difficultyContainer.addChild(difficultyTitle);
// Normal mode button
var normalModeButton = new Text2('NORMAL MODE', {
size: 70,
fill: 0x00FF88
});
normalModeButton.anchor.set(0.5, 0.5);
normalModeButton.x = 1024;
normalModeButton.y = 1000;
difficultyContainer.addChild(normalModeButton);
// Normal mode description
var normalModeDesc = new Text2('Standard difficulty\nSingle player experience', {
size: 40,
fill: 0xCCCCCC
});
normalModeDesc.anchor.set(0.5, 0.5);
normalModeDesc.x = 1024;
normalModeDesc.y = 1100;
difficultyContainer.addChild(normalModeDesc);
// Multiplayer mode button
var multiplayerModeButton = new Text2('MULTIPLAYER MODE', {
size: 70,
fill: 0xFF6644
});
multiplayerModeButton.anchor.set(0.5, 0.5);
multiplayerModeButton.x = 1024;
multiplayerModeButton.y = 1400;
difficultyContainer.addChild(multiplayerModeButton);
// Multiplayer mode description
var multiplayerModeDesc = new Text2('Increased difficulty\nFaster enemies and more challenges', {
size: 40,
fill: 0xCCCCCC
});
multiplayerModeDesc.anchor.set(0.5, 0.5);
multiplayerModeDesc.x = 1024;
multiplayerModeDesc.y = 1500;
difficultyContainer.addChild(multiplayerModeDesc);
// Difficulty back button
var difficultyBackButton = new Text2('BACK', {
size: 50,
fill: 0xFF4444
});
difficultyBackButton.anchor.set(0.5, 0.5);
difficultyBackButton.x = 1024;
difficultyBackButton.y = 1800;
difficultyContainer.addChild(difficultyBackButton);
// Multiplayer players display container
var playersContainer = new Container();
game.addChild(playersContainer);
playersContainer.visible = false;
// Players list background
var playersBg = playersContainer.attachAsset('player', {
anchorX: 0,
anchorY: 0,
scaleX: 6,
scaleY: 8
});
playersBg.x = 50;
playersBg.y = 150;
playersBg.tint = 0x001144;
playersBg.alpha = 0.8;
// Players list title
var playersTitle = new Text2('PLAYERS', {
size: 40,
fill: 0xFFFFFF
});
playersTitle.anchor.set(0, 0);
playersTitle.x = 70;
playersTitle.y = 170;
playersContainer.addChild(playersTitle);
// Skin shop container
var skinShopContainer = new Container();
game.addChild(skinShopContainer);
skinShopContainer.visible = false;
// Shop background
var shopBg = skinShopContainer.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 15
});
shopBg.x = 1024;
shopBg.y = 1366;
shopBg.tint = 0x000044;
shopBg.alpha = 0.9;
// Shop title
var shopTitle = new Text2('SKIN SHOP', {
size: 80,
fill: 0xFFFFFF
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 400;
skinShopContainer.addChild(shopTitle);
// Back button
var backButton = new Text2('BACK', {
size: 50,
fill: 0xFF4444
});
backButton.anchor.set(0.5, 0.5);
backButton.x = 1024;
backButton.y = 2200;
skinShopContainer.addChild(backButton);
// Skin definitions
var skinShopData = [{
name: 'basic',
price: 0,
description: 'Standard ship\n3 Lives, Normal Speed'
}, {
name: 'fast',
price: 100,
description: 'Speed Demon\n2 Lives, Fast Fire Rate'
}, {
name: 'tank',
price: 200,
description: 'Heavy Armor\n5 Lives, High Damage'
}, {
name: 'elite',
price: 500,
description: 'Elite Fighter\n4 Lives, Balanced Stats'
}];
// Create skin shop items
var skinItems = [];
for (var i = 0; i < skinShopData.length; i++) {
var skinData = skinShopData[i];
var skinItem = new Container();
skinItem.skinData = skinData;
var yPos = 600 + i * 300;
skinItem.x = 1024;
skinItem.y = yPos;
// Skin name
var nameText = new Text2(skinData.name.toUpperCase(), {
size: 60,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -80;
skinItem.addChild(nameText);
// Price/Status
var isOwned = storage.ownedSkins.indexOf(skinData.name) >= 0;
var isCurrent = storage.currentSkin === skinData.name;
var statusText;
if (isCurrent) {
statusText = new Text2('EQUIPPED', {
size: 40,
fill: 0x00FF00
});
} else if (isOwned) {
statusText = new Text2('OWNED - TAP TO EQUIP', {
size: 40,
fill: 0x00AAFF
});
} else {
statusText = new Text2('PRICE: ' + skinData.price + ' COINS', {
size: 40,
fill: 0xFFD700
});
}
statusText.anchor.set(0.5, 0.5);
statusText.y = -20;
skinItem.addChild(statusText);
// Description
var descText = new Text2(skinData.description, {
size: 30,
fill: 0xCCCCCC
});
descText.anchor.set(0.5, 0.5);
descText.y = 40;
skinItem.addChild(descText);
skinItems.push(skinItem);
skinShopContainer.addChild(skinItem);
}
// Animate the "TAP TO START" text
var flashTimer = 0;
function updateStartScreen() {
flashTimer++;
if (flashTimer % 60 < 30) {
instructionText.alpha = 1;
} else {
instructionText.alpha = 0.3;
}
}
// Update shop display
function updateShopDisplay() {
coinsText.setText('COINS: ' + storage.coins);
currentSkinText.setText('CURRENT: ' + storage.currentSkin.toUpperCase());
for (var i = 0; i < skinItems.length; i++) {
var item = skinItems[i];
var skinData = item.skinData;
var statusText = item.children[1]; // Status text is second child
var isOwned = storage.ownedSkins.indexOf(skinData.name) >= 0;
var isCurrent = storage.currentSkin === skinData.name;
if (isCurrent) {
statusText.setText('EQUIPPED');
statusText.tint = 0x00FF00;
} else if (isOwned) {
statusText.setText('OWNED - TAP TO EQUIP');
statusText.tint = 0x00AAFF;
} else {
statusText.setText('PRICE: ' + skinData.price + ' COINS');
statusText.tint = 0xFFD700;
}
}
}
// Generate multiplayer players list
function generateMultiplayerPlayers() {
var playerNames = ['SpaceAce', 'StarHunter', 'CosmicRider', 'NovaBlast', 'GalaxyGuard', 'StellarWing', 'QuantumPilot', 'VoidRunner', 'NebulaDash', 'OrbitMaster'];
multiplayerPlayers = [];
// Add current player
multiplayerPlayers.push({
name: storage.playerName,
score: 0,
isCurrentPlayer: true
});
// Add 3-5 other players
var numOtherPlayers = 3 + Math.floor(Math.random() * 3);
for (var i = 0; i < numOtherPlayers; i++) {
var randomName = playerNames[Math.floor(Math.random() * playerNames.length)];
// Make sure name is unique
while (multiplayerPlayers.some(function (p) {
return p.name === randomName;
})) {
randomName = playerNames[Math.floor(Math.random() * playerNames.length)];
}
multiplayerPlayers.push({
name: randomName,
score: Math.floor(Math.random() * 500),
isCurrentPlayer: false
});
}
// Sort by score (descending)
multiplayerPlayers.sort(function (a, b) {
return b.score - a.score;
});
}
// Update multiplayer players display
function updatePlayersDisplay() {
// Clear existing player texts
for (var i = playersContainer.children.length - 1; i >= 0; i--) {
var child = playersContainer.children[i];
if (child.isPlayerText) {
playersContainer.removeChild(child);
}
}
// Add player texts
for (var i = 0; i < multiplayerPlayers.length && i < 6; i++) {
var playerData = multiplayerPlayers[i];
var playerText = new Text2(playerData.name + ': ' + playerData.score, {
size: 28,
fill: playerData.isCurrentPlayer ? 0x00FF88 : 0xFFFFFF
});
playerText.anchor.set(0, 0);
playerText.x = 70;
playerText.y = 220 + i * 35;
playerText.isPlayerText = true;
playersContainer.addChild(playerText);
}
}
// Handle skin purchase or equip
function handleSkinInteraction(skinData) {
var isOwned = storage.ownedSkins.indexOf(skinData.name) >= 0;
var isCurrent = storage.currentSkin === skinData.name;
if (isCurrent) {
return; // Already equipped
} else if (isOwned) {
// Equip owned skin
storage.currentSkin = skinData.name;
updateShopDisplay();
} else {
// Try to buy skin
if (storage.coins >= skinData.price) {
storage.coins -= skinData.price;
storage.ownedSkins.push(skinData.name);
storage.currentSkin = skinData.name;
updateShopDisplay();
}
}
}
// Create game elements
function initGame() {
// Reset game variables
playerLasers = [];
enemies = [];
enemyLasers = [];
asteroids = [];
powerups = [];
portals = [];
explosions = [];
boss = null;
isSpeedMode = false;
speedModeTimer = 0;
gameState = 'playing';
score = 0;
waveNumber = 1;
// Adjust initial wave size based on difficulty
if (gameDifficulty === 'multiplayer') {
enemiesThisWave = 15;
} else {
enemiesThisWave = 10;
}
enemiesDefeated = 0;
waveDelay = 0;
bossWave = false;
// Hide start screen
startScreenContainer.visible = false;
// Show game UI
scoreTxt.visible = true;
waveText.visible = true;
livesText.visible = true;
// Show multiplayer players list if in multiplayer mode
if (gameDifficulty === 'multiplayer') {
generateMultiplayerPlayers();
playersContainer.visible = true;
updatePlayersDisplay();
} else {
playersContainer.visible = false;
}
// Update UI
scoreTxt.setText('SCORE: ' + score);
waveText.setText('WAVE: ' + waveNumber);
// Create player
player = new Player(storage.currentSkin);
player.x = 1024;
player.y = 2200;
game.addChild(player);
livesText.setText('LIVES: ' + player.lives);
// Start with player moving up
tween(player, {
y: 2000
}, {
duration: 1000
});
// Start the music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
// Create first wave
createWave();
}
// Create a new wave of enemies
function createWave() {
waveNumber++;
waveText.setText('WAVE: ' + waveNumber);
// Check for final boss after wave 100
if (waveNumber > 100) {
// Create final boss
LK.getSound('bossAlert').play();
boss = new Boss(20); // Super powerful final boss
boss.x = 1024;
boss.y = -200;
boss.isFinalBoss = true;
game.addChild(boss);
tween(boss, {
y: 300
}, {
duration: 2000
});
// Show final boss text
var finalBossText = new Text2('FINAL BOSS!', {
size: 100,
fill: 0xFF0000
});
finalBossText.anchor.set(0.5, 0.5);
finalBossText.x = 1024;
finalBossText.y = 800;
game.addChild(finalBossText);
tween(finalBossText, {
alpha: 0,
y: 700
}, {
duration: 3000,
onFinish: function onFinish() {
finalBossText.destroy();
}
});
return;
}
// Every 5 waves is a boss wave
bossWave = waveNumber % 5 === 0;
if (bossWave) {
// Create a boss
var bossLevel = Math.ceil(waveNumber / 5);
LK.getSound('bossAlert').play();
boss = new Boss(bossLevel);
boss.x = 1024;
boss.y = -200;
game.addChild(boss);
tween(boss, {
y: 300
}, {
duration: 2000
});
// Show boss wave text
var bossText = new Text2('BOSS WAVE!', {
size: 80,
fill: 0xFF0000
});
bossText.anchor.set(0.5, 0.5);
bossText.x = 1024;
bossText.y = 800;
game.addChild(bossText);
tween(bossText, {
alpha: 0,
y: 700
}, {
duration: 2000,
onFinish: function onFinish() {
bossText.destroy();
}
});
return;
}
// Regular wave - adjust based on difficulty
if (gameDifficulty === 'multiplayer') {
enemiesThisWave = 15 + waveNumber * 3;
} else {
enemiesThisWave = 10 + waveNumber * 2;
}
enemiesDefeated = 0;
// Show wave text
var newWaveText = new Text2('WAVE ' + waveNumber, {
size: 80,
fill: 0xFFFFFF
});
newWaveText.anchor.set(0.5, 0.5);
newWaveText.x = 1024;
newWaveText.y = 800;
game.addChild(newWaveText);
tween(newWaveText, {
alpha: 0,
y: 700
}, {
duration: 2000,
onFinish: function onFinish() {
newWaveText.destroy();
}
});
// Start spawning enemies after a short delay
waveDelay = 120;
}
// Create a new enemy
function spawnEnemy() {
var types = ['basic'];
// Add more enemy types as waves progress - faster in multiplayer
if (gameDifficulty === 'multiplayer') {
if (waveNumber >= 1) {
types.push('fast');
}
if (waveNumber >= 2) {
types.push('tank');
}
} else {
if (waveNumber >= 2) {
types.push('fast');
}
if (waveNumber >= 3) {
types.push('tank');
}
}
var type = types[Math.floor(Math.random() * types.length)];
var enemy = new Enemy(type);
// Position the enemy
enemy.x = Math.random() * 1800 + 124;
enemy.y = -100;
enemy.initialX = enemy.x;
// Increase speed in multiplayer mode
if (gameDifficulty === 'multiplayer') {
enemy.speed *= 1.3;
enemy.shootChance *= 1.5;
}
// Set random movement pattern
var patterns = ['straight'];
if (waveNumber >= 2) {
patterns.push('sine');
}
if (waveNumber >= 4) {
patterns.push('zigzag');
}
enemy.movement.pattern = patterns[Math.floor(Math.random() * patterns.length)];
// Add to game
enemies.push(enemy);
game.addChild(enemy);
}
// Create a new asteroid
function spawnAsteroid() {
var asteroid = new Asteroid();
// Position the asteroid
asteroid.x = Math.random() * 1800 + 124;
asteroid.y = -100;
// Add to game
asteroids.push(asteroid);
game.addChild(asteroid);
}
// Create a player laser
function firePlayerLaser() {
if (!player || !player.canShoot || player.lastShot + player.fireRate > LK.ticks) {
return;
}
player.lastShot = LK.ticks;
LK.getSound('playerShoot').play();
// Fire based on power level
if (player.power === 1) {
var laser = new PlayerLaser();
laser.x = player.x;
laser.y = player.y - 50;
laser.power = player.power;
playerLasers.push(laser);
game.addChild(laser);
} else if (player.power === 2) {
for (var i = -1; i <= 1; i += 2) {
var laser = new PlayerLaser();
laser.x = player.x + i * 30;
laser.y = player.y - 40;
laser.power = player.power;
playerLasers.push(laser);
game.addChild(laser);
}
} else if (player.power >= 3) {
var centerLaser = new PlayerLaser();
centerLaser.x = player.x;
centerLaser.y = player.y - 50;
centerLaser.power = player.power;
playerLasers.push(centerLaser);
game.addChild(centerLaser);
for (var i = -1; i <= 1; i += 2) {
var sideLaser = new PlayerLaser();
sideLaser.x = player.x + i * 40;
sideLaser.y = player.y - 30;
sideLaser.power = player.power - 1;
playerLasers.push(sideLaser);
game.addChild(sideLaser);
}
}
}
// Create an enemy laser
function fireEnemyLaser(enemy) {
var laser = new EnemyLaser();
laser.x = enemy.x;
laser.y = enemy.y + 40;
enemyLasers.push(laser);
game.addChild(laser);
LK.getSound('enemyShoot').play({
volume: 0.2
});
}
// Fire boss laser pattern
function fireBossLasers() {
if (!boss) {
return;
}
// Different patterns based on boss level and health
var healthPercent = boss.health / boss.maxHealth;
var pattern = 'spread';
if (boss.level >= 2 && healthPercent < 0.5) {
pattern = 'circle';
}
if (pattern === 'spread') {
for (var i = -2; i <= 2; i++) {
var laser = new EnemyLaser();
laser.x = boss.x + i * 50;
laser.y = boss.y + 80;
enemyLasers.push(laser);
game.addChild(laser);
}
} else if (pattern === 'circle') {
var numLasers = 8;
for (var i = 0; i < numLasers; i++) {
var angle = i / numLasers * Math.PI * 2;
var laser = new EnemyLaser();
laser.x = boss.x + Math.cos(angle) * 100;
laser.y = boss.y + Math.sin(angle) * 100;
enemyLasers.push(laser);
game.addChild(laser);
// Add directional motion
laser.update = function () {
var dx = this.x - boss.x;
var dy = this.y - boss.y;
var length = Math.sqrt(dx * dx + dy * dy);
this.x += dx / length * 5;
this.y += dy / length * 5;
};
}
}
LK.getSound('enemyShoot').play({
volume: 0.4
});
}
// Create explosion animation
function createExplosion(x, y, scale) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
if (scale) {
explosion.scale.set(scale, scale);
}
explosions.push(explosion);
game.addChild(explosion);
LK.getSound('explosion').play();
}
// Create a powerup
function spawnPowerup(x, y, type) {
var powerup = new Powerup(type);
powerup.x = x;
powerup.y = y;
powerups.push(powerup);
game.addChild(powerup);
}
// Create a portal
function spawnPortal(type) {
var portal = new Portal(type);
portal.x = Math.random() * 1600 + 224;
portal.y = -100;
portals.push(portal);
game.addChild(portal);
// Portal entry effect
tween(portal, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
onFinish: function onFinish() {
tween(portal, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
// Activate speed mode
function activateSpeedMode() {
if (isSpeedMode) return;
isSpeedMode = true;
speedModeTimer = speedModeDuration;
// Visual effect on player
if (player) {
tween(player, {
tint: 0x00ffff
}, {
duration: 300
});
// Speed trail effect
var trail = player.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
trail.tint = 0x00ffff;
tween(trail, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
onFinish: function onFinish() {
trail.destroy();
}
});
}
LK.getSound('portalEnter').play();
}
// Deactivate speed mode
function deactivateSpeedMode() {
if (!isSpeedMode) return;
isSpeedMode = false;
speedModeTimer = 0;
// Return player to normal color
if (player) {
tween(player, {
tint: 0xffffff
}, {
duration: 500
});
}
LK.getSound('portalEnter').play();
}
// Handle player shooting and movement
function handlePlayerInput() {
// Keep player in bounds
player.x = Math.max(100, Math.min(player.x, 2048 - 100));
player.y = Math.max(100, Math.min(player.y, 2732 - 100));
// Auto-fire (faster in speed mode)
var fireRate = isSpeedMode ? 5 : 10;
if (LK.ticks % fireRate === 0) {
firePlayerLaser();
}
}
// Handle collisions between game objects
function handleCollisions() {
// Player lasers vs enemies
for (var i = playerLasers.length - 1; i >= 0; i--) {
var laser = playerLasers[i];
var hitSomething = false;
// Check against enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (laser.intersects(enemy)) {
// Damage enemy
if (enemy.damage(laser.power)) {
// Enemy destroyed
createExplosion(enemy.x, enemy.y);
// Add score
score += 10;
scoreTxt.setText('SCORE: ' + score);
// Update multiplayer score if in multiplayer mode
if (gameDifficulty === 'multiplayer') {
for (var p = 0; p < multiplayerPlayers.length; p++) {
if (multiplayerPlayers[p].isCurrentPlayer) {
multiplayerPlayers[p].score = score;
break;
}
}
// Update other players' scores occasionally
if (Math.random() < 0.3) {
var randomPlayer = Math.floor(Math.random() * multiplayerPlayers.length);
if (!multiplayerPlayers[randomPlayer].isCurrentPlayer) {
multiplayerPlayers[randomPlayer].score += Math.floor(Math.random() * 15);
}
}
// Re-sort and update display
multiplayerPlayers.sort(function (a, b) {
return b.score - a.score;
});
updatePlayersDisplay();
}
// Add coins
storage.coins += Math.floor(enemy.scoreValue / 5);
// Count enemy as defeated
enemiesDefeated++;
// Chance to spawn powerup
if (Math.random() < 0.1) {
spawnPowerup(enemy.x, enemy.y);
}
enemy.destroy();
enemies.splice(j, 1);
}
// Remove laser
laser.destroy();
playerLasers.splice(i, 1);
hitSomething = true;
break;
}
}
// Only check other collisions if we haven't hit an enemy
if (!hitSomething) {
// Check against boss
if (boss && laser.intersects(boss)) {
// Damage boss
if (boss.damage(laser.power)) {
// Boss destroyed
createExplosion(boss.x, boss.y, 2);
// Add score
score += boss.scoreValue;
scoreTxt.setText('SCORE: ' + score);
// Check if final boss was defeated
if (boss.isFinalBoss) {
// Player wins the game!
// Save high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Add bonus coins for winning
storage.coins += 1000;
// Show victory message and play again button
var victoryContainer = new Container();
game.addChild(victoryContainer);
var victoryBg = victoryContainer.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 25,
scaleY: 20
});
victoryBg.x = 1024;
victoryBg.y = 1366;
victoryBg.tint = 0x001122;
victoryBg.alpha = 0.95;
var victoryText = new Text2('VICTORY!', {
size: 120,
fill: 0x00FF00
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 1024;
victoryText.y = 800;
victoryContainer.addChild(victoryText);
var finalScoreText = new Text2('FINAL SCORE: ' + score, {
size: 60,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 1024;
finalScoreText.y = 1000;
victoryContainer.addChild(finalScoreText);
var playAgainButton = new Text2('PLAY AGAIN', {
size: 80,
fill: 0x00AAFF
});
playAgainButton.anchor.set(0.5, 0.5);
playAgainButton.x = 1024;
playAgainButton.y = 1400;
victoryContainer.addChild(playAgainButton);
// Add victory effect
tween(victoryText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(victoryText, {
scaleX: 1,
scaleY: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
// Handle play again button interaction
game.victoryContainer = victoryContainer;
game.playAgainButton = playAgainButton;
boss.destroy();
boss = null;
return;
}
// Update multiplayer score if in multiplayer mode
if (gameDifficulty === 'multiplayer') {
for (var p = 0; p < multiplayerPlayers.length; p++) {
if (multiplayerPlayers[p].isCurrentPlayer) {
multiplayerPlayers[p].score = score;
break;
}
}
// Update other players' scores for boss defeat
for (var p = 0; p < multiplayerPlayers.length; p++) {
if (!multiplayerPlayers[p].isCurrentPlayer && Math.random() < 0.8) {
multiplayerPlayers[p].score += Math.floor(Math.random() * boss.scoreValue * 0.7);
}
}
// Re-sort and update display
multiplayerPlayers.sort(function (a, b) {
return b.score - a.score;
});
updatePlayersDisplay();
}
// Add coins for boss
storage.coins += Math.floor(boss.scoreValue / 3);
// Spawn multiple powerups
for (var p = 0; p < 3; p++) {
var powerupType = ['shield', 'power', 'life', 'speed'][Math.floor(Math.random() * 4)];
spawnPowerup(boss.x + (Math.random() * 200 - 100), boss.y + (Math.random() * 200 - 100), powerupType);
}
boss.destroy();
boss = null;
// Move to next wave
createWave();
}
// Remove laser
laser.destroy();
playerLasers.splice(i, 1);
hitSomething = true;
}
// Check against asteroids
for (var k = asteroids.length - 1; k >= 0; k--) {
var asteroid = asteroids[k];
if (laser.intersects(asteroid)) {
// Damage asteroid
if (asteroid.damage(laser.power)) {
// Asteroid destroyed
createExplosion(asteroid.x, asteroid.y, 0.7);
// Add score
score += asteroid.scoreValue;
scoreTxt.setText('SCORE: ' + score);
// Update multiplayer score if in multiplayer mode
if (gameDifficulty === 'multiplayer') {
for (var p = 0; p < multiplayerPlayers.length; p++) {
if (multiplayerPlayers[p].isCurrentPlayer) {
multiplayerPlayers[p].score = score;
break;
}
}
// Occasionally update other players' scores
if (Math.random() < 0.2) {
var randomPlayer = Math.floor(Math.random() * multiplayerPlayers.length);
if (!multiplayerPlayers[randomPlayer].isCurrentPlayer) {
multiplayerPlayers[randomPlayer].score += Math.floor(Math.random() * asteroid.scoreValue);
}
}
// Re-sort and update display
multiplayerPlayers.sort(function (a, b) {
return b.score - a.score;
});
updatePlayersDisplay();
}
// Add coins
storage.coins += Math.floor(asteroid.scoreValue / 8);
asteroid.destroy();
asteroids.splice(k, 1);
}
// Remove laser
laser.destroy();
playerLasers.splice(i, 1);
hitSomething = true;
break;
}
}
}
// Remove laser if it's off screen
if (!hitSomething && laser.y < -50) {
laser.destroy();
playerLasers.splice(i, 1);
}
}
// Enemy lasers vs player
for (var i = enemyLasers.length - 1; i >= 0; i--) {
var laser = enemyLasers[i];
if (player && laser.intersects(player)) {
// Damage player
player.damage();
// Update UI
livesText.setText('LIVES: ' + player.lives);
// Check for game over
if (player.lives <= 0) {
// Game over
createExplosion(player.x, player.y, 1.5);
player.destroy();
player = null;
// Save high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
// Show game over after a delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
// Remove laser
laser.destroy();
enemyLasers.splice(i, 1);
} else if (laser.y > 2732 + 50) {
// Remove laser if it's off screen
laser.destroy();
enemyLasers.splice(i, 1);
}
}
// Player vs enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (player && player.intersects(enemy)) {
// Damage player
player.damage();
// Damage enemy
enemy.damage(1);
// Update UI
livesText.setText('LIVES: ' + player.lives);
// Check for enemy death
if (enemy.health <= 0) {
// Enemy destroyed
createExplosion(enemy.x, enemy.y);
// Add score
score += enemy.scoreValue;
scoreTxt.setText('SCORE: ' + score);
// Count enemy as defeated
enemiesDefeated++;
enemy.destroy();
enemies.splice(i, 1);
}
// Check for game over
if (player.lives <= 0) {
// Game over
createExplosion(player.x, player.y, 1.5);
player.destroy();
player = null;
// Save high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
// Show game over after a delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
// Remove enemy if it's off screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Player vs asteroids
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
if (player && player.intersects(asteroid)) {
// Damage player
player.damage();
// Damage asteroid
asteroid.damage(1);
// Update UI
livesText.setText('LIVES: ' + player.lives);
// Check for asteroid death
if (asteroid.health <= 0) {
// Asteroid destroyed
createExplosion(asteroid.x, asteroid.y, 0.7);
// Add score
score += asteroid.scoreValue;
scoreTxt.setText('SCORE: ' + score);
asteroid.destroy();
asteroids.splice(i, 1);
}
// Check for game over
if (player.lives <= 0) {
// Game over
createExplosion(player.x, player.y, 1.5);
player.destroy();
player = null;
// Save high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
// Show game over after a delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
// Remove asteroid if it's off screen
if (asteroid.y > 2732 + 100 || asteroid.x < -100 || asteroid.x > 2048 + 100) {
asteroid.destroy();
asteroids.splice(i, 1);
}
}
// Player vs powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (player && player.intersects(powerup)) {
// Apply powerup
player.upgrade(powerup.type);
// Update UI if life powerup
if (powerup.type === 'life') {
livesText.setText('LIVES: ' + player.lives);
}
// Remove powerup
powerup.destroy();
powerups.splice(i, 1);
} else if (powerup.y > 2732 + 50) {
// Remove powerup if it's off screen
powerup.destroy();
powerups.splice(i, 1);
}
}
// Player vs portals
for (var i = portals.length - 1; i >= 0; i--) {
var portal = portals[i];
if (player && player.intersects(portal)) {
// Apply portal effect
if (portal.type === 'speed') {
activateSpeedMode();
} else if (portal.type === 'normal') {
deactivateSpeedMode();
}
// Portal activation effect
createExplosion(portal.x, portal.y, 1.2);
// Remove portal
portal.destroy();
portals.splice(i, 1);
} else if (portal.y > 2732 + 50) {
// Remove portal if it's off screen
portal.destroy();
portals.splice(i, 1);
}
}
// Player vs boss
if (player && boss && player.intersects(boss)) {
// Damage player
player.damage();
// Update UI
livesText.setText('LIVES: ' + player.lives);
// Check for game over
if (player.lives <= 0) {
// Game over
createExplosion(player.x, player.y, 1.5);
player.destroy();
player = null;
// Save high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
// Show game over after a delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
}
// Don't initialize game automatically - wait for start screen interaction
// Game down event handler
game.down = function (x, y, obj) {
// Check for play again button if victory screen is showing
if (game.victoryContainer && game.victoryContainer.visible !== false) {
var playAgainBounds = {
x: game.playAgainButton.x - 200,
y: game.playAgainButton.y - 40,
width: 400,
height: 80
};
if (x >= playAgainBounds.x && x <= playAgainBounds.x + playAgainBounds.width && y >= playAgainBounds.y && y <= playAgainBounds.y + playAgainBounds.height) {
// Reset game to start screen
game.victoryContainer.destroy();
game.victoryContainer = null;
game.playAgainButton = null;
gameState = 'start';
shopState = 'closed';
difficultyState = 'hidden';
startScreenContainer.visible = true;
scoreTxt.visible = false;
waveText.visible = false;
livesText.visible = false;
playersContainer.visible = false;
difficultyContainer.visible = false;
skinShopContainer.visible = false;
// Update high score display
highScoreText.setText('HIGH SCORE: ' + storage.highScore);
updateShopDisplay();
LK.stopMusic();
return;
}
}
if (gameState === 'start') {
if (shopState === 'closed') {
// Check if shop button was tapped
var shopButtonBounds = {
x: shopButton.x - 150,
y: shopButton.y - 30,
width: 300,
height: 60
};
if (x >= shopButtonBounds.x && x <= shopButtonBounds.x + shopButtonBounds.width && y >= shopButtonBounds.y && y <= shopButtonBounds.y + shopButtonBounds.height) {
// Open shop
shopState = 'open';
skinShopContainer.visible = true;
startScreenContainer.visible = false;
updateShopDisplay();
return;
}
// Show difficulty selection instead of starting game directly
difficultyState = 'visible';
difficultyContainer.visible = true;
startScreenContainer.visible = false;
return;
} else if (shopState === 'open') {
// Check back button
var backButtonBounds = {
x: backButton.x - 100,
y: backButton.y - 25,
width: 200,
height: 50
};
if (x >= backButtonBounds.x && x <= backButtonBounds.x + backButtonBounds.width && y >= backButtonBounds.y && y <= backButtonBounds.y + backButtonBounds.height) {
// Close shop
shopState = 'closed';
skinShopContainer.visible = false;
startScreenContainer.visible = true;
return;
}
// Check skin items
for (var i = 0; i < skinItems.length; i++) {
var item = skinItems[i];
var itemBounds = {
x: item.x - 400,
y: item.y - 100,
width: 800,
height: 200
};
if (x >= itemBounds.x && x <= itemBounds.x + itemBounds.width && y >= itemBounds.y && y <= itemBounds.y + itemBounds.height) {
handleSkinInteraction(item.skinData);
return;
}
}
return;
}
}
if (difficultyState === 'visible') {
// Check normal mode button
var normalButtonBounds = {
x: normalModeButton.x - 200,
y: normalModeButton.y - 35,
width: 400,
height: 70
};
if (x >= normalButtonBounds.x && x <= normalButtonBounds.x + normalButtonBounds.width && y >= normalButtonBounds.y && y <= normalButtonBounds.y + normalButtonBounds.height) {
gameDifficulty = 'normal';
difficultyState = 'hidden';
difficultyContainer.visible = false;
gameState = 'playing';
initGame();
return;
}
// Check multiplayer mode button
var multiplayerButtonBounds = {
x: multiplayerModeButton.x - 250,
y: multiplayerModeButton.y - 35,
width: 500,
height: 70
};
if (x >= multiplayerButtonBounds.x && x <= multiplayerButtonBounds.x + multiplayerButtonBounds.width && y >= multiplayerButtonBounds.y && y <= multiplayerButtonBounds.y + multiplayerButtonBounds.height) {
gameDifficulty = 'multiplayer';
difficultyState = 'hidden';
difficultyContainer.visible = false;
gameState = 'playing';
initGame();
return;
}
// Check difficulty back button
var difficultyBackBounds = {
x: difficultyBackButton.x - 100,
y: difficultyBackButton.y - 25,
width: 200,
height: 50
};
if (x >= difficultyBackBounds.x && x <= difficultyBackBounds.x + difficultyBackBounds.width && y >= difficultyBackBounds.y && y <= difficultyBackBounds.y + difficultyBackBounds.height) {
difficultyState = 'hidden';
difficultyContainer.visible = false;
startScreenContainer.visible = true;
return;
}
}
if (!player) {
return;
}
dragStartPosition.x = x;
dragStartPosition.y = y;
// Fire lasers on tap
firePlayerLaser();
};
// Game move event handler
game.move = function (x, y, obj) {
if (!player) {
return;
}
// Move player with drag
player.x = x;
player.y = y;
};
// Game update handler
game.update = function () {
if (gameState === 'start') {
if (shopState === 'closed') {
updateStartScreen();
}
return;
}
if (gameState !== 'playing') {
return;
}
// Handle player input
if (player) {
handlePlayerInput();
}
// Handle wave creation
if (waveDelay > 0) {
waveDelay--;
} else if (!bossWave && enemies.length === 0 && enemiesDefeated >= enemiesThisWave) {
// All enemies for this wave defeated, create next wave
createWave();
} else if (!bossWave && enemies.length < 5 && enemiesDefeated < enemiesThisWave && LK.ticks % 30 === 0) {
// Spawn more enemies for this wave
spawnEnemy();
}
// Spawn asteroids occasionally
if (LK.ticks % 180 === 0 && Math.random() < 0.7) {
spawnAsteroid();
}
// Spawn portals occasionally
if (LK.ticks % 600 === 0 && Math.random() < 0.4) {
// Spawn speed portal if not in speed mode, or normal portal if in speed mode
var portalType = isSpeedMode ? 'normal' : 'speed';
spawnPortal(portalType);
}
// Handle speed mode timer
if (isSpeedMode) {
speedModeTimer -= 16; // Approximate 60fps
if (speedModeTimer <= 0) {
deactivateSpeedMode();
}
}
// Boss shooting
if (boss && LK.ticks % 90 === 0) {
fireBossLasers();
}
// Enemy shooting
for (var i = 0; i < enemies.length; i++) {
if (Math.random() < enemies[i].shootChance) {
fireEnemyLaser(enemies[i]);
}
}
// Collision detection
handleCollisions();
}; ===================================================================
--- original.js
+++ change.js
@@ -924,8 +924,42 @@
// Create a new wave of enemies
function createWave() {
waveNumber++;
waveText.setText('WAVE: ' + waveNumber);
+ // Check for final boss after wave 100
+ if (waveNumber > 100) {
+ // Create final boss
+ LK.getSound('bossAlert').play();
+ boss = new Boss(20); // Super powerful final boss
+ boss.x = 1024;
+ boss.y = -200;
+ boss.isFinalBoss = true;
+ game.addChild(boss);
+ tween(boss, {
+ y: 300
+ }, {
+ duration: 2000
+ });
+ // Show final boss text
+ var finalBossText = new Text2('FINAL BOSS!', {
+ size: 100,
+ fill: 0xFF0000
+ });
+ finalBossText.anchor.set(0.5, 0.5);
+ finalBossText.x = 1024;
+ finalBossText.y = 800;
+ game.addChild(finalBossText);
+ tween(finalBossText, {
+ alpha: 0,
+ y: 700
+ }, {
+ duration: 3000,
+ onFinish: function onFinish() {
+ finalBossText.destroy();
+ }
+ });
+ return;
+ }
// Every 5 waves is a boss wave
bossWave = waveNumber % 5 === 0;
if (bossWave) {
// Create a boss
@@ -1302,8 +1336,78 @@
createExplosion(boss.x, boss.y, 2);
// Add score
score += boss.scoreValue;
scoreTxt.setText('SCORE: ' + score);
+ // Check if final boss was defeated
+ if (boss.isFinalBoss) {
+ // Player wins the game!
+ // Save high score
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+ // Add bonus coins for winning
+ storage.coins += 1000;
+ // Show victory message and play again button
+ var victoryContainer = new Container();
+ game.addChild(victoryContainer);
+ var victoryBg = victoryContainer.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 25,
+ scaleY: 20
+ });
+ victoryBg.x = 1024;
+ victoryBg.y = 1366;
+ victoryBg.tint = 0x001122;
+ victoryBg.alpha = 0.95;
+ var victoryText = new Text2('VICTORY!', {
+ size: 120,
+ fill: 0x00FF00
+ });
+ victoryText.anchor.set(0.5, 0.5);
+ victoryText.x = 1024;
+ victoryText.y = 800;
+ victoryContainer.addChild(victoryText);
+ var finalScoreText = new Text2('FINAL SCORE: ' + score, {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ finalScoreText.anchor.set(0.5, 0.5);
+ finalScoreText.x = 1024;
+ finalScoreText.y = 1000;
+ victoryContainer.addChild(finalScoreText);
+ var playAgainButton = new Text2('PLAY AGAIN', {
+ size: 80,
+ fill: 0x00AAFF
+ });
+ playAgainButton.anchor.set(0.5, 0.5);
+ playAgainButton.x = 1024;
+ playAgainButton.y = 1400;
+ victoryContainer.addChild(playAgainButton);
+ // Add victory effect
+ tween(victoryText, {
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(victoryText, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ // Handle play again button interaction
+ game.victoryContainer = victoryContainer;
+ game.playAgainButton = playAgainButton;
+ boss.destroy();
+ boss = null;
+ return;
+ }
// Update multiplayer score if in multiplayer mode
if (gameDifficulty === 'multiplayer') {
for (var p = 0; p < multiplayerPlayers.length; p++) {
if (multiplayerPlayers[p].isCurrentPlayer) {
@@ -1574,8 +1678,38 @@
}
// Don't initialize game automatically - wait for start screen interaction
// Game down event handler
game.down = function (x, y, obj) {
+ // Check for play again button if victory screen is showing
+ if (game.victoryContainer && game.victoryContainer.visible !== false) {
+ var playAgainBounds = {
+ x: game.playAgainButton.x - 200,
+ y: game.playAgainButton.y - 40,
+ width: 400,
+ height: 80
+ };
+ if (x >= playAgainBounds.x && x <= playAgainBounds.x + playAgainBounds.width && y >= playAgainBounds.y && y <= playAgainBounds.y + playAgainBounds.height) {
+ // Reset game to start screen
+ game.victoryContainer.destroy();
+ game.victoryContainer = null;
+ game.playAgainButton = null;
+ gameState = 'start';
+ shopState = 'closed';
+ difficultyState = 'hidden';
+ startScreenContainer.visible = true;
+ scoreTxt.visible = false;
+ waveText.visible = false;
+ livesText.visible = false;
+ playersContainer.visible = false;
+ difficultyContainer.visible = false;
+ skinShopContainer.visible = false;
+ // Update high score display
+ highScoreText.setText('HIGH SCORE: ' + storage.highScore);
+ updateShopDisplay();
+ LK.stopMusic();
+ return;
+ }
+ }
if (gameState === 'start') {
if (shopState === 'closed') {
// Check if shop button was tapped
var shopButtonBounds = {
space ship. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
asteroid. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
space enemy. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
shield. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
powerup. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
space boss ufo. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
green laser. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
red laser. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Fancy spaceship image. In-Game asset. 2d. High contrast
The image of the world fastest spaceship. In-Game asset. 2d. High contrast
Giant and strong spaceship. In-Game asset. 2d. High contrast
3 arrows is facing upwards. In-Game asset. 2d. High contrast
1 arrow is facing upwards. In-Game asset. 2d. High contrast