User prompt
double the size of the text in the how to play scene
User prompt
triple the size of the list text in the how to play scene
User prompt
Reduce the number of particles by half
User prompt
Reduce the number of particles by half
User prompt
Reduce the number of particles by half
User prompt
Increase by 2 the number of bullets required to kill a monster as the levels increase
User prompt
Increase monster speed as levels increase
User prompt
Increase is too much
User prompt
Slowly Increase monsters and monster bombs as the levels increase
User prompt
Increase monsters and monster bombs as the levels increase
User prompt
Add a startup screen before the intro screen. Startup screen should read "Hitokiri presents..." . Wait for 5 s then load intro scene āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught ReferenceError: shootTimer is not defined' in or related to this line: 'if (shootTimer) {' Line Number: 670
User prompt
Add an intro screen that has two buttons : "Start Game" and "How to Play". Start game button starts the game. How to play button opens the help scene
User prompt
Let the background image slide slowly down in parallax as game progresses āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a spa e background image to entire game
User prompt
Increase frequency of life instrument spawn. Reduce frequency of turbo instrument
User prompt
Increase counter icons by 1 when new life gained
User prompt
Spawn life instruments 10 times per level
User prompt
Add life instrument that adds 1 life to user. Show only twice per level āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add life instrument that adds 1 life to user. Show only twice per level āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Start spawning monsters fromlevel 2.
User prompt
Let user lose a life when monster bullet touches any part of gun asset
User prompt
Let user lose a life if monster bullet hits gun
User prompt
Let .monster die after 5 shots
User prompt
Let monster bullet explode and give 1 point when shot āŖš” Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.update = function () { if (self.angle !== undefined) { // Angled movement for turbo bullets self.x += Math.sin(self.angle) * Math.abs(self.speed) * 0.5; self.y += self.speed; } else { // Normal straight movement self.y += self.speed; } }; return self; }); var Guitar = Container.expand(function () { var self = Container.call(this); var guitarGraphics = self.attachAsset('guitar', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.points = 5; self.instrumentType = 'guitar'; self.update = function () { self.x += self.speed; }; return self; }); var Gun = Container.expand(function () { var self = Container.call(this); var gunGraphics = self.attachAsset('gun', { anchorX: 0.5, anchorY: 1 }); self.update = function () { if (facekit.mouthCenter.x > 0) { self.x = facekit.mouthCenter.x; } }; return self; }); var Instrument = Container.expand(function (type) { var self = Container.call(this); var instrumentGraphics = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); self.points = 1; self.instrumentType = type; self.lifespan = 180; // 3 seconds at 60fps self.update = function () { self.lifespan--; }; return self; }); var Monster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('monster', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.shootTimer = 0; self.shootInterval = 120; // Shoot every 2 seconds at 60fps self.health = 3; self.points = 20; self.update = function () { self.x += self.speed; // Reverse direction at screen edges if (self.x <= 150 || self.x >= 1898) { self.speed = -self.speed; } // Shooting timer self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; // Create monster bullet var monsterBullet = new MonsterBullet(); monsterBullet.x = self.x; monsterBullet.y = self.y + 150; monsterBullets.push(monsterBullet); game.addChild(monsterBullet); LK.getSound('monsterShoot').play(); } }; return self; }); var MonsterBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('monsterBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.y += self.speed; }; return self; }); var Particle = Container.expand(function (x, y, type) { var self = Container.call(this); var particleGraphics = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; // Random velocity var angle = Math.random() * Math.PI * 2; var speed = 5 + Math.random() * 10; self.vx = Math.cos(angle) * speed; self.vy = Math.sin(angle) * speed; // Random rotation speed self.rotationSpeed = (Math.random() - 0.5) * 0.3; // Lifetime self.lifetime = 1000; // 1 second // Initial scale self.scaleX = self.scaleY = 1; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var gun; var bullets = []; var guitars = []; var instruments = []; var particles = []; var monsters = []; var monsterBullets = []; var level = 1; var guitarsHit = 0; var timeRemaining = 30; var guitarSpeed = 3; var instrumentSpawnRate = 120; var gameTimer; var spawnTimer = 0; var lives = 3; var turboMode = false; var turboEndTime = 0; var turboTimerBar; var turboTimerContainer; var TURBO_DURATION = 300; // 5 seconds at 60fps // Add HUD background to GUI layer var hudBackground = LK.gui.top.addChild(LK.getAsset('hudBg', { anchorX: 0.5, anchorY: 0 })); hudBackground.x = 0; hudBackground.y = 0; // Adjust width to cover full screen width in GUI coordinates hudBackground.width = LK.gui.top.width; // Initialize gun gun = game.addChild(new Gun()); gun.x = 1024; gun.y = 2600; // Score display var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Level display var levelTxt = new Text2('Level: 1', { size: 60, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); levelTxt.anchor.set(1, 0); levelTxt.x = -20; LK.gui.topRight.addChild(levelTxt); // Timer display - larger and more prominent var timerTxt = new Text2('30', { size: 120, fill: 0xFFFFFF }); timerTxt.anchor.set(1, 0); timerTxt.x = -20; timerTxt.y = 80; LK.gui.topRight.addChild(timerTxt); // Guitars hit display var guitarsHitTxt = new Text2('Guitars: 0/3', { size: 60, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); guitarsHitTxt.anchor.set(0.5, 0); guitarsHitTxt.y = 100; LK.gui.top.addChild(guitarsHitTxt); // Lives display container var livesContainer = new Container(); livesContainer.x = -100; livesContainer.y = -100; LK.gui.bottomRight.addChild(livesContainer); // Create life icons var lifeIcons = []; for (var i = 0; i < 3; i++) { var lifeIcon = LK.getAsset('life', { anchorX: 0.5, anchorY: 0.5 }); lifeIcon.x = -i * 70; // Changed to position icons to the left lifeIcon.y = 0; lifeIcons.push(lifeIcon); livesContainer.addChild(lifeIcon); } // Create turbo timer bar container (initially hidden) turboTimerContainer = new Container(); turboTimerContainer.x = 20; turboTimerContainer.y = -60; turboTimerContainer.visible = false; LK.gui.bottomLeft.addChild(turboTimerContainer); // Timer bar background var timerBarBg = LK.getAsset('hudBg', { anchorX: 0, anchorY: 0 }); timerBarBg.width = 300; timerBarBg.height = 20; timerBarBg.tint = 0x333333; turboTimerContainer.addChild(timerBarBg); // Timer bar fill turboTimerBar = LK.getAsset('hudBg', { anchorX: 0, anchorY: 0 }); turboTimerBar.width = 300; turboTimerBar.height = 20; turboTimerBar.tint = 0x00ff00; turboTimerContainer.addChild(turboTimerBar); // Start game timer gameTimer = LK.setInterval(function () { timeRemaining--; timerTxt.setText(timeRemaining.toString()); // Add color change when time is running out if (timeRemaining <= 10) { timerTxt.setStyle({ fill: 0xFF0000 }); } else { timerTxt.setStyle({ fill: 0xFFFFFF }); } if (timeRemaining <= 0) { // Lose a life instead of game over lives--; // Remove a life icon if (lifeIcons.length > 0 && lives >= 0) { var removedLife = lifeIcons.pop(); removedLife.destroy(); } // Flash screen red to indicate life lost LK.effects.flashScreen(0xFF0000, 500); // Check if game over if (lives <= 0) { LK.showGameOver(); } else { // Reset timer for next life timeRemaining = 30; timerTxt.setText(timeRemaining.toString()); // Reset timer color timerTxt.setStyle({ fill: 0xFFFFFF }); } } }, 1000); // Create particle explosion effect function createExplosion(x, y) { var particleCount = 15 + Math.floor(Math.random() * 10); for (var i = 0; i < particleCount; i++) { var particleType = Math.random() < 0.5 ? 'particle1' : 'particle2'; var particle = new Particle(x, y, particleType); particles.push(particle); game.addChild(particle); // Animate particle tween(particle, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: particle.lifetime, easing: tween.easeOut, onFinish: function onFinish() { // Particle will be cleaned up in update loop } }); } } // Play background music LK.playMusic('bgmusic'); // Variables for long press shooting var isPressed = false; var shootTimer = null; // Function to create and fire a bullet function fireBullet() { if (turboMode) { // Fire three bullets in spread pattern var angles = [-0.3, 0, 0.3]; // Spread angles in radians for (var i = 0; i < 3; i++) { var newBullet = new Bullet(); newBullet.x = gun.x; newBullet.y = gun.y - 120; // Add angle to bullet movement newBullet.angle = angles[i]; newBullet.speed = -15; bullets.push(newBullet); game.addChild(newBullet); } } else { // Normal single bullet var newBullet = new Bullet(); newBullet.x = gun.x; newBullet.y = gun.y - 120; bullets.push(newBullet); game.addChild(newBullet); } LK.getSound('shoot').play(); } // Screen tap/click handler for shooting game.down = function (x, y, obj) { isPressed = true; // Fire immediately on press fireBullet(); // Start continuous shooting timer shootTimer = LK.setInterval(function () { if (isPressed) { fireBullet(); } }, 200); // Fire every 200ms while pressed }; // Screen release handler to stop shooting game.up = function (x, y, obj) { isPressed = false; if (shootTimer) { LK.clearInterval(shootTimer); shootTimer = null; } }; game.update = function () { // Check turbo mode timer if (turboMode) { var timeLeft = turboEndTime - LK.ticks; if (timeLeft <= 0) { turboMode = false; turboTimerContainer.visible = false; LK.effects.flashScreen(0xffffff, 200); } else { // Update timer bar width based on remaining time var progress = timeLeft / TURBO_DURATION; turboTimerBar.width = 300 * progress; } } // Shooting is now handled by screen tap/click in game.down event // Spawn guitars if (LK.ticks % 180 === 0) { // Every 3 seconds var newGuitar = new Guitar(); newGuitar.x = -60; newGuitar.y = 500; // Moved lower to avoid HUD overlap newGuitar.speed = guitarSpeed; guitars.push(newGuitar); game.addChild(newGuitar); } // Spawn monsters occasionally if (LK.ticks % 600 === 0 && monsters.length < 2) { // Every 10 seconds, max 2 monsters var newMonster = new Monster(); newMonster.x = 300 + Math.random() * 1448; newMonster.y = 400; monsters.push(newMonster); game.addChild(newMonster); } // Spawn random instruments spawnTimer++; if (spawnTimer >= instrumentSpawnRate) { spawnTimer = 0; var types = ['drum', 'flute', 'piano', 'saxophone', 'xylophone', 'tuba', 'harp']; // Only add bomb and turbo to spawn types if not in turbo mode if (!turboMode) { types.push('bomb'); types.push('turbo'); } var type = types[Math.floor(Math.random() * types.length)]; var newInstrument = new Instrument(type); // Try to find a non-overlapping position var maxAttempts = 50; var attempts = 0; var validPosition = false; while (!validPosition && attempts < maxAttempts) { newInstrument.x = 300 + Math.random() * 1448; newInstrument.y = 500 + Math.random() * 1600; // Check if this position overlaps with existing instruments validPosition = true; for (var m = 0; m < instruments.length; m++) { var existingInstrument = instruments[m]; var dx = newInstrument.x - existingInstrument.x; var dy = newInstrument.y - existingInstrument.y; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = 300; // Increased minimum distance between instruments if (distance < minDistance) { validPosition = false; break; } } // If this is a bomb, also check overlap with guitars if (validPosition && type === 'bomb') { for (var n = 0; n < guitars.length; n++) { var guitar = guitars[n]; var dx = newInstrument.x - guitar.x; var dy = newInstrument.y - guitar.y; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = 300; // Same minimum distance for guitars if (distance < minDistance) { validPosition = false; break; } } } attempts++; } // Only add instrument if we found a valid position if (validPosition) { // Set special properties for bomb if (type === 'bomb') { newInstrument.points = -1; // Special marker for bomb newInstrument.instrumentType = 'bomb'; } else if (type === 'turbo') { newInstrument.points = 10; newInstrument.instrumentType = 'turbo'; } instruments.push(newInstrument); game.addChild(newInstrument); } } // Update monster bullets for (var i = monsterBullets.length - 1; i >= 0; i--) { var monsterBullet = monsterBullets[i]; if (monsterBullet.y > 2800) { monsterBullet.destroy(); monsterBullets.splice(i, 1); continue; } // Check collision with gun/player area var dx = monsterBullet.x - gun.x; var dy = monsterBullet.y - gun.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 100) { // Hit player lives--; if (lifeIcons.length > 0 && lives >= 0) { var removedLife = lifeIcons.pop(); removedLife.destroy(); } LK.effects.flashScreen(0xFF0000, 500); createExplosion(monsterBullet.x, monsterBullet.y); monsterBullet.destroy(); monsterBullets.splice(i, 1); if (lives <= 0) { LK.showGameOver(); } continue; } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.y < -20) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check guitar collisions for (var j = guitars.length - 1; j >= 0; j--) { var guitar = guitars[j]; if (bullet.intersects(guitar)) { LK.setScore(LK.getScore() + guitar.points); scoreTxt.setText('Score: ' + LK.getScore()); guitarsHit++; guitarsHitTxt.setText('Guitars: ' + guitarsHit + '/3'); LK.getSound('guitarHit').play(); LK.effects.flashObject(guitar, 0xFFFFFF, 300); createExplosion(guitar.x, guitar.y); guitar.destroy(); guitars.splice(j, 1); bullet.destroy(); bullets.splice(i, 1); // Check level advancement if (guitarsHit >= 3) { level++; levelTxt.setText('Level: ' + level); guitarsHit = 0; guitarsHitTxt.setText('Guitars: 0/3'); timeRemaining = 30; guitarSpeed += 2; // Increase spawn frequency more aggressively: decrease by 30 instead of 20, with minimum of 30 instead of 60 instrumentSpawnRate = Math.max(30, instrumentSpawnRate - 30); } break; } } if (i < 0 || i >= bullets.length) continue; // Check instrument collisions for (var k = instruments.length - 1; k >= 0; k--) { var instrument = instruments[k]; if (bullet.intersects(instrument)) { // Handle bomb collision if (instrument.instrumentType === 'bomb') { lives--; // Remove a life icon if (lifeIcons.length > 0 && lives >= 0) { var removedLife = lifeIcons.pop(); removedLife.destroy(); } LK.effects.flashScreen(0xFF0000, 500); LK.getSound('bombHit').play(); if (lives <= 0) { LK.showGameOver(); } } else if (instrument.instrumentType === 'turbo') { // Activate turbo mode turboMode = true; turboEndTime = LK.ticks + TURBO_DURATION; turboTimerContainer.visible = true; LK.effects.flashScreen(0x00ff00, 300); LK.getSound('turboHit').play(); LK.setScore(LK.getScore() + 10); scoreTxt.setText('Score: ' + LK.getScore()); } else { // Normal instrument hit LK.setScore(LK.getScore() + instrument.points); scoreTxt.setText('Score: ' + LK.getScore()); // Play specific sound based on instrument type if (instrument.instrumentType === 'drum') { LK.getSound('drumHit').play(); } else if (instrument.instrumentType === 'flute') { LK.getSound('fluteHit').play(); } else if (instrument.instrumentType === 'piano') { LK.getSound('pianoHit').play(); } else if (instrument.instrumentType === 'saxophone') { LK.getSound('saxophoneHit').play(); } else if (instrument.instrumentType === 'xylophone') { LK.getSound('xylophoneHit').play(); } else if (instrument.instrumentType === 'tuba') { LK.getSound('tubaHit').play(); } else if (instrument.instrumentType === 'harp') { LK.getSound('harpHit').play(); } } LK.effects.flashObject(instrument, 0xFFFFFF, 300); createExplosion(instrument.x, instrument.y); instrument.destroy(); instruments.splice(k, 1); bullet.destroy(); bullets.splice(i, 1); break; } } if (i < 0 || i >= bullets.length) continue; // Check monster bullet collisions for (var mb = monsterBullets.length - 1; mb >= 0; mb--) { var monsterBullet = monsterBullets[mb]; if (bullet.intersects(monsterBullet)) { // Award 1 point for shooting monster bullet LK.setScore(LK.getScore() + 1); scoreTxt.setText('Score: ' + LK.getScore()); // Create explosion effect createExplosion(monsterBullet.x, monsterBullet.y); // Destroy both bullets monsterBullet.destroy(); monsterBullets.splice(mb, 1); bullet.destroy(); bullets.splice(i, 1); break; } } if (i < 0 || i >= bullets.length) continue; // Check monster collisions for (var m = monsters.length - 1; m >= 0; m--) { var monster = monsters[m]; if (bullet.intersects(monster)) { monster.health--; createExplosion(bullet.x, bullet.y); bullet.destroy(); bullets.splice(i, 1); if (monster.health <= 0) { LK.setScore(LK.getScore() + monster.points); scoreTxt.setText('Score: ' + LK.getScore()); createExplosion(monster.x, monster.y); monster.destroy(); monsters.splice(m, 1); } else { LK.effects.flashObject(monster, 0xFF0000, 200); } break; } } } // Update guitars for (var i = guitars.length - 1; i >= 0; i--) { var guitar = guitars[i]; // Check for collisions with instruments and destroy them for (var q = instruments.length - 1; q >= 0; q--) { var instrument = instruments[q]; if (guitar.intersects(instrument)) { // Create explosion effect createExplosion(instrument.x, instrument.y); // Destroy the instrument instrument.destroy(); instruments.splice(q, 1); } } if (guitar.x > 2108) { guitar.destroy(); guitars.splice(i, 1); } } // Update instruments for (var i = instruments.length - 1; i >= 0; i--) { var instrument = instruments[i]; if (instrument.lifespan <= 0) { instrument.destroy(); instruments.splice(i, 1); } } // Update particles for (var i = particles.length - 1; i >= 0; i--) { var particle = particles[i]; // Update position particle.x += particle.vx; particle.y += particle.vy; // Apply gravity particle.vy += 0.5; // Apply rotation particle.rotation += particle.rotationSpeed; // Slow down horizontal movement particle.vx *= 0.98; // Remove dead particles if (particle.alpha <= 0) { particle.destroy(); particles.splice(i, 1); } } // Update monsters (cleanup if needed) for (var i = monsters.length - 1; i >= 0; i--) { var monster = monsters[i]; // Monsters are persistent, only removed when destroyed by bullets } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.update = function () {
if (self.angle !== undefined) {
// Angled movement for turbo bullets
self.x += Math.sin(self.angle) * Math.abs(self.speed) * 0.5;
self.y += self.speed;
} else {
// Normal straight movement
self.y += self.speed;
}
};
return self;
});
var Guitar = Container.expand(function () {
var self = Container.call(this);
var guitarGraphics = self.attachAsset('guitar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.points = 5;
self.instrumentType = 'guitar';
self.update = function () {
self.x += self.speed;
};
return self;
});
var Gun = Container.expand(function () {
var self = Container.call(this);
var gunGraphics = self.attachAsset('gun', {
anchorX: 0.5,
anchorY: 1
});
self.update = function () {
if (facekit.mouthCenter.x > 0) {
self.x = facekit.mouthCenter.x;
}
};
return self;
});
var Instrument = Container.expand(function (type) {
var self = Container.call(this);
var instrumentGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 1;
self.instrumentType = type;
self.lifespan = 180; // 3 seconds at 60fps
self.update = function () {
self.lifespan--;
};
return self;
});
var Monster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.shootTimer = 0;
self.shootInterval = 120; // Shoot every 2 seconds at 60fps
self.health = 3;
self.points = 20;
self.update = function () {
self.x += self.speed;
// Reverse direction at screen edges
if (self.x <= 150 || self.x >= 1898) {
self.speed = -self.speed;
}
// Shooting timer
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
// Create monster bullet
var monsterBullet = new MonsterBullet();
monsterBullet.x = self.x;
monsterBullet.y = self.y + 150;
monsterBullets.push(monsterBullet);
game.addChild(monsterBullet);
LK.getSound('monsterShoot').play();
}
};
return self;
});
var MonsterBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('monsterBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Particle = Container.expand(function (x, y, type) {
var self = Container.call(this);
var particleGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
// Random velocity
var angle = Math.random() * Math.PI * 2;
var speed = 5 + Math.random() * 10;
self.vx = Math.cos(angle) * speed;
self.vy = Math.sin(angle) * speed;
// Random rotation speed
self.rotationSpeed = (Math.random() - 0.5) * 0.3;
// Lifetime
self.lifetime = 1000; // 1 second
// Initial scale
self.scaleX = self.scaleY = 1;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var gun;
var bullets = [];
var guitars = [];
var instruments = [];
var particles = [];
var monsters = [];
var monsterBullets = [];
var level = 1;
var guitarsHit = 0;
var timeRemaining = 30;
var guitarSpeed = 3;
var instrumentSpawnRate = 120;
var gameTimer;
var spawnTimer = 0;
var lives = 3;
var turboMode = false;
var turboEndTime = 0;
var turboTimerBar;
var turboTimerContainer;
var TURBO_DURATION = 300; // 5 seconds at 60fps
// Add HUD background to GUI layer
var hudBackground = LK.gui.top.addChild(LK.getAsset('hudBg', {
anchorX: 0.5,
anchorY: 0
}));
hudBackground.x = 0;
hudBackground.y = 0;
// Adjust width to cover full screen width in GUI coordinates
hudBackground.width = LK.gui.top.width;
// Initialize gun
gun = game.addChild(new Gun());
gun.x = 1024;
gun.y = 2600;
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0x000000,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Level display
var levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0x000000,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
levelTxt.anchor.set(1, 0);
levelTxt.x = -20;
LK.gui.topRight.addChild(levelTxt);
// Timer display - larger and more prominent
var timerTxt = new Text2('30', {
size: 120,
fill: 0xFFFFFF
});
timerTxt.anchor.set(1, 0);
timerTxt.x = -20;
timerTxt.y = 80;
LK.gui.topRight.addChild(timerTxt);
// Guitars hit display
var guitarsHitTxt = new Text2('Guitars: 0/3', {
size: 60,
fill: 0x000000,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
guitarsHitTxt.anchor.set(0.5, 0);
guitarsHitTxt.y = 100;
LK.gui.top.addChild(guitarsHitTxt);
// Lives display container
var livesContainer = new Container();
livesContainer.x = -100;
livesContainer.y = -100;
LK.gui.bottomRight.addChild(livesContainer);
// Create life icons
var lifeIcons = [];
for (var i = 0; i < 3; i++) {
var lifeIcon = LK.getAsset('life', {
anchorX: 0.5,
anchorY: 0.5
});
lifeIcon.x = -i * 70; // Changed to position icons to the left
lifeIcon.y = 0;
lifeIcons.push(lifeIcon);
livesContainer.addChild(lifeIcon);
}
// Create turbo timer bar container (initially hidden)
turboTimerContainer = new Container();
turboTimerContainer.x = 20;
turboTimerContainer.y = -60;
turboTimerContainer.visible = false;
LK.gui.bottomLeft.addChild(turboTimerContainer);
// Timer bar background
var timerBarBg = LK.getAsset('hudBg', {
anchorX: 0,
anchorY: 0
});
timerBarBg.width = 300;
timerBarBg.height = 20;
timerBarBg.tint = 0x333333;
turboTimerContainer.addChild(timerBarBg);
// Timer bar fill
turboTimerBar = LK.getAsset('hudBg', {
anchorX: 0,
anchorY: 0
});
turboTimerBar.width = 300;
turboTimerBar.height = 20;
turboTimerBar.tint = 0x00ff00;
turboTimerContainer.addChild(turboTimerBar);
// Start game timer
gameTimer = LK.setInterval(function () {
timeRemaining--;
timerTxt.setText(timeRemaining.toString());
// Add color change when time is running out
if (timeRemaining <= 10) {
timerTxt.setStyle({
fill: 0xFF0000
});
} else {
timerTxt.setStyle({
fill: 0xFFFFFF
});
}
if (timeRemaining <= 0) {
// Lose a life instead of game over
lives--;
// Remove a life icon
if (lifeIcons.length > 0 && lives >= 0) {
var removedLife = lifeIcons.pop();
removedLife.destroy();
}
// Flash screen red to indicate life lost
LK.effects.flashScreen(0xFF0000, 500);
// Check if game over
if (lives <= 0) {
LK.showGameOver();
} else {
// Reset timer for next life
timeRemaining = 30;
timerTxt.setText(timeRemaining.toString());
// Reset timer color
timerTxt.setStyle({
fill: 0xFFFFFF
});
}
}
}, 1000);
// Create particle explosion effect
function createExplosion(x, y) {
var particleCount = 15 + Math.floor(Math.random() * 10);
for (var i = 0; i < particleCount; i++) {
var particleType = Math.random() < 0.5 ? 'particle1' : 'particle2';
var particle = new Particle(x, y, particleType);
particles.push(particle);
game.addChild(particle);
// Animate particle
tween(particle, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: particle.lifetime,
easing: tween.easeOut,
onFinish: function onFinish() {
// Particle will be cleaned up in update loop
}
});
}
}
// Play background music
LK.playMusic('bgmusic');
// Variables for long press shooting
var isPressed = false;
var shootTimer = null;
// Function to create and fire a bullet
function fireBullet() {
if (turboMode) {
// Fire three bullets in spread pattern
var angles = [-0.3, 0, 0.3]; // Spread angles in radians
for (var i = 0; i < 3; i++) {
var newBullet = new Bullet();
newBullet.x = gun.x;
newBullet.y = gun.y - 120;
// Add angle to bullet movement
newBullet.angle = angles[i];
newBullet.speed = -15;
bullets.push(newBullet);
game.addChild(newBullet);
}
} else {
// Normal single bullet
var newBullet = new Bullet();
newBullet.x = gun.x;
newBullet.y = gun.y - 120;
bullets.push(newBullet);
game.addChild(newBullet);
}
LK.getSound('shoot').play();
}
// Screen tap/click handler for shooting
game.down = function (x, y, obj) {
isPressed = true;
// Fire immediately on press
fireBullet();
// Start continuous shooting timer
shootTimer = LK.setInterval(function () {
if (isPressed) {
fireBullet();
}
}, 200); // Fire every 200ms while pressed
};
// Screen release handler to stop shooting
game.up = function (x, y, obj) {
isPressed = false;
if (shootTimer) {
LK.clearInterval(shootTimer);
shootTimer = null;
}
};
game.update = function () {
// Check turbo mode timer
if (turboMode) {
var timeLeft = turboEndTime - LK.ticks;
if (timeLeft <= 0) {
turboMode = false;
turboTimerContainer.visible = false;
LK.effects.flashScreen(0xffffff, 200);
} else {
// Update timer bar width based on remaining time
var progress = timeLeft / TURBO_DURATION;
turboTimerBar.width = 300 * progress;
}
}
// Shooting is now handled by screen tap/click in game.down event
// Spawn guitars
if (LK.ticks % 180 === 0) {
// Every 3 seconds
var newGuitar = new Guitar();
newGuitar.x = -60;
newGuitar.y = 500; // Moved lower to avoid HUD overlap
newGuitar.speed = guitarSpeed;
guitars.push(newGuitar);
game.addChild(newGuitar);
}
// Spawn monsters occasionally
if (LK.ticks % 600 === 0 && monsters.length < 2) {
// Every 10 seconds, max 2 monsters
var newMonster = new Monster();
newMonster.x = 300 + Math.random() * 1448;
newMonster.y = 400;
monsters.push(newMonster);
game.addChild(newMonster);
}
// Spawn random instruments
spawnTimer++;
if (spawnTimer >= instrumentSpawnRate) {
spawnTimer = 0;
var types = ['drum', 'flute', 'piano', 'saxophone', 'xylophone', 'tuba', 'harp'];
// Only add bomb and turbo to spawn types if not in turbo mode
if (!turboMode) {
types.push('bomb');
types.push('turbo');
}
var type = types[Math.floor(Math.random() * types.length)];
var newInstrument = new Instrument(type);
// Try to find a non-overlapping position
var maxAttempts = 50;
var attempts = 0;
var validPosition = false;
while (!validPosition && attempts < maxAttempts) {
newInstrument.x = 300 + Math.random() * 1448;
newInstrument.y = 500 + Math.random() * 1600;
// Check if this position overlaps with existing instruments
validPosition = true;
for (var m = 0; m < instruments.length; m++) {
var existingInstrument = instruments[m];
var dx = newInstrument.x - existingInstrument.x;
var dy = newInstrument.y - existingInstrument.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = 300; // Increased minimum distance between instruments
if (distance < minDistance) {
validPosition = false;
break;
}
}
// If this is a bomb, also check overlap with guitars
if (validPosition && type === 'bomb') {
for (var n = 0; n < guitars.length; n++) {
var guitar = guitars[n];
var dx = newInstrument.x - guitar.x;
var dy = newInstrument.y - guitar.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = 300; // Same minimum distance for guitars
if (distance < minDistance) {
validPosition = false;
break;
}
}
}
attempts++;
}
// Only add instrument if we found a valid position
if (validPosition) {
// Set special properties for bomb
if (type === 'bomb') {
newInstrument.points = -1; // Special marker for bomb
newInstrument.instrumentType = 'bomb';
} else if (type === 'turbo') {
newInstrument.points = 10;
newInstrument.instrumentType = 'turbo';
}
instruments.push(newInstrument);
game.addChild(newInstrument);
}
}
// Update monster bullets
for (var i = monsterBullets.length - 1; i >= 0; i--) {
var monsterBullet = monsterBullets[i];
if (monsterBullet.y > 2800) {
monsterBullet.destroy();
monsterBullets.splice(i, 1);
continue;
}
// Check collision with gun/player area
var dx = monsterBullet.x - gun.x;
var dy = monsterBullet.y - gun.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
// Hit player
lives--;
if (lifeIcons.length > 0 && lives >= 0) {
var removedLife = lifeIcons.pop();
removedLife.destroy();
}
LK.effects.flashScreen(0xFF0000, 500);
createExplosion(monsterBullet.x, monsterBullet.y);
monsterBullet.destroy();
monsterBullets.splice(i, 1);
if (lives <= 0) {
LK.showGameOver();
}
continue;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.y < -20) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check guitar collisions
for (var j = guitars.length - 1; j >= 0; j--) {
var guitar = guitars[j];
if (bullet.intersects(guitar)) {
LK.setScore(LK.getScore() + guitar.points);
scoreTxt.setText('Score: ' + LK.getScore());
guitarsHit++;
guitarsHitTxt.setText('Guitars: ' + guitarsHit + '/3');
LK.getSound('guitarHit').play();
LK.effects.flashObject(guitar, 0xFFFFFF, 300);
createExplosion(guitar.x, guitar.y);
guitar.destroy();
guitars.splice(j, 1);
bullet.destroy();
bullets.splice(i, 1);
// Check level advancement
if (guitarsHit >= 3) {
level++;
levelTxt.setText('Level: ' + level);
guitarsHit = 0;
guitarsHitTxt.setText('Guitars: 0/3');
timeRemaining = 30;
guitarSpeed += 2;
// Increase spawn frequency more aggressively: decrease by 30 instead of 20, with minimum of 30 instead of 60
instrumentSpawnRate = Math.max(30, instrumentSpawnRate - 30);
}
break;
}
}
if (i < 0 || i >= bullets.length) continue;
// Check instrument collisions
for (var k = instruments.length - 1; k >= 0; k--) {
var instrument = instruments[k];
if (bullet.intersects(instrument)) {
// Handle bomb collision
if (instrument.instrumentType === 'bomb') {
lives--;
// Remove a life icon
if (lifeIcons.length > 0 && lives >= 0) {
var removedLife = lifeIcons.pop();
removedLife.destroy();
}
LK.effects.flashScreen(0xFF0000, 500);
LK.getSound('bombHit').play();
if (lives <= 0) {
LK.showGameOver();
}
} else if (instrument.instrumentType === 'turbo') {
// Activate turbo mode
turboMode = true;
turboEndTime = LK.ticks + TURBO_DURATION;
turboTimerContainer.visible = true;
LK.effects.flashScreen(0x00ff00, 300);
LK.getSound('turboHit').play();
LK.setScore(LK.getScore() + 10);
scoreTxt.setText('Score: ' + LK.getScore());
} else {
// Normal instrument hit
LK.setScore(LK.getScore() + instrument.points);
scoreTxt.setText('Score: ' + LK.getScore());
// Play specific sound based on instrument type
if (instrument.instrumentType === 'drum') {
LK.getSound('drumHit').play();
} else if (instrument.instrumentType === 'flute') {
LK.getSound('fluteHit').play();
} else if (instrument.instrumentType === 'piano') {
LK.getSound('pianoHit').play();
} else if (instrument.instrumentType === 'saxophone') {
LK.getSound('saxophoneHit').play();
} else if (instrument.instrumentType === 'xylophone') {
LK.getSound('xylophoneHit').play();
} else if (instrument.instrumentType === 'tuba') {
LK.getSound('tubaHit').play();
} else if (instrument.instrumentType === 'harp') {
LK.getSound('harpHit').play();
}
}
LK.effects.flashObject(instrument, 0xFFFFFF, 300);
createExplosion(instrument.x, instrument.y);
instrument.destroy();
instruments.splice(k, 1);
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
if (i < 0 || i >= bullets.length) continue;
// Check monster bullet collisions
for (var mb = monsterBullets.length - 1; mb >= 0; mb--) {
var monsterBullet = monsterBullets[mb];
if (bullet.intersects(monsterBullet)) {
// Award 1 point for shooting monster bullet
LK.setScore(LK.getScore() + 1);
scoreTxt.setText('Score: ' + LK.getScore());
// Create explosion effect
createExplosion(monsterBullet.x, monsterBullet.y);
// Destroy both bullets
monsterBullet.destroy();
monsterBullets.splice(mb, 1);
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
if (i < 0 || i >= bullets.length) continue;
// Check monster collisions
for (var m = monsters.length - 1; m >= 0; m--) {
var monster = monsters[m];
if (bullet.intersects(monster)) {
monster.health--;
createExplosion(bullet.x, bullet.y);
bullet.destroy();
bullets.splice(i, 1);
if (monster.health <= 0) {
LK.setScore(LK.getScore() + monster.points);
scoreTxt.setText('Score: ' + LK.getScore());
createExplosion(monster.x, monster.y);
monster.destroy();
monsters.splice(m, 1);
} else {
LK.effects.flashObject(monster, 0xFF0000, 200);
}
break;
}
}
}
// Update guitars
for (var i = guitars.length - 1; i >= 0; i--) {
var guitar = guitars[i];
// Check for collisions with instruments and destroy them
for (var q = instruments.length - 1; q >= 0; q--) {
var instrument = instruments[q];
if (guitar.intersects(instrument)) {
// Create explosion effect
createExplosion(instrument.x, instrument.y);
// Destroy the instrument
instrument.destroy();
instruments.splice(q, 1);
}
}
if (guitar.x > 2108) {
guitar.destroy();
guitars.splice(i, 1);
}
}
// Update instruments
for (var i = instruments.length - 1; i >= 0; i--) {
var instrument = instruments[i];
if (instrument.lifespan <= 0) {
instrument.destroy();
instruments.splice(i, 1);
}
}
// Update particles
for (var i = particles.length - 1; i >= 0; i--) {
var particle = particles[i];
// Update position
particle.x += particle.vx;
particle.y += particle.vy;
// Apply gravity
particle.vy += 0.5;
// Apply rotation
particle.rotation += particle.rotationSpeed;
// Slow down horizontal movement
particle.vx *= 0.98;
// Remove dead particles
if (particle.alpha <= 0) {
particle.destroy();
particles.splice(i, 1);
}
}
// Update monsters (cleanup if needed)
for (var i = monsters.length - 1; i >= 0; i--) {
var monster = monsters[i];
// Monsters are persistent, only removed when destroyed by bullets
}
};
vertical bullet. In-Game asset. 2d. High contrast. No shadows
drum. In-Game asset. 2d. High contrast. No shadows
Guitar. In-Game asset. 2d. High contrast. No shadows
futuristic space cannon gun vertical top view. In-Game asset. 2d. High contrast. No shadows
piano. In-Game asset. 2d. High contrast. No shadows
saxophone. In-Game asset. 2d. High contrast. No shadows
red bomb. In-Game asset. 2d. High contrast. No shadows
xylophone. In-Game asset. 2d. High contrast. No shadows
gold musical note. In-Game asset. 3d. High contrast. No shadows
red musical note. In-Game asset. 3d. High contrast. No shadows
flute. In-Game asset. 3d. High contrast. No shadows
harp. In-Game asset. 3d. High contrast. No shadows
tuba. In-Game asset. 3d. High contrast. No shadows
Triple vertical bullet. In-Game asset. 3d. High contrast. No shadows
Music maestro monster head . 3d.. In-Game asset. High contrast. No shadows
Dark space background with stars
Bright green glowing musical note. In-Game asset. 3d. High contrast. No shadows
guitarHit
Sound effect
drumHit
Sound effect
fluteHit
Sound effect
pianoHit
Sound effect
saxophoneHit
Sound effect
xylophoneHit
Sound effect
shoot
Sound effect
bombHit
Sound effect
tubaHit
Sound effect
harpHit
Sound effect
turboHit
Sound effect
bgmusic
Music