/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BTSMember = Container.expand(function (memberNumber, xPos) {
var self = Container.call(this);
self.memberNumber = memberNumber;
self.isPerforming = false;
self.animationState = 'idle';
var memberGraphics = self.attachAsset('member' + memberNumber, {
anchorX: 0.5,
anchorY: 1.0
});
var hitZone = self.attachAsset('hitZone', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
self.x = xPos;
self.y = 2200;
hitZone.y = -200;
self.performAnimation = function () {
self.isPerforming = true;
self.animationState = 'performing';
tween(memberGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(memberGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
tween(memberGraphics, {
tint: 0xffffff
}, {
duration: 300,
onFinish: function onFinish() {
tween(memberGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
};
self.idleAnimation = function () {
self.isPerforming = false;
self.animationState = 'idle';
tween(memberGraphics, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(memberGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
};
self.getHitZoneY = function () {
return self.y + hitZone.y;
};
return self;
});
var Note = Container.expand(function (lane, type) {
var self = Container.call(this);
self.lane = lane;
self.type = type || 'normal';
self.speed = 8;
self.isActive = true;
self.hitTiming = 0;
var noteGraphics = self.attachAsset(self.type === 'hold' ? 'holdNote' : 'note', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.isActive) {
self.y += self.speed;
}
};
self.checkHit = function (hitY) {
var distance = Math.abs(self.y - hitY);
if (distance < 50) {
return 'perfect';
} else if (distance < 80) {
return 'good';
} else if (distance < 120) {
return 'ok';
}
return 'miss';
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a0a
});
/****
* Game Code
****/
// Sound effects
// UI elements
// Note types
// BTS character representations
// Stage and background elements
// Game state variables
var gameState = 'playing';
var score = 0;
var combo = 0;
var maxCombo = 0;
var performanceLevel = 100;
var difficulty = 1;
var songPosition = 0;
var nextNoteTime = 0;
// Member positions (7 members spread across stage)
var memberPositions = [200, 400, 600, 800, 1000, 1200, 1400, 1600];
// Create stage
var stage = game.attachAsset('stage', {
anchorX: 0.5,
anchorY: 1.0,
x: 1024,
y: 2200
});
// Create BTS members
var members = [];
for (var i = 0; i < 7; i++) {
var member = new BTSMember(i + 1, memberPositions[i]);
members.push(member);
game.addChild(member);
}
// Create notes array
var notes = [];
// Create UI elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var comboText = new Text2('Combo: 0', {
size: 50,
fill: 0xFFFF00
});
comboText.anchor.set(0.5, 0);
comboText.y = 80;
LK.gui.top.addChild(comboText);
// Performance meter
var performanceMeterBg = LK.gui.bottom.attachAsset('performanceMeter', {
anchorX: 0.5,
anchorY: 1.0,
x: 0,
y: -100
});
var performanceBar = LK.gui.bottom.attachAsset('performanceBar', {
anchorX: 0.0,
anchorY: 1.0,
x: -150,
y: -100
});
// Note patterns for different difficulty levels
var notePatterns = {
1: [{
lane: 0,
time: 60
}, {
lane: 2,
time: 120
}, {
lane: 4,
time: 180
}, {
lane: 6,
time: 240
}, {
lane: 1,
time: 300
}, {
lane: 3,
time: 360
}, {
lane: 5,
time: 420
}, {
lane: 0,
time: 480
}],
2: [{
lane: 0,
time: 30
}, {
lane: 2,
time: 60
}, {
lane: 4,
time: 90
}, {
lane: 6,
time: 120
}, {
lane: 1,
time: 150
}, {
lane: 3,
time: 180
}, {
lane: 5,
time: 210
}, {
lane: 0,
time: 240
}]
};
var currentPattern = notePatterns[difficulty];
var patternIndex = 0;
// Function to spawn notes
function spawnNote(lane, type) {
if (lane < 0 || lane >= members.length) return;
var note = new Note(lane, type);
note.x = members[lane].x;
note.y = 200;
notes.push(note);
game.addChild(note);
}
// Function to update performance meter
function updatePerformanceMeter() {
var percentage = performanceLevel / 100;
performanceBar.scaleX = Math.max(0, percentage);
if (performanceLevel > 70) {
performanceBar.tint = 0x00ff00;
} else if (performanceLevel > 40) {
performanceBar.tint = 0xffff00;
} else {
performanceBar.tint = 0xff0000;
}
}
// Function to handle note hit
function hitNote(note, accuracy) {
var points = 0;
switch (accuracy) {
case 'perfect':
points = 100;
combo++;
performanceLevel = Math.min(100, performanceLevel + 3);
break;
case 'good':
points = 80;
combo++;
performanceLevel = Math.min(100, performanceLevel + 2);
break;
case 'ok':
points = 60;
combo++;
performanceLevel = Math.min(100, performanceLevel + 1);
break;
default:
combo = 0;
performanceLevel = Math.max(0, performanceLevel - 5);
break;
}
score += points * (1 + combo * 0.1);
maxCombo = Math.max(maxCombo, combo);
// Update member animation
if (accuracy !== 'miss') {
members[note.lane].performAnimation();
LK.getSound('noteHit').play();
} else {
LK.getSound('noteMiss').play();
}
// Update UI
scoreText.setText('Score: ' + Math.floor(score));
comboText.setText('Combo: ' + combo);
updatePerformanceMeter();
// Set LK score for leaderboard
LK.setScore(Math.floor(score));
}
// Touch/click handling
var touchedLanes = [];
game.down = function (x, y, obj) {
// Find which member was touched
for (var i = 0; i < members.length; i++) {
var member = members[i];
var distance = Math.abs(x - member.x);
if (distance < 100) {
touchedLanes.push(i);
// Check for notes in this lane
var hitZoneY = member.getHitZoneY();
var bestNote = null;
var bestDistance = Infinity;
for (var j = 0; j < notes.length; j++) {
var note = notes[j];
if (note.lane === i && note.isActive) {
var noteDistance = Math.abs(note.y - hitZoneY);
if (noteDistance < bestDistance) {
bestDistance = noteDistance;
bestNote = note;
}
}
}
if (bestNote) {
var accuracy = bestNote.checkHit(hitZoneY);
hitNote(bestNote, accuracy);
bestNote.isActive = false;
bestNote.destroy();
// Remove from notes array
var noteIndex = notes.indexOf(bestNote);
if (noteIndex > -1) {
notes.splice(noteIndex, 1);
}
}
break;
}
}
};
game.up = function (x, y, obj) {
touchedLanes = [];
};
// Main game update loop
game.update = function () {
songPosition++;
// Spawn notes based on pattern
if (patternIndex < currentPattern.length) {
if (songPosition >= currentPattern[patternIndex].time) {
spawnNote(currentPattern[patternIndex].lane, 'normal');
patternIndex++;
// Loop pattern
if (patternIndex >= currentPattern.length) {
patternIndex = 0;
songPosition = 0;
}
}
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
// Remove notes that are off screen
if (note.y > 2800) {
// Miss penalty
if (note.isActive) {
combo = 0;
performanceLevel = Math.max(0, performanceLevel - 8);
updatePerformanceMeter();
LK.getSound('noteMiss').play();
}
note.destroy();
notes.splice(i, 1);
}
}
// Update member idle animations
for (var i = 0; i < members.length; i++) {
if (!members[i].isPerforming && LK.ticks % 180 === i * 20) {
members[i].idleAnimation();
}
}
// Check game over condition
if (performanceLevel <= 0) {
gameState = 'gameOver';
LK.showGameOver();
}
// Check win condition (high score threshold)
if (score >= 5000) {
gameState = 'win';
LK.showYouWin();
}
// Increase difficulty over time
if (LK.ticks % 1800 === 0 && difficulty < 2) {
difficulty++;
currentPattern = notePatterns[difficulty];
patternIndex = 0;
songPosition = 0;
// Increase note speed
for (var i = 0; i < notes.length; i++) {
notes[i].speed = 8 + difficulty * 2;
}
}
};
// Start background music
LK.playMusic('btsSong');
// Initial performance meter update
updatePerformanceMeter(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,401 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var BTSMember = Container.expand(function (memberNumber, xPos) {
+ var self = Container.call(this);
+ self.memberNumber = memberNumber;
+ self.isPerforming = false;
+ self.animationState = 'idle';
+ var memberGraphics = self.attachAsset('member' + memberNumber, {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ var hitZone = self.attachAsset('hitZone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.3
+ });
+ self.x = xPos;
+ self.y = 2200;
+ hitZone.y = -200;
+ self.performAnimation = function () {
+ self.isPerforming = true;
+ self.animationState = 'performing';
+ tween(memberGraphics, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 200,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(memberGraphics, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 200,
+ easing: tween.easeIn
+ });
+ }
+ });
+ tween(memberGraphics, {
+ tint: 0xffffff
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ tween(memberGraphics, {
+ tint: 0xffffff
+ }, {
+ duration: 200
+ });
+ }
+ });
+ };
+ self.idleAnimation = function () {
+ self.isPerforming = false;
+ self.animationState = 'idle';
+ tween(memberGraphics, {
+ scaleX: 0.9,
+ scaleY: 0.9
+ }, {
+ duration: 500,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(memberGraphics, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 500,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ };
+ self.getHitZoneY = function () {
+ return self.y + hitZone.y;
+ };
+ return self;
+});
+var Note = Container.expand(function (lane, type) {
+ var self = Container.call(this);
+ self.lane = lane;
+ self.type = type || 'normal';
+ self.speed = 8;
+ self.isActive = true;
+ self.hitTiming = 0;
+ var noteGraphics = self.attachAsset(self.type === 'hold' ? 'holdNote' : 'note', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.update = function () {
+ if (self.isActive) {
+ self.y += self.speed;
+ }
+ };
+ self.checkHit = function (hitY) {
+ var distance = Math.abs(self.y - hitY);
+ if (distance < 50) {
+ return 'perfect';
+ } else if (distance < 80) {
+ return 'good';
+ } else if (distance < 120) {
+ return 'ok';
+ }
+ return 'miss';
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x0a0a0a
+});
+
+/****
+* Game Code
+****/
+// Sound effects
+// UI elements
+// Note types
+// BTS character representations
+// Stage and background elements
+// Game state variables
+var gameState = 'playing';
+var score = 0;
+var combo = 0;
+var maxCombo = 0;
+var performanceLevel = 100;
+var difficulty = 1;
+var songPosition = 0;
+var nextNoteTime = 0;
+// Member positions (7 members spread across stage)
+var memberPositions = [200, 400, 600, 800, 1000, 1200, 1400, 1600];
+// Create stage
+var stage = game.attachAsset('stage', {
+ anchorX: 0.5,
+ anchorY: 1.0,
+ x: 1024,
+ y: 2200
+});
+// Create BTS members
+var members = [];
+for (var i = 0; i < 7; i++) {
+ var member = new BTSMember(i + 1, memberPositions[i]);
+ members.push(member);
+ game.addChild(member);
+}
+// Create notes array
+var notes = [];
+// Create UI elements
+var scoreText = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreText);
+var comboText = new Text2('Combo: 0', {
+ size: 50,
+ fill: 0xFFFF00
+});
+comboText.anchor.set(0.5, 0);
+comboText.y = 80;
+LK.gui.top.addChild(comboText);
+// Performance meter
+var performanceMeterBg = LK.gui.bottom.attachAsset('performanceMeter', {
+ anchorX: 0.5,
+ anchorY: 1.0,
+ x: 0,
+ y: -100
+});
+var performanceBar = LK.gui.bottom.attachAsset('performanceBar', {
+ anchorX: 0.0,
+ anchorY: 1.0,
+ x: -150,
+ y: -100
+});
+// Note patterns for different difficulty levels
+var notePatterns = {
+ 1: [{
+ lane: 0,
+ time: 60
+ }, {
+ lane: 2,
+ time: 120
+ }, {
+ lane: 4,
+ time: 180
+ }, {
+ lane: 6,
+ time: 240
+ }, {
+ lane: 1,
+ time: 300
+ }, {
+ lane: 3,
+ time: 360
+ }, {
+ lane: 5,
+ time: 420
+ }, {
+ lane: 0,
+ time: 480
+ }],
+ 2: [{
+ lane: 0,
+ time: 30
+ }, {
+ lane: 2,
+ time: 60
+ }, {
+ lane: 4,
+ time: 90
+ }, {
+ lane: 6,
+ time: 120
+ }, {
+ lane: 1,
+ time: 150
+ }, {
+ lane: 3,
+ time: 180
+ }, {
+ lane: 5,
+ time: 210
+ }, {
+ lane: 0,
+ time: 240
+ }]
+};
+var currentPattern = notePatterns[difficulty];
+var patternIndex = 0;
+// Function to spawn notes
+function spawnNote(lane, type) {
+ if (lane < 0 || lane >= members.length) return;
+ var note = new Note(lane, type);
+ note.x = members[lane].x;
+ note.y = 200;
+ notes.push(note);
+ game.addChild(note);
+}
+// Function to update performance meter
+function updatePerformanceMeter() {
+ var percentage = performanceLevel / 100;
+ performanceBar.scaleX = Math.max(0, percentage);
+ if (performanceLevel > 70) {
+ performanceBar.tint = 0x00ff00;
+ } else if (performanceLevel > 40) {
+ performanceBar.tint = 0xffff00;
+ } else {
+ performanceBar.tint = 0xff0000;
+ }
+}
+// Function to handle note hit
+function hitNote(note, accuracy) {
+ var points = 0;
+ switch (accuracy) {
+ case 'perfect':
+ points = 100;
+ combo++;
+ performanceLevel = Math.min(100, performanceLevel + 3);
+ break;
+ case 'good':
+ points = 80;
+ combo++;
+ performanceLevel = Math.min(100, performanceLevel + 2);
+ break;
+ case 'ok':
+ points = 60;
+ combo++;
+ performanceLevel = Math.min(100, performanceLevel + 1);
+ break;
+ default:
+ combo = 0;
+ performanceLevel = Math.max(0, performanceLevel - 5);
+ break;
+ }
+ score += points * (1 + combo * 0.1);
+ maxCombo = Math.max(maxCombo, combo);
+ // Update member animation
+ if (accuracy !== 'miss') {
+ members[note.lane].performAnimation();
+ LK.getSound('noteHit').play();
+ } else {
+ LK.getSound('noteMiss').play();
+ }
+ // Update UI
+ scoreText.setText('Score: ' + Math.floor(score));
+ comboText.setText('Combo: ' + combo);
+ updatePerformanceMeter();
+ // Set LK score for leaderboard
+ LK.setScore(Math.floor(score));
+}
+// Touch/click handling
+var touchedLanes = [];
+game.down = function (x, y, obj) {
+ // Find which member was touched
+ for (var i = 0; i < members.length; i++) {
+ var member = members[i];
+ var distance = Math.abs(x - member.x);
+ if (distance < 100) {
+ touchedLanes.push(i);
+ // Check for notes in this lane
+ var hitZoneY = member.getHitZoneY();
+ var bestNote = null;
+ var bestDistance = Infinity;
+ for (var j = 0; j < notes.length; j++) {
+ var note = notes[j];
+ if (note.lane === i && note.isActive) {
+ var noteDistance = Math.abs(note.y - hitZoneY);
+ if (noteDistance < bestDistance) {
+ bestDistance = noteDistance;
+ bestNote = note;
+ }
+ }
+ }
+ if (bestNote) {
+ var accuracy = bestNote.checkHit(hitZoneY);
+ hitNote(bestNote, accuracy);
+ bestNote.isActive = false;
+ bestNote.destroy();
+ // Remove from notes array
+ var noteIndex = notes.indexOf(bestNote);
+ if (noteIndex > -1) {
+ notes.splice(noteIndex, 1);
+ }
+ }
+ break;
+ }
+ }
+};
+game.up = function (x, y, obj) {
+ touchedLanes = [];
+};
+// Main game update loop
+game.update = function () {
+ songPosition++;
+ // Spawn notes based on pattern
+ if (patternIndex < currentPattern.length) {
+ if (songPosition >= currentPattern[patternIndex].time) {
+ spawnNote(currentPattern[patternIndex].lane, 'normal');
+ patternIndex++;
+ // Loop pattern
+ if (patternIndex >= currentPattern.length) {
+ patternIndex = 0;
+ songPosition = 0;
+ }
+ }
+ }
+ // Update notes
+ for (var i = notes.length - 1; i >= 0; i--) {
+ var note = notes[i];
+ // Remove notes that are off screen
+ if (note.y > 2800) {
+ // Miss penalty
+ if (note.isActive) {
+ combo = 0;
+ performanceLevel = Math.max(0, performanceLevel - 8);
+ updatePerformanceMeter();
+ LK.getSound('noteMiss').play();
+ }
+ note.destroy();
+ notes.splice(i, 1);
+ }
+ }
+ // Update member idle animations
+ for (var i = 0; i < members.length; i++) {
+ if (!members[i].isPerforming && LK.ticks % 180 === i * 20) {
+ members[i].idleAnimation();
+ }
+ }
+ // Check game over condition
+ if (performanceLevel <= 0) {
+ gameState = 'gameOver';
+ LK.showGameOver();
+ }
+ // Check win condition (high score threshold)
+ if (score >= 5000) {
+ gameState = 'win';
+ LK.showYouWin();
+ }
+ // Increase difficulty over time
+ if (LK.ticks % 1800 === 0 && difficulty < 2) {
+ difficulty++;
+ currentPattern = notePatterns[difficulty];
+ patternIndex = 0;
+ songPosition = 0;
+ // Increase note speed
+ for (var i = 0; i < notes.length; i++) {
+ notes[i].speed = 8 + difficulty * 2;
+ }
+ }
+};
+// Start background music
+LK.playMusic('btsSong');
+// Initial performance meter update
+updatePerformanceMeter();
\ No newline at end of file