/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LightStick = Container.expand(function () {
var self = Container.call(this);
var stickGraphics = self.attachAsset('lightStick', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.isCollected = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var MemberCard = Container.expand(function () {
var self = Container.call(this);
var cardGraphics = self.attachAsset('memberCard', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.isCollected = false;
self.memberName = '';
self.update = function () {
self.y += self.speed;
};
return self;
});
var Note = Container.expand(function () {
var self = Container.call(this);
var noteGraphics = self.attachAsset('note', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.isGolden = false;
self.isHit = false;
self.lane = 0;
self.makeGolden = function () {
self.isGolden = true;
self.removeChild(noteGraphics);
noteGraphics = self.attachAsset('goldenNote', {
anchorX: 0.5,
anchorY: 0.5
});
};
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a0033
});
/****
* Game Code
****/
// Game variables
var notes = [];
var memberCards = [];
var lightSticks = [];
var hearts = [];
var combo = 0;
var maxCombo = 0;
var health = 3;
var armyBoostActive = false;
var armyBoostTimer = 0;
var noteSpawnTimer = 0;
var powerUpSpawnTimer = 0;
var isGameActive = true;
// Member names for cards
var memberNames = ['RM', 'Jin', 'Suga', 'J-Hope', 'Jimin', 'V', 'Jungkook'];
// Create hit zone
var hitZone = game.addChild(LK.getAsset('hitZone', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
}));
hitZone.x = 2048 / 2;
hitZone.y = 2732 - 200;
// Create lane markers
var lanePositions = [400, 700, 1000, 1300, 1648];
// Create UI elements
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var comboTxt = new Text2('Combo: 0', {
size: 80,
fill: 0x9C27B0
});
comboTxt.anchor.set(0, 0);
comboTxt.x = 150;
comboTxt.y = 200;
LK.gui.topLeft.addChild(comboTxt);
var armyBoostTxt = new Text2('', {
size: 100,
fill: 0xFFD700
});
armyBoostTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(armyBoostTxt);
// Create health hearts
for (var i = 0; i < 3; i++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heart.x = 150 + i * 80;
heart.y = 100;
hearts.push(heart);
LK.gui.topLeft.addChild(heart);
}
// Helper functions
function spawnNote() {
var note = new Note();
var laneIndex = Math.floor(Math.random() * lanePositions.length);
note.x = lanePositions[laneIndex];
note.y = -50;
note.lane = laneIndex;
// 15% chance for golden note
if (Math.random() < 0.15) {
note.makeGolden();
}
notes.push(note);
game.addChild(note);
}
function spawnMemberCard() {
var card = new MemberCard();
card.x = Math.random() * 1648 + 200;
card.y = -100;
card.memberName = memberNames[Math.floor(Math.random() * memberNames.length)];
memberCards.push(card);
game.addChild(card);
}
function spawnLightStick() {
var stick = new LightStick();
stick.x = Math.random() * 1648 + 200;
stick.y = -100;
lightSticks.push(stick);
game.addChild(stick);
}
function hitNote(note) {
if (note.isHit) return;
note.isHit = true;
var points = note.isGolden ? 200 : 100;
// Army boost multiplier
if (armyBoostActive) {
points *= 2;
}
// Combo multiplier
combo++;
if (combo > maxCombo) maxCombo = combo;
if (combo >= 10) {
points *= Math.floor(combo / 10) + 1;
}
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore().toString());
comboTxt.setText('Combo: ' + combo);
// Play sound
if (note.isGolden) {
LK.getSound('bonus').play();
} else {
LK.getSound('hit').play();
}
// Army boost trigger
if (combo > 0 && combo % 20 === 0) {
activateArmyBoost();
}
// Flash effect
LK.effects.flashObject(note, 0xffd700, 300);
// Remove note
var index = notes.indexOf(note);
if (index > -1) {
notes.splice(index, 1);
note.destroy();
}
}
function missNote() {
combo = 0;
comboTxt.setText('Combo: 0');
health--;
// Update hearts
if (health >= 0 && health < hearts.length) {
hearts[health].alpha = 0.3;
}
LK.getSound('miss').play();
LK.effects.flashScreen(0xff0000, 500);
if (health <= 0) {
isGameActive = false;
LK.showGameOver();
}
}
function activateArmyBoost() {
armyBoostActive = true;
armyBoostTimer = 300; // 5 seconds at 60fps
armyBoostTxt.setText('ARMY BOOST!');
armyBoostTxt.alpha = 1;
// Animate text
tween(armyBoostTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
tween(armyBoostTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
function checkNoteHit(x, y) {
var hitZoneTop = hitZone.y - 60;
var hitZoneBottom = hitZone.y + 60;
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
if (note.isHit) continue;
var noteLeft = note.x - 60;
var noteRight = note.x + 60;
if (x >= noteLeft && x <= noteRight && note.y >= hitZoneTop && note.y <= hitZoneBottom) {
hitNote(note);
return true;
}
}
return false;
}
// Game events
game.down = function (x, y, obj) {
if (!isGameActive) return;
if (!checkNoteHit(x, y)) {
missNote();
}
};
// Main game loop
game.update = function () {
if (!isGameActive) return;
// Spawn notes
noteSpawnTimer++;
if (noteSpawnTimer >= 40) {
// Spawn every ~0.67 seconds
spawnNote();
noteSpawnTimer = 0;
}
// Spawn power-ups
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= 200) {
// Spawn every ~3.33 seconds
if (Math.random() < 0.6) {
spawnMemberCard();
} else {
spawnLightStick();
}
powerUpSpawnTimer = 0;
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
// Check if note passed hit zone without being hit
if (!note.isHit && note.y > hitZone.y + 100) {
missNote();
notes.splice(i, 1);
note.destroy();
continue;
}
// Remove notes that are off screen
if (note.y > 2732 + 100) {
notes.splice(i, 1);
note.destroy();
}
}
// Update member cards
for (var i = memberCards.length - 1; i >= 0; i--) {
var card = memberCards[i];
// Check collision with hit zone
if (!card.isCollected && card.y > hitZone.y - 100 && card.y < hitZone.y + 100) {
card.isCollected = true;
var bonusPoints = 300;
if (armyBoostActive) bonusPoints *= 2;
LK.setScore(LK.getScore() + bonusPoints);
scoreTxt.setText(LK.getScore().toString());
LK.getSound('bonus').play();
memberCards.splice(i, 1);
card.destroy();
continue;
}
// Remove cards that are off screen
if (card.y > 2732 + 100) {
memberCards.splice(i, 1);
card.destroy();
}
}
// Update light sticks
for (var i = lightSticks.length - 1; i >= 0; i--) {
var stick = lightSticks[i];
// Check collision with hit zone
if (!stick.isCollected && stick.y > hitZone.y - 100 && stick.y < hitZone.y + 100) {
stick.isCollected = true;
// Restore health
if (health < 3) {
hearts[health].alpha = 1;
health++;
}
LK.getSound('bonus').play();
lightSticks.splice(i, 1);
stick.destroy();
continue;
}
// Remove sticks that are off screen
if (stick.y > 2732 + 100) {
lightSticks.splice(i, 1);
stick.destroy();
}
}
// Update Army boost
if (armyBoostActive) {
armyBoostTimer--;
if (armyBoostTimer <= 0) {
armyBoostActive = false;
armyBoostTxt.setText('');
armyBoostTxt.alpha = 0;
} else if (armyBoostTimer < 60) {
// Fade out effect
armyBoostTxt.alpha = armyBoostTimer / 60;
}
}
// Check win condition
if (LK.getScore() >= 10000) {
isGameActive = false;
LK.showYouWin();
}
};
// Start the music
LK.playMusic('btsTrack'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LightStick = Container.expand(function () {
var self = Container.call(this);
var stickGraphics = self.attachAsset('lightStick', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.isCollected = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var MemberCard = Container.expand(function () {
var self = Container.call(this);
var cardGraphics = self.attachAsset('memberCard', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.isCollected = false;
self.memberName = '';
self.update = function () {
self.y += self.speed;
};
return self;
});
var Note = Container.expand(function () {
var self = Container.call(this);
var noteGraphics = self.attachAsset('note', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.isGolden = false;
self.isHit = false;
self.lane = 0;
self.makeGolden = function () {
self.isGolden = true;
self.removeChild(noteGraphics);
noteGraphics = self.attachAsset('goldenNote', {
anchorX: 0.5,
anchorY: 0.5
});
};
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a0033
});
/****
* Game Code
****/
// Game variables
var notes = [];
var memberCards = [];
var lightSticks = [];
var hearts = [];
var combo = 0;
var maxCombo = 0;
var health = 3;
var armyBoostActive = false;
var armyBoostTimer = 0;
var noteSpawnTimer = 0;
var powerUpSpawnTimer = 0;
var isGameActive = true;
// Member names for cards
var memberNames = ['RM', 'Jin', 'Suga', 'J-Hope', 'Jimin', 'V', 'Jungkook'];
// Create hit zone
var hitZone = game.addChild(LK.getAsset('hitZone', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
}));
hitZone.x = 2048 / 2;
hitZone.y = 2732 - 200;
// Create lane markers
var lanePositions = [400, 700, 1000, 1300, 1648];
// Create UI elements
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var comboTxt = new Text2('Combo: 0', {
size: 80,
fill: 0x9C27B0
});
comboTxt.anchor.set(0, 0);
comboTxt.x = 150;
comboTxt.y = 200;
LK.gui.topLeft.addChild(comboTxt);
var armyBoostTxt = new Text2('', {
size: 100,
fill: 0xFFD700
});
armyBoostTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(armyBoostTxt);
// Create health hearts
for (var i = 0; i < 3; i++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heart.x = 150 + i * 80;
heart.y = 100;
hearts.push(heart);
LK.gui.topLeft.addChild(heart);
}
// Helper functions
function spawnNote() {
var note = new Note();
var laneIndex = Math.floor(Math.random() * lanePositions.length);
note.x = lanePositions[laneIndex];
note.y = -50;
note.lane = laneIndex;
// 15% chance for golden note
if (Math.random() < 0.15) {
note.makeGolden();
}
notes.push(note);
game.addChild(note);
}
function spawnMemberCard() {
var card = new MemberCard();
card.x = Math.random() * 1648 + 200;
card.y = -100;
card.memberName = memberNames[Math.floor(Math.random() * memberNames.length)];
memberCards.push(card);
game.addChild(card);
}
function spawnLightStick() {
var stick = new LightStick();
stick.x = Math.random() * 1648 + 200;
stick.y = -100;
lightSticks.push(stick);
game.addChild(stick);
}
function hitNote(note) {
if (note.isHit) return;
note.isHit = true;
var points = note.isGolden ? 200 : 100;
// Army boost multiplier
if (armyBoostActive) {
points *= 2;
}
// Combo multiplier
combo++;
if (combo > maxCombo) maxCombo = combo;
if (combo >= 10) {
points *= Math.floor(combo / 10) + 1;
}
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore().toString());
comboTxt.setText('Combo: ' + combo);
// Play sound
if (note.isGolden) {
LK.getSound('bonus').play();
} else {
LK.getSound('hit').play();
}
// Army boost trigger
if (combo > 0 && combo % 20 === 0) {
activateArmyBoost();
}
// Flash effect
LK.effects.flashObject(note, 0xffd700, 300);
// Remove note
var index = notes.indexOf(note);
if (index > -1) {
notes.splice(index, 1);
note.destroy();
}
}
function missNote() {
combo = 0;
comboTxt.setText('Combo: 0');
health--;
// Update hearts
if (health >= 0 && health < hearts.length) {
hearts[health].alpha = 0.3;
}
LK.getSound('miss').play();
LK.effects.flashScreen(0xff0000, 500);
if (health <= 0) {
isGameActive = false;
LK.showGameOver();
}
}
function activateArmyBoost() {
armyBoostActive = true;
armyBoostTimer = 300; // 5 seconds at 60fps
armyBoostTxt.setText('ARMY BOOST!');
armyBoostTxt.alpha = 1;
// Animate text
tween(armyBoostTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
tween(armyBoostTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
function checkNoteHit(x, y) {
var hitZoneTop = hitZone.y - 60;
var hitZoneBottom = hitZone.y + 60;
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
if (note.isHit) continue;
var noteLeft = note.x - 60;
var noteRight = note.x + 60;
if (x >= noteLeft && x <= noteRight && note.y >= hitZoneTop && note.y <= hitZoneBottom) {
hitNote(note);
return true;
}
}
return false;
}
// Game events
game.down = function (x, y, obj) {
if (!isGameActive) return;
if (!checkNoteHit(x, y)) {
missNote();
}
};
// Main game loop
game.update = function () {
if (!isGameActive) return;
// Spawn notes
noteSpawnTimer++;
if (noteSpawnTimer >= 40) {
// Spawn every ~0.67 seconds
spawnNote();
noteSpawnTimer = 0;
}
// Spawn power-ups
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= 200) {
// Spawn every ~3.33 seconds
if (Math.random() < 0.6) {
spawnMemberCard();
} else {
spawnLightStick();
}
powerUpSpawnTimer = 0;
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
// Check if note passed hit zone without being hit
if (!note.isHit && note.y > hitZone.y + 100) {
missNote();
notes.splice(i, 1);
note.destroy();
continue;
}
// Remove notes that are off screen
if (note.y > 2732 + 100) {
notes.splice(i, 1);
note.destroy();
}
}
// Update member cards
for (var i = memberCards.length - 1; i >= 0; i--) {
var card = memberCards[i];
// Check collision with hit zone
if (!card.isCollected && card.y > hitZone.y - 100 && card.y < hitZone.y + 100) {
card.isCollected = true;
var bonusPoints = 300;
if (armyBoostActive) bonusPoints *= 2;
LK.setScore(LK.getScore() + bonusPoints);
scoreTxt.setText(LK.getScore().toString());
LK.getSound('bonus').play();
memberCards.splice(i, 1);
card.destroy();
continue;
}
// Remove cards that are off screen
if (card.y > 2732 + 100) {
memberCards.splice(i, 1);
card.destroy();
}
}
// Update light sticks
for (var i = lightSticks.length - 1; i >= 0; i--) {
var stick = lightSticks[i];
// Check collision with hit zone
if (!stick.isCollected && stick.y > hitZone.y - 100 && stick.y < hitZone.y + 100) {
stick.isCollected = true;
// Restore health
if (health < 3) {
hearts[health].alpha = 1;
health++;
}
LK.getSound('bonus').play();
lightSticks.splice(i, 1);
stick.destroy();
continue;
}
// Remove sticks that are off screen
if (stick.y > 2732 + 100) {
lightSticks.splice(i, 1);
stick.destroy();
}
}
// Update Army boost
if (armyBoostActive) {
armyBoostTimer--;
if (armyBoostTimer <= 0) {
armyBoostActive = false;
armyBoostTxt.setText('');
armyBoostTxt.alpha = 0;
} else if (armyBoostTimer < 60) {
// Fade out effect
armyBoostTxt.alpha = armyBoostTimer / 60;
}
}
// Check win condition
if (LK.getScore() >= 10000) {
isGameActive = false;
LK.showYouWin();
}
};
// Start the music
LK.playMusic('btsTrack');