/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Catcher = Container.expand(function () { var self = Container.call(this); var catcherGraphics = self.attachAsset('catcher', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var FallingObject = Container.expand(function (color, type) { var self = Container.call(this); var objectGraphics = self.attachAsset(color + 'Object', { anchorX: 0.5, anchorY: 0.5 }); self.color = color; self.type = type; // 'positive' or 'negative' self.speed = 6 + Math.random() * 6; self.caught = false; self.update = function () { if (!self.caught) { self.y += self.speed; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Add concert background var background = game.addChild(LK.getAsset('concertBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); // Game variables var fallingObjects = []; var catcher; var fanCount = 100; var consecutiveNegative = 0; var consecutivePositive = 0; var spawnTimer = 0; var musicLayers = 1; var maxMusicLayers = 5; // UI Elements var fanCountText = new Text2('Fans: ' + fanCount, { size: 60, fill: 0xFFFFFF }); fanCountText.anchor.set(0.5, 0); LK.gui.top.addChild(fanCountText); var energyText = new Text2('Energy: HIGH', { size: 40, fill: 0x00FF00 }); energyText.anchor.set(0, 0); energyText.x = 50; energyText.y = 150; LK.gui.topLeft.addChild(energyText); // Create catcher catcher = game.addChild(new Catcher()); catcher.x = 2048 / 2; catcher.y = 2532; // Start background music LK.playMusic('background'); // Object colors and types var objectTypes = [{ color: 'green', type: 'positive', weight: 3 }, { color: 'blue', type: 'positive', weight: 3 }, { color: 'red', type: 'negative', weight: 2 }, { color: 'orange', type: 'negative', weight: 2 }]; function getRandomObjectType() { var totalWeight = 0; for (var i = 0; i < objectTypes.length; i++) { totalWeight += objectTypes[i].weight; } var random = Math.random() * totalWeight; var currentWeight = 0; for (var i = 0; i < objectTypes.length; i++) { currentWeight += objectTypes[i].weight; if (random <= currentWeight) { return objectTypes[i]; } } return objectTypes[0]; } function spawnObject() { var objType = getRandomObjectType(); var obj = new FallingObject(objType.color, objType.type); obj.x = 100 + Math.random() * (2048 - 200); obj.y = -50; fallingObjects.push(obj); game.addChild(obj); // Add rhythmic movement for blue and green objects if (objType.color === 'blue' || objType.color === 'green') { // Start with a gentle sway animation tween(obj, { x: obj.x + 30 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { // Create continuous rhythmic movement var swayLeft = function swayLeft() { tween(obj, { x: obj.x - 60 }, { duration: 1200, easing: tween.easeInOut, onFinish: swayRight }); }; var swayRight = function swayRight() { tween(obj, { x: obj.x + 60 }, { duration: 1200, easing: tween.easeInOut, onFinish: swayLeft }); }; swayLeft(); } }); // Add subtle scale pulsing for rhythm var _pulseScale = function pulseScale() { tween(obj, { scaleX: 1.1, scaleY: 1.1 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { tween(obj, { scaleX: 1.0, scaleY: 1.0 }, { duration: 600, easing: tween.easeInOut, onFinish: _pulseScale }); } }); }; _pulseScale(); } } function updateFanCount(change) { fanCount += change; fanCount = Math.max(0, fanCount); fanCountText.setText('Fans: ' + fanCount); // Update energy display if (fanCount > 150) { energyText.setText('Energy: AMAZING'); energyText.fill = "#00ff00"; } else if (fanCount > 100) { energyText.setText('Energy: HIGH'); energyText.fill = "#66ff66"; } else if (fanCount > 50) { energyText.setText('Energy: MEDIUM'); energyText.fill = "#ffff00"; } else if (fanCount > 20) { energyText.setText('Energy: LOW'); energyText.fill = "#ff6600"; } else { energyText.setText('Energy: DEAD'); energyText.fill = "#ff0000"; } } function handleObjectCatch(obj) { // Play color-specific sound and wait for it to complete var catchSound = LK.getSound(obj.color + 'Catch'); catchSound.play(); // Pause game temporarily to let melody finish game.paused = true; // Wait for sound duration before continuing LK.setTimeout(function () { game.paused = false; }, catchSound.duration || 1000); // Default 1 second if duration not available if (obj.type === 'positive') { // Positive object caught updateFanCount(10); consecutiveNegative = 0; consecutivePositive++; // Check for cheer trigger after 3 consecutive positive catches if (consecutivePositive >= 3) { LK.getSound('cheer').play(); consecutivePositive = 0; // Reset counter after triggering cheer } // Add visual effect for blue and green objects if (obj.color === 'blue' || obj.color === 'green') { // Create sparkle effect with scaling and color flash tween(obj, { scaleX: 1.5, scaleY: 1.5, tint: 0xffffff }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(obj, { scaleX: 1.0, scaleY: 1.0, tint: 0xffffff }, { duration: 200, easing: tween.easeIn }); } }); // Add rotation effect tween(obj, { rotation: obj.rotation + Math.PI * 2 }, { duration: 400, easing: tween.easeInOut }); } else { // Regular flash effect for other positive objects LK.effects.flashObject(obj, 0xffffff, 300); } // Increase music richness if (musicLayers < maxMusicLayers) { musicLayers++; } } else { // Negative object caught updateFanCount(-15); consecutiveNegative++; consecutivePositive = 0; // Reset positive counter when catching negative // Check for boo trigger after 3 consecutive negative catches if (consecutiveNegative >= 3) { LK.getSound('boo').play(); consecutiveNegative = 0; // Reset counter after triggering boo } // Add negative visual effect LK.effects.flashScreen(0xff0000, 200); // Decrease music richness if (musicLayers > 1) { musicLayers--; } // Check game over condition if (fanCount <= 0) { LK.setScore(fanCount); LK.showGameOver(); return; } } // Remove object obj.caught = true; tween(obj, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 300, onFinish: function onFinish() { obj.destroy(); } }); } // Touch/mouse controls var isDragging = false; game.down = function (x, y, obj) { isDragging = true; catcher.x = x; }; game.move = function (x, y, obj) { if (isDragging) { catcher.x = Math.max(60, Math.min(2048 - 60, x)); } }; game.up = function (x, y, obj) { isDragging = false; }; // Main game loop game.update = function () { spawnTimer++; // Spawn objects if (spawnTimer >= 30) { // Spawn every half second for faster action spawnObject(); spawnTimer = 0; } // Update falling objects for (var i = fallingObjects.length - 1; i >= 0; i--) { var obj = fallingObjects[i]; if (obj.caught) { continue; } // Check collision with catcher if (obj.intersects(catcher)) { handleObjectCatch(obj); fallingObjects.splice(i, 1); continue; } // Remove objects that fall off screen if (obj.y > 2832) { // Missed object - penalty for positive objects if (obj.type === 'positive') { updateFanCount(-5); } obj.destroy(); fallingObjects.splice(i, 1); } } // Win condition if (fanCount >= 1000) { LK.setScore(fanCount); LK.showYouWin(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Catcher = Container.expand(function () {
var self = Container.call(this);
var catcherGraphics = self.attachAsset('catcher', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var FallingObject = Container.expand(function (color, type) {
var self = Container.call(this);
var objectGraphics = self.attachAsset(color + 'Object', {
anchorX: 0.5,
anchorY: 0.5
});
self.color = color;
self.type = type; // 'positive' or 'negative'
self.speed = 6 + Math.random() * 6;
self.caught = false;
self.update = function () {
if (!self.caught) {
self.y += self.speed;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Add concert background
var background = game.addChild(LK.getAsset('concertBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Game variables
var fallingObjects = [];
var catcher;
var fanCount = 100;
var consecutiveNegative = 0;
var consecutivePositive = 0;
var spawnTimer = 0;
var musicLayers = 1;
var maxMusicLayers = 5;
// UI Elements
var fanCountText = new Text2('Fans: ' + fanCount, {
size: 60,
fill: 0xFFFFFF
});
fanCountText.anchor.set(0.5, 0);
LK.gui.top.addChild(fanCountText);
var energyText = new Text2('Energy: HIGH', {
size: 40,
fill: 0x00FF00
});
energyText.anchor.set(0, 0);
energyText.x = 50;
energyText.y = 150;
LK.gui.topLeft.addChild(energyText);
// Create catcher
catcher = game.addChild(new Catcher());
catcher.x = 2048 / 2;
catcher.y = 2532;
// Start background music
LK.playMusic('background');
// Object colors and types
var objectTypes = [{
color: 'green',
type: 'positive',
weight: 3
}, {
color: 'blue',
type: 'positive',
weight: 3
}, {
color: 'red',
type: 'negative',
weight: 2
}, {
color: 'orange',
type: 'negative',
weight: 2
}];
function getRandomObjectType() {
var totalWeight = 0;
for (var i = 0; i < objectTypes.length; i++) {
totalWeight += objectTypes[i].weight;
}
var random = Math.random() * totalWeight;
var currentWeight = 0;
for (var i = 0; i < objectTypes.length; i++) {
currentWeight += objectTypes[i].weight;
if (random <= currentWeight) {
return objectTypes[i];
}
}
return objectTypes[0];
}
function spawnObject() {
var objType = getRandomObjectType();
var obj = new FallingObject(objType.color, objType.type);
obj.x = 100 + Math.random() * (2048 - 200);
obj.y = -50;
fallingObjects.push(obj);
game.addChild(obj);
// Add rhythmic movement for blue and green objects
if (objType.color === 'blue' || objType.color === 'green') {
// Start with a gentle sway animation
tween(obj, {
x: obj.x + 30
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Create continuous rhythmic movement
var swayLeft = function swayLeft() {
tween(obj, {
x: obj.x - 60
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: swayRight
});
};
var swayRight = function swayRight() {
tween(obj, {
x: obj.x + 60
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: swayLeft
});
};
swayLeft();
}
});
// Add subtle scale pulsing for rhythm
var _pulseScale = function pulseScale() {
tween(obj, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(obj, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: _pulseScale
});
}
});
};
_pulseScale();
}
}
function updateFanCount(change) {
fanCount += change;
fanCount = Math.max(0, fanCount);
fanCountText.setText('Fans: ' + fanCount);
// Update energy display
if (fanCount > 150) {
energyText.setText('Energy: AMAZING');
energyText.fill = "#00ff00";
} else if (fanCount > 100) {
energyText.setText('Energy: HIGH');
energyText.fill = "#66ff66";
} else if (fanCount > 50) {
energyText.setText('Energy: MEDIUM');
energyText.fill = "#ffff00";
} else if (fanCount > 20) {
energyText.setText('Energy: LOW');
energyText.fill = "#ff6600";
} else {
energyText.setText('Energy: DEAD');
energyText.fill = "#ff0000";
}
}
function handleObjectCatch(obj) {
// Play color-specific sound and wait for it to complete
var catchSound = LK.getSound(obj.color + 'Catch');
catchSound.play();
// Pause game temporarily to let melody finish
game.paused = true;
// Wait for sound duration before continuing
LK.setTimeout(function () {
game.paused = false;
}, catchSound.duration || 1000); // Default 1 second if duration not available
if (obj.type === 'positive') {
// Positive object caught
updateFanCount(10);
consecutiveNegative = 0;
consecutivePositive++;
// Check for cheer trigger after 3 consecutive positive catches
if (consecutivePositive >= 3) {
LK.getSound('cheer').play();
consecutivePositive = 0; // Reset counter after triggering cheer
}
// Add visual effect for blue and green objects
if (obj.color === 'blue' || obj.color === 'green') {
// Create sparkle effect with scaling and color flash
tween(obj, {
scaleX: 1.5,
scaleY: 1.5,
tint: 0xffffff
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(obj, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0xffffff
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Add rotation effect
tween(obj, {
rotation: obj.rotation + Math.PI * 2
}, {
duration: 400,
easing: tween.easeInOut
});
} else {
// Regular flash effect for other positive objects
LK.effects.flashObject(obj, 0xffffff, 300);
}
// Increase music richness
if (musicLayers < maxMusicLayers) {
musicLayers++;
}
} else {
// Negative object caught
updateFanCount(-15);
consecutiveNegative++;
consecutivePositive = 0; // Reset positive counter when catching negative
// Check for boo trigger after 3 consecutive negative catches
if (consecutiveNegative >= 3) {
LK.getSound('boo').play();
consecutiveNegative = 0; // Reset counter after triggering boo
}
// Add negative visual effect
LK.effects.flashScreen(0xff0000, 200);
// Decrease music richness
if (musicLayers > 1) {
musicLayers--;
}
// Check game over condition
if (fanCount <= 0) {
LK.setScore(fanCount);
LK.showGameOver();
return;
}
}
// Remove object
obj.caught = true;
tween(obj, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300,
onFinish: function onFinish() {
obj.destroy();
}
});
}
// Touch/mouse controls
var isDragging = false;
game.down = function (x, y, obj) {
isDragging = true;
catcher.x = x;
};
game.move = function (x, y, obj) {
if (isDragging) {
catcher.x = Math.max(60, Math.min(2048 - 60, x));
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
// Main game loop
game.update = function () {
spawnTimer++;
// Spawn objects
if (spawnTimer >= 30) {
// Spawn every half second for faster action
spawnObject();
spawnTimer = 0;
}
// Update falling objects
for (var i = fallingObjects.length - 1; i >= 0; i--) {
var obj = fallingObjects[i];
if (obj.caught) {
continue;
}
// Check collision with catcher
if (obj.intersects(catcher)) {
handleObjectCatch(obj);
fallingObjects.splice(i, 1);
continue;
}
// Remove objects that fall off screen
if (obj.y > 2832) {
// Missed object - penalty for positive objects
if (obj.type === 'positive') {
updateFanCount(-5);
}
obj.destroy();
fallingObjects.splice(i, 1);
}
}
// Win condition
if (fanCount >= 1000) {
LK.setScore(fanCount);
LK.showYouWin();
}
};