/****
* 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();
}
};