/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Button = Container.expand(function (assetId, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.width = buttonGraphics.width;
self.height = buttonGraphics.height;
self.callback = callback;
self.down = function () {
buttonGraphics.alpha = 0.9;
self.isPressed = true;
if (self.callback) {
self.callback();
}
};
self.up = function () {
buttonGraphics.alpha = 0.7;
self.isPressed = false;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemyGraphics.width;
self.height = enemyGraphics.height;
self.health = 2; // Enemy needs 2 hits to die
self.movementDirection = Math.random() > 0.5 ? 1 : -1;
self.movementSpeed = 2 + Math.random() * 2;
self.verticalSpeed = 0.5 + Math.random() * 0.5;
self.shootCooldown = 60 + Math.floor(Math.random() * 120);
// Method to create explosion animation
self.explode = function () {
// Stop any movement
self.movementSpeed = 0;
self.verticalSpeed = 0;
// Create explosion animation with tweens
tween(enemyGraphics, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 800,
easing: tween.easeOut
});
// Create red pulsing effect with tint
tween(enemyGraphics, {
tint: 0xff0000
}, {
duration: 300,
easing: tween.linear
});
};
self.update = function () {
// Move horizontally
self.x += self.movementDirection * self.movementSpeed;
// Move vertically (downward)
self.y += self.verticalSpeed;
// Change direction if at screen edge
if (self.x < self.width / 2 || self.x > 2048 - self.width / 2) {
self.movementDirection *= -1;
}
// Maybe shoot
self.shootCooldown--;
if (self.shootCooldown <= 0) {
self.shoot();
self.shootCooldown = 60 + Math.floor(Math.random() * 120);
}
// Check for player collision
if (self.intersects(player)) {
gameOver();
}
// Remove if off bottom of screen
if (self.y > SCREEN_HEIGHT + 100) {
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.shoot = function () {
// Check if this enemy already has a bullet active
var hasActiveBullet = false;
for (var i = 0; i < enemyBullets.length; i++) {
if (enemyBullets[i].owner === self) {
hasActiveBullet = true;
break;
}
}
// Only shoot if no active bullet
if (!hasActiveBullet) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + self.height / 2;
bullet.owner = self; // Mark which enemy shot this bullet
game.addChild(bullet);
enemyBullets.push(bullet);
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletGraphics.width;
self.height = bulletGraphics.height;
self.speed = 12; // Increased speed for faster falling bullets
self.update = function () {
self.y += self.speed;
// Remove if off screen
if (self.y > 2732 + 50) {
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
}
// Check for player collision
if (player && self.intersects(player)) {
// Remove bullet
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
// End game
gameOver();
}
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = platformGraphics.width;
self.height = platformGraphics.height;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = playerGraphics.width;
self.height = playerGraphics.height;
self.velocityY = 0;
self.velocityX = 0;
self.isJumping = false;
self.facingRight = true;
self.shootCooldown = 0;
self.speed = 8;
self.explode = function () {
// Stop any movement
self.velocityX = 0;
self.velocityY = 0;
// Create explosion animation with tweens
tween(playerGraphics, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 800,
easing: tween.easeOut
});
// Create red pulsing effect
tween(playerGraphics, {
tint: 0xff0000
}, {
duration: 300,
easing: tween.linear
});
};
self.jump = function () {
if (!self.isJumping) {
self.velocityY = -20;
self.isJumping = true;
LK.getSound('jump').play();
}
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - self.height / 2;
bullet.direction = 0; // Direction 0 means upward
game.addChild(bullet);
playerBullets.push(bullet);
self.shootCooldown = 15;
LK.getSound('shoot').play();
}
};
self.update = function () {
// Apply direct movement instead of physics
self.x += self.velocityX;
// Decrease shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Boundary checks
if (self.x < self.width / 2) {
self.x = self.width / 2;
}
if (self.x > 2048 - self.width / 2) {
self.x = 2048 - self.width / 2;
}
// Bottom boundary check for player
if (self.y < SCREEN_HEIGHT - 300) {
self.y = self.y;
} else if (self.y > SCREEN_HEIGHT - 150) {
self.y = SCREEN_HEIGHT - 150;
}
// Update facing direction based on velocity
if (self.velocityX > 0) {
self.facingRight = true;
} else if (self.velocityX < 0) {
self.facingRight = false;
}
// Flip player graphic based on direction
if (self.facingRight) {
playerGraphics.scaleX = 1;
} else {
playerGraphics.scaleX = -1;
}
};
self.checkPlatformCollisions = function () {
var wasOnPlatform = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Only check for collision if falling
if (self.velocityY > 0) {
var playerBottom = self.y + self.height / 2;
var platformTop = platform.y - platform.height / 2;
// If player's bottom is at or slightly below platform top
if (Math.abs(playerBottom - platformTop) < 20) {
// And player is horizontally within platform bounds
if (self.x + self.width / 2 > platform.x - platform.width / 2 && self.x - self.width / 2 < platform.x + platform.width / 2) {
// Land on platform
self.y = platformTop - self.height / 2;
self.velocityY = 0;
self.isJumping = false;
wasOnPlatform = true;
}
}
}
}
if (!wasOnPlatform && !self.isJumping && self.velocityY === 0) {
self.isJumping = true;
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletGraphics.width;
self.height = bulletGraphics.height;
self.direction = 1; // 1 for right, -1 for left
self.speed = 20;
self.update = function () {
// If direction is 0, move upward, otherwise use horizontal movement
if (self.direction === 0) {
self.y -= self.speed;
} else {
self.x += self.speed * self.direction;
}
// Remove if off screen
if (self.x < -50 || self.x > 2048 + 50 || self.y < -50) {
self.destroy();
var index = playerBullets.indexOf(self);
if (index > -1) {
playerBullets.splice(index, 1);
}
}
// Check for enemy collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
// Remove bullet
self.destroy();
var bulletIndex = playerBullets.indexOf(self);
if (bulletIndex > -1) {
playerBullets.splice(bulletIndex, 1);
}
// Reduce enemy health
enemy.health -= 1;
// Flash enemy to show damage - different color based on remaining health
if (enemy.health == 1) {
LK.effects.flashObject(enemy, 0xff9900, 300); // Orange flash for 1 health remaining
} else {
LK.effects.flashObject(enemy, 0xff0000, 300); // Red flash for other cases
}
// Play hit sound
LK.getSound('enemyHit').play();
// Check if enemy is dead
if (enemy.health <= 0) {
// Play explosion animation
enemy.explode();
// Remove enemy after animation completes
LK.setTimeout(function () {
enemy.destroy();
var enemyIndex = enemies.indexOf(enemy);
if (enemyIndex > -1) {
enemies.splice(enemyIndex, 1);
}
}, 800);
// Increase score
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
}
break;
}
}
// Check for enemy bullet collisions
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var enemyBullet = enemyBullets[i];
if (self.intersects(enemyBullet)) {
// Remove enemy bullet
enemyBullet.destroy();
var enemyBulletIndex = enemyBullets.indexOf(enemyBullet);
if (enemyBulletIndex > -1) {
enemyBullets.splice(enemyBulletIndex, 1);
}
// Remove player bullet
self.destroy();
var playerBulletIndex = playerBullets.indexOf(self);
if (playerBulletIndex > -1) {
playerBullets.splice(playerBulletIndex, 1);
}
// Flash effect for bullet collision
LK.effects.flashObject(enemyBullet, 0xffff00, 100);
// Increase score slightly
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
break;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Constants
var GRAVITY = 0.8;
var SCREEN_WIDTH = 2048;
var SCREEN_HEIGHT = 2732;
var PLATFORM_COUNT = 8;
var MAX_ENEMIES = 6;
// Game variables
var player;
var platforms = [];
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var gameStarted = false;
var spawnTimer = 0;
var jumpButton, shootButton, moveLeftButton, moveRightButton;
var scoreTxt;
function initGame() {
// Add background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Add score display
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -20;
scoreTxt.y = 20;
// Create player
player = new Player();
player.x = SCREEN_WIDTH / 2;
player.y = SCREEN_HEIGHT - 200; // Position at bottom of screen
game.addChild(player);
// Create initial platforms
generatePlatforms();
// Create UI controls
createControls();
// Start game music
LK.playMusic('gameMusic');
// Remove start screen text
if (startText && startText.parent) {
startText.parent.removeChild(startText);
}
if (instructionsText && instructionsText.parent) {
instructionsText.parent.removeChild(instructionsText);
}
// Set game as started
gameStarted = true;
}
function generatePlatforms() {
// No platforms needed for vertical shooter
}
function createControls() {
// Shoot button
shootButton = new Button('shootButton', function () {
player.shoot();
});
shootButton.x = SCREEN_WIDTH - 200;
shootButton.y = SCREEN_HEIGHT - 200;
game.addChild(shootButton);
// Move left button
moveLeftButton = new Button('moveLeftButton');
moveLeftButton.x = 200;
moveLeftButton.y = SCREEN_HEIGHT - 200;
game.addChild(moveLeftButton);
// Move right button
moveRightButton = new Button('moveRightButton');
moveRightButton.x = 400;
moveRightButton.y = SCREEN_HEIGHT - 200;
game.addChild(moveRightButton);
}
function spawnEnemy() {
if (enemies.length < MAX_ENEMIES) {
var enemy = new Enemy();
enemy.x = Math.random() * (SCREEN_WIDTH - 200) + 100;
enemy.y = 100;
game.addChild(enemy);
enemies.push(enemy);
}
}
function gameOver() {
LK.getSound('playerHit').play();
LK.effects.flashScreen(0xff0000, 500);
// Trigger player explosion animation
player.explode();
// Delay the game over screen to let explosion animation play
LK.setTimeout(function () {
LK.showGameOver();
}, 800);
}
function handleMove(x, y, obj) {
// We don't need to handle move events for this game
}
function handleDown(x, y, obj) {
// Start the game on first touch if not started
if (!gameStarted) {
initGame();
return;
}
}
function handleUp(x, y, obj) {
// We'll handle button releases in their own event handlers
}
// Game event handlers
game.move = handleMove;
game.down = handleDown;
game.up = handleUp;
// Main game update loop
game.update = function () {
if (!gameStarted) {
return;
}
// Handle player movement from buttons
if (moveLeftButton.isPressed) {
player.velocityX = -player.speed;
} else if (moveRightButton.isPressed) {
player.velocityX = player.speed;
} else {
player.velocityX = 0;
}
// Update player
player.update();
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
playerBullets[i].update();
}
// Update enemies
for (var i = 0; i < enemies.length; i++) {
enemies[i].update();
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
enemyBullets[i].update();
}
// Spawn enemies
spawnTimer++;
if (spawnTimer >= 120) {
// Every 2 seconds
spawnEnemy();
spawnTimer = 0;
}
// No screen boundary game over for vertical shooter
};
// Start screen message
var startText = new Text2('Tap to Start', {
size: 70,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = SCREEN_WIDTH / 2;
startText.y = SCREEN_HEIGHT / 2;
game.addChild(startText);
// Instructions
var instructionsText = new Text2('Use left/right buttons to move\nTap Shoot to fire at enemies from above', {
size: 40,
fill: 0xCCCCCC
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = SCREEN_WIDTH / 2;
instructionsText.y = SCREEN_HEIGHT / 2 + 200;
game.addChild(instructionsText);
; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Button = Container.expand(function (assetId, callback) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.width = buttonGraphics.width;
self.height = buttonGraphics.height;
self.callback = callback;
self.down = function () {
buttonGraphics.alpha = 0.9;
self.isPressed = true;
if (self.callback) {
self.callback();
}
};
self.up = function () {
buttonGraphics.alpha = 0.7;
self.isPressed = false;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemyGraphics.width;
self.height = enemyGraphics.height;
self.health = 2; // Enemy needs 2 hits to die
self.movementDirection = Math.random() > 0.5 ? 1 : -1;
self.movementSpeed = 2 + Math.random() * 2;
self.verticalSpeed = 0.5 + Math.random() * 0.5;
self.shootCooldown = 60 + Math.floor(Math.random() * 120);
// Method to create explosion animation
self.explode = function () {
// Stop any movement
self.movementSpeed = 0;
self.verticalSpeed = 0;
// Create explosion animation with tweens
tween(enemyGraphics, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 800,
easing: tween.easeOut
});
// Create red pulsing effect with tint
tween(enemyGraphics, {
tint: 0xff0000
}, {
duration: 300,
easing: tween.linear
});
};
self.update = function () {
// Move horizontally
self.x += self.movementDirection * self.movementSpeed;
// Move vertically (downward)
self.y += self.verticalSpeed;
// Change direction if at screen edge
if (self.x < self.width / 2 || self.x > 2048 - self.width / 2) {
self.movementDirection *= -1;
}
// Maybe shoot
self.shootCooldown--;
if (self.shootCooldown <= 0) {
self.shoot();
self.shootCooldown = 60 + Math.floor(Math.random() * 120);
}
// Check for player collision
if (self.intersects(player)) {
gameOver();
}
// Remove if off bottom of screen
if (self.y > SCREEN_HEIGHT + 100) {
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.shoot = function () {
// Check if this enemy already has a bullet active
var hasActiveBullet = false;
for (var i = 0; i < enemyBullets.length; i++) {
if (enemyBullets[i].owner === self) {
hasActiveBullet = true;
break;
}
}
// Only shoot if no active bullet
if (!hasActiveBullet) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + self.height / 2;
bullet.owner = self; // Mark which enemy shot this bullet
game.addChild(bullet);
enemyBullets.push(bullet);
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletGraphics.width;
self.height = bulletGraphics.height;
self.speed = 12; // Increased speed for faster falling bullets
self.update = function () {
self.y += self.speed;
// Remove if off screen
if (self.y > 2732 + 50) {
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
}
// Check for player collision
if (player && self.intersects(player)) {
// Remove bullet
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
// End game
gameOver();
}
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = platformGraphics.width;
self.height = platformGraphics.height;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = playerGraphics.width;
self.height = playerGraphics.height;
self.velocityY = 0;
self.velocityX = 0;
self.isJumping = false;
self.facingRight = true;
self.shootCooldown = 0;
self.speed = 8;
self.explode = function () {
// Stop any movement
self.velocityX = 0;
self.velocityY = 0;
// Create explosion animation with tweens
tween(playerGraphics, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 800,
easing: tween.easeOut
});
// Create red pulsing effect
tween(playerGraphics, {
tint: 0xff0000
}, {
duration: 300,
easing: tween.linear
});
};
self.jump = function () {
if (!self.isJumping) {
self.velocityY = -20;
self.isJumping = true;
LK.getSound('jump').play();
}
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - self.height / 2;
bullet.direction = 0; // Direction 0 means upward
game.addChild(bullet);
playerBullets.push(bullet);
self.shootCooldown = 15;
LK.getSound('shoot').play();
}
};
self.update = function () {
// Apply direct movement instead of physics
self.x += self.velocityX;
// Decrease shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Boundary checks
if (self.x < self.width / 2) {
self.x = self.width / 2;
}
if (self.x > 2048 - self.width / 2) {
self.x = 2048 - self.width / 2;
}
// Bottom boundary check for player
if (self.y < SCREEN_HEIGHT - 300) {
self.y = self.y;
} else if (self.y > SCREEN_HEIGHT - 150) {
self.y = SCREEN_HEIGHT - 150;
}
// Update facing direction based on velocity
if (self.velocityX > 0) {
self.facingRight = true;
} else if (self.velocityX < 0) {
self.facingRight = false;
}
// Flip player graphic based on direction
if (self.facingRight) {
playerGraphics.scaleX = 1;
} else {
playerGraphics.scaleX = -1;
}
};
self.checkPlatformCollisions = function () {
var wasOnPlatform = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Only check for collision if falling
if (self.velocityY > 0) {
var playerBottom = self.y + self.height / 2;
var platformTop = platform.y - platform.height / 2;
// If player's bottom is at or slightly below platform top
if (Math.abs(playerBottom - platformTop) < 20) {
// And player is horizontally within platform bounds
if (self.x + self.width / 2 > platform.x - platform.width / 2 && self.x - self.width / 2 < platform.x + platform.width / 2) {
// Land on platform
self.y = platformTop - self.height / 2;
self.velocityY = 0;
self.isJumping = false;
wasOnPlatform = true;
}
}
}
}
if (!wasOnPlatform && !self.isJumping && self.velocityY === 0) {
self.isJumping = true;
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletGraphics.width;
self.height = bulletGraphics.height;
self.direction = 1; // 1 for right, -1 for left
self.speed = 20;
self.update = function () {
// If direction is 0, move upward, otherwise use horizontal movement
if (self.direction === 0) {
self.y -= self.speed;
} else {
self.x += self.speed * self.direction;
}
// Remove if off screen
if (self.x < -50 || self.x > 2048 + 50 || self.y < -50) {
self.destroy();
var index = playerBullets.indexOf(self);
if (index > -1) {
playerBullets.splice(index, 1);
}
}
// Check for enemy collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
// Remove bullet
self.destroy();
var bulletIndex = playerBullets.indexOf(self);
if (bulletIndex > -1) {
playerBullets.splice(bulletIndex, 1);
}
// Reduce enemy health
enemy.health -= 1;
// Flash enemy to show damage - different color based on remaining health
if (enemy.health == 1) {
LK.effects.flashObject(enemy, 0xff9900, 300); // Orange flash for 1 health remaining
} else {
LK.effects.flashObject(enemy, 0xff0000, 300); // Red flash for other cases
}
// Play hit sound
LK.getSound('enemyHit').play();
// Check if enemy is dead
if (enemy.health <= 0) {
// Play explosion animation
enemy.explode();
// Remove enemy after animation completes
LK.setTimeout(function () {
enemy.destroy();
var enemyIndex = enemies.indexOf(enemy);
if (enemyIndex > -1) {
enemies.splice(enemyIndex, 1);
}
}, 800);
// Increase score
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
}
break;
}
}
// Check for enemy bullet collisions
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var enemyBullet = enemyBullets[i];
if (self.intersects(enemyBullet)) {
// Remove enemy bullet
enemyBullet.destroy();
var enemyBulletIndex = enemyBullets.indexOf(enemyBullet);
if (enemyBulletIndex > -1) {
enemyBullets.splice(enemyBulletIndex, 1);
}
// Remove player bullet
self.destroy();
var playerBulletIndex = playerBullets.indexOf(self);
if (playerBulletIndex > -1) {
playerBullets.splice(playerBulletIndex, 1);
}
// Flash effect for bullet collision
LK.effects.flashObject(enemyBullet, 0xffff00, 100);
// Increase score slightly
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
break;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Constants
var GRAVITY = 0.8;
var SCREEN_WIDTH = 2048;
var SCREEN_HEIGHT = 2732;
var PLATFORM_COUNT = 8;
var MAX_ENEMIES = 6;
// Game variables
var player;
var platforms = [];
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var gameStarted = false;
var spawnTimer = 0;
var jumpButton, shootButton, moveLeftButton, moveRightButton;
var scoreTxt;
function initGame() {
// Add background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Add score display
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -20;
scoreTxt.y = 20;
// Create player
player = new Player();
player.x = SCREEN_WIDTH / 2;
player.y = SCREEN_HEIGHT - 200; // Position at bottom of screen
game.addChild(player);
// Create initial platforms
generatePlatforms();
// Create UI controls
createControls();
// Start game music
LK.playMusic('gameMusic');
// Remove start screen text
if (startText && startText.parent) {
startText.parent.removeChild(startText);
}
if (instructionsText && instructionsText.parent) {
instructionsText.parent.removeChild(instructionsText);
}
// Set game as started
gameStarted = true;
}
function generatePlatforms() {
// No platforms needed for vertical shooter
}
function createControls() {
// Shoot button
shootButton = new Button('shootButton', function () {
player.shoot();
});
shootButton.x = SCREEN_WIDTH - 200;
shootButton.y = SCREEN_HEIGHT - 200;
game.addChild(shootButton);
// Move left button
moveLeftButton = new Button('moveLeftButton');
moveLeftButton.x = 200;
moveLeftButton.y = SCREEN_HEIGHT - 200;
game.addChild(moveLeftButton);
// Move right button
moveRightButton = new Button('moveRightButton');
moveRightButton.x = 400;
moveRightButton.y = SCREEN_HEIGHT - 200;
game.addChild(moveRightButton);
}
function spawnEnemy() {
if (enemies.length < MAX_ENEMIES) {
var enemy = new Enemy();
enemy.x = Math.random() * (SCREEN_WIDTH - 200) + 100;
enemy.y = 100;
game.addChild(enemy);
enemies.push(enemy);
}
}
function gameOver() {
LK.getSound('playerHit').play();
LK.effects.flashScreen(0xff0000, 500);
// Trigger player explosion animation
player.explode();
// Delay the game over screen to let explosion animation play
LK.setTimeout(function () {
LK.showGameOver();
}, 800);
}
function handleMove(x, y, obj) {
// We don't need to handle move events for this game
}
function handleDown(x, y, obj) {
// Start the game on first touch if not started
if (!gameStarted) {
initGame();
return;
}
}
function handleUp(x, y, obj) {
// We'll handle button releases in their own event handlers
}
// Game event handlers
game.move = handleMove;
game.down = handleDown;
game.up = handleUp;
// Main game update loop
game.update = function () {
if (!gameStarted) {
return;
}
// Handle player movement from buttons
if (moveLeftButton.isPressed) {
player.velocityX = -player.speed;
} else if (moveRightButton.isPressed) {
player.velocityX = player.speed;
} else {
player.velocityX = 0;
}
// Update player
player.update();
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
playerBullets[i].update();
}
// Update enemies
for (var i = 0; i < enemies.length; i++) {
enemies[i].update();
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
enemyBullets[i].update();
}
// Spawn enemies
spawnTimer++;
if (spawnTimer >= 120) {
// Every 2 seconds
spawnEnemy();
spawnTimer = 0;
}
// No screen boundary game over for vertical shooter
};
// Start screen message
var startText = new Text2('Tap to Start', {
size: 70,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = SCREEN_WIDTH / 2;
startText.y = SCREEN_HEIGHT / 2;
game.addChild(startText);
// Instructions
var instructionsText = new Text2('Use left/right buttons to move\nTap Shoot to fire at enemies from above', {
size: 40,
fill: 0xCCCCCC
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = SCREEN_WIDTH / 2;
instructionsText.y = SCREEN_HEIGHT / 2 + 200;
game.addChild(instructionsText);
;