/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); // Default: straight up self.speedX = 0; self.speedY = -18; self.update = function () { self.x += self.speedX; self.y += self.speedY; }; return self; }); // CenterShip class removed (no longer needed) // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; // Will be set dynamically self.targetX = 0; self.targetY = 0; self.update = function () { // Move towards target (center ship) var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Movement handled in game.update }; return self; }); // Powerup class var Powerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Example id, replace with actual if needed // --- Game Variables --- // Play SpaceBackground sound at game start LK.getSound('SpaceBackground').play(); // --- Asset Initialization --- // Add background image as the first child so it's behind everything var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(background); var player = new Player(); // Center ship removed as per new requirements var enemies = []; var bullets = []; var powerups = []; var dragNode = null; var lastPlayerIntersect = false; var canShoot = true; var shootCooldown = 0; var shootInterval = 18; // frames between shots var multiShot = 1; // Number of bullets per shot (increases with each powerup, max 5) var multiShotTimer = 0; // Frames left for powerup var difficulty = 1; // 1-100 var difficultyTimer = 0; // frames var enemySpawnTimer = 0; var enemySpawnInterval = 60; // frames var powerupSpawnTimer = 0; var powerupSpawnInterval = 600; // frames // --- Positioning --- player.x = 2048 / 2; player.y = 2732 - 400; game.addChild(player); // --- GUI Elements --- var scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var difficultyTxt = new Text2('Difficulty: 1', { size: 70, fill: 0xFFCC00 }); difficultyTxt.anchor.set(0, 0); LK.gui.top.addChild(difficultyTxt); difficultyTxt.x = 120; // Avoid top left menu // --- Powerup Timer GUI --- var powerupTimerTxt = new Text2('', { size: 80, fill: 0x00FFCC }); powerupTimerTxt.anchor.set(0, 0); // left-top, will position manually powerupTimerTxt.visible = false; LK.gui.top.addChild(powerupTimerTxt); // Position powerupTimerTxt below difficultyTxt powerupTimerTxt.x = difficultyTxt.x; powerupTimerTxt.y = difficultyTxt.y + difficultyTxt.height + 10; // --- Helper Functions --- function spawnEnemy() { var enemy = new Enemy(); // Spawn at random X at top, target centerShip enemy.x = 200 + Math.random() * (2048 - 400); enemy.y = -100; enemy.targetX = player.x; enemy.targetY = player.y; // Speed scales with difficulty enemy.speed = 2.5 + difficulty * 0.08; enemies.push(enemy); game.addChild(enemy); } function spawnPowerup() { var powerup = new Powerup(); powerup.x = 200 + Math.random() * (2048 - 400); powerup.y = -80; powerups.push(powerup); game.addChild(powerup); } function shootBullets() { if (!canShoot) return; canShoot = false; shootCooldown = shootInterval; var angleStep = 0.18; // radians between bullets if multiShot var baseAngle = -Math.PI / 2; var startAngle = baseAngle - (multiShot - 1) * angleStep / 2; for (var i = 0; i < multiShot; i++) { var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - player.height / 2; // Spread for multiShot var angle = startAngle + i * angleStep; // Set bullet velocity based on angle bullet.speedX = Math.cos(angle) * 18; bullet.speedY = Math.sin(angle) * 18; // Override update for angled bullets bullet.update = function () { this.x += this.speedX; this.y += this.speedY; }; bullets.push(bullet); game.addChild(bullet); } // Play laser sound when firing LK.getSound('laser').play(); } // --- Input Handling --- game.move = function (x, y, obj) { // Move player towards pointer at 0.7 speed (10 üzerinden 7) var dx = x - player.x; var dy = y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var moveDist = Math.min(dist, 0.7 * 60); // 0.7*60 px per frame player.x += dx / dist * moveDist; player.y += dy / dist * moveDist; } // Check collision with enemies var playerHit = false; for (var i = 0; i < enemies.length; i++) { if (player.intersects(enemies[i])) { playerHit = true; break; } } if (!lastPlayerIntersect && playerHit) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } lastPlayerIntersect = playerHit; // Powerup collection for (var i = powerups.length - 1; i >= 0; i--) { if (player.intersects(powerups[i])) { // Each powerup increases multiShot by 1 and extends timer by 10s multiShot += 1; // Play powerup sound when collected LK.getSound('powerup').play(); // If timer is running, add 10s, else set to 10s if (multiShotTimer > 0) { multiShotTimer += 600; // stack duration } else { multiShotTimer = 600; } // Show timer text immediately powerupTimerTxt.visible = true; powerupTimerTxt.setText('Power: ' + Math.ceil(multiShotTimer / 60) + 's'); powerups[i].destroy(); powerups.splice(i, 1); } } }; // (removed duplicate game.down/game.up, handled below) // --- Main Game Loop --- game.update = function () { // --- Shooting cooldown --- if (!canShoot) { shootCooldown--; if (shootCooldown <= 0) { canShoot = true; } } // --- MultiShot Powerup timer logic --- if (multiShotTimer > 0) { multiShotTimer--; // Show timer text powerupTimerTxt.visible = true; var secondsLeft = Math.ceil(multiShotTimer / 60); powerupTimerTxt.setText('Power: ' + secondsLeft + 's'); if (multiShotTimer === 0) { multiShot = 1; powerupTimerTxt.visible = false; powerupTimerTxt.setText(''); } } else { powerupTimerTxt.visible = false; powerupTimerTxt.setText(''); } // --- Difficulty by Score --- var newDifficulty = Math.floor(LK.getScore() / 50) + 1; if (newDifficulty !== difficulty && newDifficulty <= 100) { difficulty = newDifficulty; difficultyTxt.setText('Difficulty: ' + difficulty); // Increase enemy spawn rate enemySpawnInterval = Math.max(20, 60 - difficulty * 0.4); } // --- Enemy Spawning --- enemySpawnTimer++; if (enemySpawnTimer >= enemySpawnInterval) { spawnEnemy(); enemySpawnTimer = 0; } // --- Powerup Spawning --- powerupSpawnTimer++; if (powerupSpawnTimer >= powerupSpawnInterval) { spawnPowerup(); powerupSpawnTimer = 0; } // --- Update Enemies --- for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; // Always update target to player's current position so enemies never stop enemy.targetX = player.x; enemy.targetY = player.y; enemy.update(); // Game over if enemy touches player if (enemy.intersects(player)) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } // If enemy goes off screen, remove if (enemy.y > 2732 + 200) { enemy.destroy(); enemies.splice(i, 1); } } // --- Update Bullets --- for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Remove if off screen if (bullet.y < -100 || bullet.x < -100 || bullet.x > 2148) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check collision with enemies var hit = false; for (var j = enemies.length - 1; j >= 0; j--) { if (bullet.intersects(enemies[j])) { // Destroy both enemies[j].destroy(); enemies.splice(j, 1); bullet.destroy(); bullets.splice(i, 1); // Score LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); hit = true; break; } } if (hit) continue; } // --- Update Powerups --- for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); if (powerup.y > 2732 + 100) { powerup.destroy(); powerups.splice(i, 1); } } }; // --- Touchscreen: auto-fire on hold --- var fireHold = false; game.down = function (x, y, obj) { fireHold = true; game.move(x, y, obj); }; game.up = function (x, y, obj) { fireHold = false; }; LK.on('tick', function () { if (fireHold && canShoot) { shootBullets(); } }); // --- Initial Score --- scoreTxt.setText(LK.getScore()); difficultyTxt.setText('Difficulty: ' + difficulty);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
// Default: straight up
self.speedX = 0;
self.speedY = -18;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
};
return self;
});
// CenterShip class removed (no longer needed)
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3; // Will be set dynamically
self.targetX = 0;
self.targetY = 0;
self.update = function () {
// Move towards target (center ship)
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Movement handled in game.update
};
return self;
});
// Powerup class
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Example id, replace with actual if needed
// --- Game Variables ---
// Play SpaceBackground sound at game start
LK.getSound('SpaceBackground').play();
// --- Asset Initialization ---
// Add background image as the first child so it's behind everything
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
var player = new Player();
// Center ship removed as per new requirements
var enemies = [];
var bullets = [];
var powerups = [];
var dragNode = null;
var lastPlayerIntersect = false;
var canShoot = true;
var shootCooldown = 0;
var shootInterval = 18; // frames between shots
var multiShot = 1; // Number of bullets per shot (increases with each powerup, max 5)
var multiShotTimer = 0; // Frames left for powerup
var difficulty = 1; // 1-100
var difficultyTimer = 0; // frames
var enemySpawnTimer = 0;
var enemySpawnInterval = 60; // frames
var powerupSpawnTimer = 0;
var powerupSpawnInterval = 600; // frames
// --- Positioning ---
player.x = 2048 / 2;
player.y = 2732 - 400;
game.addChild(player);
// --- GUI Elements ---
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var difficultyTxt = new Text2('Difficulty: 1', {
size: 70,
fill: 0xFFCC00
});
difficultyTxt.anchor.set(0, 0);
LK.gui.top.addChild(difficultyTxt);
difficultyTxt.x = 120; // Avoid top left menu
// --- Powerup Timer GUI ---
var powerupTimerTxt = new Text2('', {
size: 80,
fill: 0x00FFCC
});
powerupTimerTxt.anchor.set(0, 0); // left-top, will position manually
powerupTimerTxt.visible = false;
LK.gui.top.addChild(powerupTimerTxt);
// Position powerupTimerTxt below difficultyTxt
powerupTimerTxt.x = difficultyTxt.x;
powerupTimerTxt.y = difficultyTxt.y + difficultyTxt.height + 10;
// --- Helper Functions ---
function spawnEnemy() {
var enemy = new Enemy();
// Spawn at random X at top, target centerShip
enemy.x = 200 + Math.random() * (2048 - 400);
enemy.y = -100;
enemy.targetX = player.x;
enemy.targetY = player.y;
// Speed scales with difficulty
enemy.speed = 2.5 + difficulty * 0.08;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnPowerup() {
var powerup = new Powerup();
powerup.x = 200 + Math.random() * (2048 - 400);
powerup.y = -80;
powerups.push(powerup);
game.addChild(powerup);
}
function shootBullets() {
if (!canShoot) return;
canShoot = false;
shootCooldown = shootInterval;
var angleStep = 0.18; // radians between bullets if multiShot
var baseAngle = -Math.PI / 2;
var startAngle = baseAngle - (multiShot - 1) * angleStep / 2;
for (var i = 0; i < multiShot; i++) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - player.height / 2;
// Spread for multiShot
var angle = startAngle + i * angleStep;
// Set bullet velocity based on angle
bullet.speedX = Math.cos(angle) * 18;
bullet.speedY = Math.sin(angle) * 18;
// Override update for angled bullets
bullet.update = function () {
this.x += this.speedX;
this.y += this.speedY;
};
bullets.push(bullet);
game.addChild(bullet);
}
// Play laser sound when firing
LK.getSound('laser').play();
}
// --- Input Handling ---
game.move = function (x, y, obj) {
// Move player towards pointer at 0.7 speed (10 üzerinden 7)
var dx = x - player.x;
var dy = y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
var moveDist = Math.min(dist, 0.7 * 60); // 0.7*60 px per frame
player.x += dx / dist * moveDist;
player.y += dy / dist * moveDist;
}
// Check collision with enemies
var playerHit = false;
for (var i = 0; i < enemies.length; i++) {
if (player.intersects(enemies[i])) {
playerHit = true;
break;
}
}
if (!lastPlayerIntersect && playerHit) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
lastPlayerIntersect = playerHit;
// Powerup collection
for (var i = powerups.length - 1; i >= 0; i--) {
if (player.intersects(powerups[i])) {
// Each powerup increases multiShot by 1 and extends timer by 10s
multiShot += 1;
// Play powerup sound when collected
LK.getSound('powerup').play();
// If timer is running, add 10s, else set to 10s
if (multiShotTimer > 0) {
multiShotTimer += 600; // stack duration
} else {
multiShotTimer = 600;
}
// Show timer text immediately
powerupTimerTxt.visible = true;
powerupTimerTxt.setText('Power: ' + Math.ceil(multiShotTimer / 60) + 's');
powerups[i].destroy();
powerups.splice(i, 1);
}
}
};
// (removed duplicate game.down/game.up, handled below)
// --- Main Game Loop ---
game.update = function () {
// --- Shooting cooldown ---
if (!canShoot) {
shootCooldown--;
if (shootCooldown <= 0) {
canShoot = true;
}
}
// --- MultiShot Powerup timer logic ---
if (multiShotTimer > 0) {
multiShotTimer--;
// Show timer text
powerupTimerTxt.visible = true;
var secondsLeft = Math.ceil(multiShotTimer / 60);
powerupTimerTxt.setText('Power: ' + secondsLeft + 's');
if (multiShotTimer === 0) {
multiShot = 1;
powerupTimerTxt.visible = false;
powerupTimerTxt.setText('');
}
} else {
powerupTimerTxt.visible = false;
powerupTimerTxt.setText('');
}
// --- Difficulty by Score ---
var newDifficulty = Math.floor(LK.getScore() / 50) + 1;
if (newDifficulty !== difficulty && newDifficulty <= 100) {
difficulty = newDifficulty;
difficultyTxt.setText('Difficulty: ' + difficulty);
// Increase enemy spawn rate
enemySpawnInterval = Math.max(20, 60 - difficulty * 0.4);
}
// --- Enemy Spawning ---
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnInterval) {
spawnEnemy();
enemySpawnTimer = 0;
}
// --- Powerup Spawning ---
powerupSpawnTimer++;
if (powerupSpawnTimer >= powerupSpawnInterval) {
spawnPowerup();
powerupSpawnTimer = 0;
}
// --- Update Enemies ---
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Always update target to player's current position so enemies never stop
enemy.targetX = player.x;
enemy.targetY = player.y;
enemy.update();
// Game over if enemy touches player
if (enemy.intersects(player)) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// If enemy goes off screen, remove
if (enemy.y > 2732 + 200) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// --- Update Bullets ---
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove if off screen
if (bullet.y < -100 || bullet.x < -100 || bullet.x > 2148) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with enemies
var hit = false;
for (var j = enemies.length - 1; j >= 0; j--) {
if (bullet.intersects(enemies[j])) {
// Destroy both
enemies[j].destroy();
enemies.splice(j, 1);
bullet.destroy();
bullets.splice(i, 1);
// Score
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
hit = true;
break;
}
}
if (hit) continue;
}
// --- Update Powerups ---
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
powerup.update();
if (powerup.y > 2732 + 100) {
powerup.destroy();
powerups.splice(i, 1);
}
}
};
// --- Touchscreen: auto-fire on hold ---
var fireHold = false;
game.down = function (x, y, obj) {
fireHold = true;
game.move(x, y, obj);
};
game.up = function (x, y, obj) {
fireHold = false;
};
LK.on('tick', function () {
if (fireHold && canShoot) {
shootBullets();
}
});
// --- Initial Score ---
scoreTxt.setText(LK.getScore());
difficultyTxt.setText('Difficulty: ' + difficulty);