/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { unlockedFilters: ["normal", "grayscale"], coins: 0, highestRating: 0 }); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Button = Container.expand(function (text, width, height) { var self = Container.call(this); var background = self.attachAsset('button', { width: width || 300, height: height || 100, anchorX: 0.5, anchorY: 0.5 }); var label = new Text2(text, { size: 50, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.setEnabled = function (enabled) { self.interactive = enabled; background.alpha = enabled ? 1.0 : 0.5; }; self.down = function (x, y, obj) { tween(background, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(background, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; self.setText = function (newText) { label.setText(newText); }; return self; }); var EffectIndicator = Container.expand(function () { var self = Container.call(this); var circle = self.attachAsset('effectIndicator', { anchorX: 0.5, anchorY: 0.5 }); var label = new Text2("π΅", { size: 50, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.pulse = function (strength) { var targetScale = 0.8 + strength * 0.5; tween(self, { scaleX: targetScale, scaleY: targetScale }, { duration: 100, onFinish: function onFinish() { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); }; return self; }); var FilterPreview = Container.expand(function (filterId, filterName) { var self = Container.call(this); self.filterId = filterId; var background = self.attachAsset('filterPreview', { anchorX: 0.5, anchorY: 0.5 }); var label = new Text2(filterName, { size: 30, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); label.y = 90; self.addChild(label); self.setSelected = function (selected) { background.tint = selected ? 0x3498db : 0xcccccc; }; self.setLocked = function (locked) { self.interactive = !locked; self.alpha = locked ? 0.5 : 1.0; if (locked) { var lockIcon = new Text2("π", { size: 60, fill: 0xFFFFFF }); lockIcon.anchor.set(0.5, 0.5); self.addChild(lockIcon); } else { // Remove lock icon if it exists for (var i = self.children.length - 1; i >= 0; i--) { if (self.children[i] instanceof Text2 && self.children[i].text === "π") { self.removeChild(self.children[i]); break; } } } }; self.down = function (x, y, obj) { tween(background, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(background, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; return self; }); var Judge = Container.expand(function (judgeName) { var self = Container.call(this); var background = self.attachAsset('judgeBackground', { anchorX: 0.5, anchorY: 0.5 }); var nameLabel = new Text2(judgeName, { size: 40, fill: 0xFFFFFF }); nameLabel.anchor.set(0.5, 0); nameLabel.y = -120; self.addChild(nameLabel); var commentLabel = new Text2("", { size: 35, fill: 0xFFFFFF }); commentLabel.anchor.set(0.5, 0); commentLabel.y = -60; self.addChild(commentLabel); // Create stars self.stars = []; for (var i = 0; i < 5; i++) { var star = new RatingStar(); star.x = (i - 2) * 90; star.y = 60; self.addChild(star); self.stars.push(star); } self.setRating = function (rating) { for (var i = 0; i < 5; i++) { self.stars[i].setFilled(i < rating); if (i < rating) { // Delay the animation for each star (function (index) { LK.setTimeout(function () { self.stars[index].animateStar(); }, 200 * index); })(i); } } }; self.setComment = function (comment) { commentLabel.setText(comment); }; self.animateEntrance = function (delay) { self.alpha = 0; self.y = 100; LK.setTimeout(function () { tween(self, { alpha: 1, y: 0 }, { duration: 500, easing: tween.easeOut }); }, delay); }; return self; }); var RatingStar = Container.expand(function () { var self = Container.call(this); var emptyStarGraphic = self.attachAsset('ratingStarEmpty', { anchorX: 0.5, anchorY: 0.5 }); var filledStarGraphic = self.attachAsset('ratingStarFilled', { anchorX: 0.5, anchorY: 0.5 }); filledStarGraphic.alpha = 0; self.setFilled = function (filled) { emptyStarGraphic.alpha = filled ? 0 : 1; filledStarGraphic.alpha = filled ? 1 : 0; }; self.animateStar = function () { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Game states var STATE_CAMERA = "camera"; var STATE_REVIEW = "review"; var currentState = STATE_CAMERA; // Current filter settings var currentFilter = "normal"; var availableFilters = [{ id: "normal", name: "Normal", unlockRating: 0 }, { id: "grayscale", name: "Grayscale", unlockRating: 0 }, { id: "sepia", name: "Sepia", unlockRating: 2 }, { id: "vibrant", name: "Vibrant", unlockRating: 3 }, { id: "blur", name: "Blur", unlockRating: 3.5 }, { id: "pixelate", name: "Pixelate", unlockRating: 4 }, { id: "rainbow", name: "Rainbow", unlockRating: 4.5 }]; // Judge configurations var judges = [{ name: "Alex", comments: { 1: "Not feeling it...", 2: "Has potential.", 3: "Pretty good!", 4: "Very creative!", 5: "Absolute perfection!" } }, { name: "Taylor", comments: { 1: "Needs work...", 2: "Getting better!", 3: "Nice effort!", 4: "Love the style!", 5: "Outstanding!" } }, { name: "Jordan", comments: { 1: "Try again...", 2: "Almost there.", 3: "Good composition!", 4: "Excellent work!", 5: "Masterpiece!" } }]; // Last detected voice volume for effects var lastVoiceVolume = 0; var voiceEffectThreshold = 0.3; var voiceEffectActive = false; // Create coin display var coinText = new Text2("Coins: " + storage.coins, { size: 60, fill: 0xFFFFFF }); coinText.anchor.set(0.5, 0.5); coinText.x = 2048 - 150; coinText.y = 100; game.addChild(coinText); // Create UI elements var cameraFrame = game.addChild(LK.getAsset('cameraFrame', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.2 })); // Create filter selector container var filterContainer = new Container(); filterContainer.y = 2732 - 200; game.addChild(filterContainer); // Create filter previews var filterPreviews = {}; var filterPreviewWidth = 170; var totalFiltersWidth = availableFilters.length * filterPreviewWidth; var startX = (2048 - totalFiltersWidth) / 2 + filterPreviewWidth / 2; availableFilters.forEach(function (filter, index) { var preview = new FilterPreview(filter.id, filter.name); preview.x = startX + index * filterPreviewWidth; preview.y = 0; var isUnlocked = storage.unlockedFilters.indexOf(filter.id) !== -1; preview.setLocked(!isUnlocked); preview.setSelected(filter.id === currentFilter); filterContainer.addChild(preview); filterPreviews[filter.id] = preview; }); // Create capture button var captureButton = new Button("Take Selfie", 400, 100); captureButton.x = 2048 / 2; captureButton.y = 2732 - 400; game.addChild(captureButton); // Create effect indicator var effectIndicator = new EffectIndicator(); effectIndicator.x = 2048 - 150; effectIndicator.y = 150; effectIndicator.alpha = 0.7; game.addChild(effectIndicator); // Create judge container for ratings var judgeContainer = new Container(); judgeContainer.x = 2048 / 2; judgeContainer.y = 2732 / 2; judgeContainer.visible = false; game.addChild(judgeContainer); // Create judges var judgeObjects = []; judges.forEach(function (judgeData, index) { var judge = new Judge(judgeData.name); judge.y = index * 350 - 350; judgeContainer.addChild(judge); judgeObjects.push(judge); }); // Create return button for after ratings var returnButton = new Button("New Selfie", 400, 100); returnButton.x = 2048 / 2; returnButton.y = 2732 - 200; returnButton.visible = false; game.addChild(returnButton); // Current ratings info var currentRatings = []; var averageRatingText = new Text2("", { size: 80, fill: 0xFFFFFF }); averageRatingText.anchor.set(0.5, 0.5); averageRatingText.x = 2048 / 2; averageRatingText.y = 200; averageRatingText.visible = false; game.addChild(averageRatingText); // Function to switch between camera and review states function switchToState(newState) { currentState = newState; if (newState === STATE_CAMERA) { cameraFrame.visible = true; filterContainer.visible = true; captureButton.visible = true; judgeContainer.visible = false; returnButton.visible = false; averageRatingText.visible = false; // Reset any effects voiceEffectActive = false; // Start background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } }); } else if (newState === STATE_REVIEW) { cameraFrame.visible = false; filterContainer.visible = false; captureButton.visible = false; judgeContainer.visible = true; returnButton.visible = true; averageRatingText.visible = true; // Generate random ratings from judges generateRatings(); // Stop background music LK.stopMusic(); // Play applause sound LK.getSound('applause').play(); } } // Function to handle filter selection function selectFilter(filterId) { if (currentFilter === filterId) { return; } // Deselect current filter filterPreviews[currentFilter].setSelected(false); // Set and select new filter currentFilter = filterId; filterPreviews[currentFilter].setSelected(true); // Apply the selected filter using facekit switch (filterId) { case "normal": facekit.applyFilter("normal"); break; case "grayscale": facekit.applyFilter("grayscale"); break; case "sepia": facekit.applyFilter("sepia"); break; case "vibrant": facekit.applyFilter("vibrant"); break; case "blur": facekit.applyFilter("blur"); break; case "pixelate": facekit.applyFilter("pixelate"); break; case "rainbow": facekit.applyFilter("rainbow"); break; } } // Generate ratings from judges function generateRatings() { currentRatings = []; var totalRating = 0; // Reset judges and prepare for animation judgeObjects.forEach(function (judge) { judge.setRating(0); judge.setComment(""); }); // Generate a rating for each judge judges.forEach(function (judgeData, index) { // Base rating is random but weighted toward the middle var baseRating = Math.floor(Math.random() * 3) + 2; // 2-4 // Use coins to increase the chance of getting a higher rating if (storage.coins >= 10) { var chanceBoost = Math.random(); if (chanceBoost > 0.5) { baseRating += 1; // Increase base rating by 1 storage.coins -= 10; // Deduct 10 coins for the boost console.log("Used 10 coins for a rating boost. Remaining coins: " + storage.coins); } } // Adjust based on current filter (bonus for using advanced filters) var filterIndex = availableFilters.findIndex(function (f) { return f.id === currentFilter; }); var filterBonus = filterIndex / 10; // Small bonus for advanced filters // Calculate final rating (1-5) var finalRating = Math.min(5, Math.max(1, Math.round(baseRating + filterBonus))); currentRatings.push(finalRating); totalRating += finalRating; // Set rating and comment with delay (function (judgeObj, rating, comments) { var delay = 1000 + index * 1000; // Stagger judges' responses LK.setTimeout(function () { judgeObj.animateEntrance(0); judgeObj.setRating(rating); judgeObj.setComment(comments[rating]); LK.getSound('judgeComment').play(); }, delay); })(judgeObjects[index], finalRating, judgeData.comments); }); // Calculate and display average rating var averageRating = totalRating / judges.length; // Award coins based on average rating var coinsEarned = Math.round(averageRating * 10); // Earn 10 coins per star storage.coins = (storage.coins || 0) + coinsEarned; console.log("Coins earned: " + coinsEarned + ", Total coins: " + storage.coins); coinText.setText("Coins: " + storage.coins); // Update coin display // Update the highest rating if this is better if (averageRating > storage.highestRating) { storage.highestRating = averageRating; // Unlock new filters based on rating availableFilters.forEach(function (filter) { if (filter.unlockRating <= averageRating && storage.unlockedFilters.indexOf(filter.id) === -1) { storage.unlockedFilters.push(filter.id); } }); } // Display average rating LK.setTimeout(function () { averageRatingText.setText("Rating: " + averageRating.toFixed(1) + " / 5.0"); averageRatingText.alpha = 0; averageRatingText.visible = true; tween(averageRatingText, { alpha: 1 }, { duration: 500 }); }, 4000); } // Handle touch events for game elements game.down = function (x, y, obj) { // Handle filter selection if (currentState === STATE_CAMERA) { for (var filterId in filterPreviews) { var preview = filterPreviews[filterId]; if (preview.interactive && preview.getBounds().contains(x, y)) { selectFilter(filterId); return; } } } }; // Capture button event handler captureButton.down = function (x, y, obj) { if (currentState !== STATE_CAMERA) { return; } // Play camera click sound LK.getSound('cameraClick').play(); // Flash screen effect LK.effects.flashScreen(0xffffff, 500); // Switch to review mode after a short delay LK.setTimeout(function () { switchToState(STATE_REVIEW); }, 600); }; // Return button event handler returnButton.down = function (x, y, obj) { if (currentState !== STATE_REVIEW) { return; } // Deduct 10 coins if player has 10 or more coins if (storage.coins >= 10) { storage.coins -= 10; console.log("Spent 10 coins for a new selfie. Remaining coins: " + storage.coins); coinText.setText("Coins: " + storage.coins); // Update coin display } // Update filter previews to show newly unlocked filters availableFilters.forEach(function (filter) { var preview = filterPreviews[filter.id]; var isUnlocked = storage.unlockedFilters.indexOf(filter.id) !== -1; preview.setLocked(!isUnlocked); }); // Switch back to camera mode switchToState(STATE_CAMERA); }; // Game update function game.update = function () { // Handle voice-activated effects in camera mode if (currentState === STATE_CAMERA) { // Detect voice volume changes var volume = facekit.volume; // Update effect indicator based on current volume if (volume > lastVoiceVolume && volume > voiceEffectThreshold) { effectIndicator.pulse(volume); // Activate voice effect if over threshold if (volume > voiceEffectThreshold && !voiceEffectActive) { voiceEffectActive = true; // Apply random effect when voice detected var effect = Math.floor(Math.random() * 3); // Effects could include: // 1. Temporary color flash // 2. Scale animation // 3. Rotation effect switch (effect) { case 0: // Temporary color tint var randomColor = Math.random() * 0xFFFFFF; cameraFrame.tint = randomColor; LK.setTimeout(function () { tween(cameraFrame, { tint: 0xFFFFFF }, { duration: 500 }); }, 500); break; case 1: // Scale animation tween(cameraFrame, { scaleX: 1.1, scaleY: 1.1 }, { duration: 300, onFinish: function onFinish() { tween(cameraFrame, { scaleX: 1.0, scaleY: 1.0 }, { duration: 400 }); } }); break; case 2: // Rotation effect var startRotation = cameraFrame.rotation; var targetRotation = startRotation + Math.PI * 0.1; tween(cameraFrame, { rotation: targetRotation }, { duration: 300, onFinish: function onFinish() { tween(cameraFrame, { rotation: startRotation }, { duration: 400 }); } }); break; } } } else if (volume < voiceEffectThreshold && voiceEffectActive) { // Reset voice effect flag when volume drops voiceEffectActive = false; } lastVoiceVolume = volume; } }; // Start with camera state switchToState(STATE_CAMERA);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
unlockedFilters: ["normal", "grayscale"],
coins: 0,
highestRating: 0
});
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Button = Container.expand(function (text, width, height) {
var self = Container.call(this);
var background = self.attachAsset('button', {
width: width || 300,
height: height || 100,
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2(text, {
size: 50,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setEnabled = function (enabled) {
self.interactive = enabled;
background.alpha = enabled ? 1.0 : 0.5;
};
self.down = function (x, y, obj) {
tween(background, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
};
self.up = function (x, y, obj) {
tween(background, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
};
self.setText = function (newText) {
label.setText(newText);
};
return self;
});
var EffectIndicator = Container.expand(function () {
var self = Container.call(this);
var circle = self.attachAsset('effectIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2("π΅", {
size: 50,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.pulse = function (strength) {
var targetScale = 0.8 + strength * 0.5;
tween(self, {
scaleX: targetScale,
scaleY: targetScale
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
};
return self;
});
var FilterPreview = Container.expand(function (filterId, filterName) {
var self = Container.call(this);
self.filterId = filterId;
var background = self.attachAsset('filterPreview', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2(filterName, {
size: 30,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
label.y = 90;
self.addChild(label);
self.setSelected = function (selected) {
background.tint = selected ? 0x3498db : 0xcccccc;
};
self.setLocked = function (locked) {
self.interactive = !locked;
self.alpha = locked ? 0.5 : 1.0;
if (locked) {
var lockIcon = new Text2("π", {
size: 60,
fill: 0xFFFFFF
});
lockIcon.anchor.set(0.5, 0.5);
self.addChild(lockIcon);
} else {
// Remove lock icon if it exists
for (var i = self.children.length - 1; i >= 0; i--) {
if (self.children[i] instanceof Text2 && self.children[i].text === "π") {
self.removeChild(self.children[i]);
break;
}
}
}
};
self.down = function (x, y, obj) {
tween(background, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
};
self.up = function (x, y, obj) {
tween(background, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
};
return self;
});
var Judge = Container.expand(function (judgeName) {
var self = Container.call(this);
var background = self.attachAsset('judgeBackground', {
anchorX: 0.5,
anchorY: 0.5
});
var nameLabel = new Text2(judgeName, {
size: 40,
fill: 0xFFFFFF
});
nameLabel.anchor.set(0.5, 0);
nameLabel.y = -120;
self.addChild(nameLabel);
var commentLabel = new Text2("", {
size: 35,
fill: 0xFFFFFF
});
commentLabel.anchor.set(0.5, 0);
commentLabel.y = -60;
self.addChild(commentLabel);
// Create stars
self.stars = [];
for (var i = 0; i < 5; i++) {
var star = new RatingStar();
star.x = (i - 2) * 90;
star.y = 60;
self.addChild(star);
self.stars.push(star);
}
self.setRating = function (rating) {
for (var i = 0; i < 5; i++) {
self.stars[i].setFilled(i < rating);
if (i < rating) {
// Delay the animation for each star
(function (index) {
LK.setTimeout(function () {
self.stars[index].animateStar();
}, 200 * index);
})(i);
}
}
};
self.setComment = function (comment) {
commentLabel.setText(comment);
};
self.animateEntrance = function (delay) {
self.alpha = 0;
self.y = 100;
LK.setTimeout(function () {
tween(self, {
alpha: 1,
y: 0
}, {
duration: 500,
easing: tween.easeOut
});
}, delay);
};
return self;
});
var RatingStar = Container.expand(function () {
var self = Container.call(this);
var emptyStarGraphic = self.attachAsset('ratingStarEmpty', {
anchorX: 0.5,
anchorY: 0.5
});
var filledStarGraphic = self.attachAsset('ratingStarFilled', {
anchorX: 0.5,
anchorY: 0.5
});
filledStarGraphic.alpha = 0;
self.setFilled = function (filled) {
emptyStarGraphic.alpha = filled ? 0 : 1;
filledStarGraphic.alpha = filled ? 1 : 0;
};
self.animateStar = function () {
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game states
var STATE_CAMERA = "camera";
var STATE_REVIEW = "review";
var currentState = STATE_CAMERA;
// Current filter settings
var currentFilter = "normal";
var availableFilters = [{
id: "normal",
name: "Normal",
unlockRating: 0
}, {
id: "grayscale",
name: "Grayscale",
unlockRating: 0
}, {
id: "sepia",
name: "Sepia",
unlockRating: 2
}, {
id: "vibrant",
name: "Vibrant",
unlockRating: 3
}, {
id: "blur",
name: "Blur",
unlockRating: 3.5
}, {
id: "pixelate",
name: "Pixelate",
unlockRating: 4
}, {
id: "rainbow",
name: "Rainbow",
unlockRating: 4.5
}];
// Judge configurations
var judges = [{
name: "Alex",
comments: {
1: "Not feeling it...",
2: "Has potential.",
3: "Pretty good!",
4: "Very creative!",
5: "Absolute perfection!"
}
}, {
name: "Taylor",
comments: {
1: "Needs work...",
2: "Getting better!",
3: "Nice effort!",
4: "Love the style!",
5: "Outstanding!"
}
}, {
name: "Jordan",
comments: {
1: "Try again...",
2: "Almost there.",
3: "Good composition!",
4: "Excellent work!",
5: "Masterpiece!"
}
}];
// Last detected voice volume for effects
var lastVoiceVolume = 0;
var voiceEffectThreshold = 0.3;
var voiceEffectActive = false;
// Create coin display
var coinText = new Text2("Coins: " + storage.coins, {
size: 60,
fill: 0xFFFFFF
});
coinText.anchor.set(0.5, 0.5);
coinText.x = 2048 - 150;
coinText.y = 100;
game.addChild(coinText);
// Create UI elements
var cameraFrame = game.addChild(LK.getAsset('cameraFrame', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.2
}));
// Create filter selector container
var filterContainer = new Container();
filterContainer.y = 2732 - 200;
game.addChild(filterContainer);
// Create filter previews
var filterPreviews = {};
var filterPreviewWidth = 170;
var totalFiltersWidth = availableFilters.length * filterPreviewWidth;
var startX = (2048 - totalFiltersWidth) / 2 + filterPreviewWidth / 2;
availableFilters.forEach(function (filter, index) {
var preview = new FilterPreview(filter.id, filter.name);
preview.x = startX + index * filterPreviewWidth;
preview.y = 0;
var isUnlocked = storage.unlockedFilters.indexOf(filter.id) !== -1;
preview.setLocked(!isUnlocked);
preview.setSelected(filter.id === currentFilter);
filterContainer.addChild(preview);
filterPreviews[filter.id] = preview;
});
// Create capture button
var captureButton = new Button("Take Selfie", 400, 100);
captureButton.x = 2048 / 2;
captureButton.y = 2732 - 400;
game.addChild(captureButton);
// Create effect indicator
var effectIndicator = new EffectIndicator();
effectIndicator.x = 2048 - 150;
effectIndicator.y = 150;
effectIndicator.alpha = 0.7;
game.addChild(effectIndicator);
// Create judge container for ratings
var judgeContainer = new Container();
judgeContainer.x = 2048 / 2;
judgeContainer.y = 2732 / 2;
judgeContainer.visible = false;
game.addChild(judgeContainer);
// Create judges
var judgeObjects = [];
judges.forEach(function (judgeData, index) {
var judge = new Judge(judgeData.name);
judge.y = index * 350 - 350;
judgeContainer.addChild(judge);
judgeObjects.push(judge);
});
// Create return button for after ratings
var returnButton = new Button("New Selfie", 400, 100);
returnButton.x = 2048 / 2;
returnButton.y = 2732 - 200;
returnButton.visible = false;
game.addChild(returnButton);
// Current ratings info
var currentRatings = [];
var averageRatingText = new Text2("", {
size: 80,
fill: 0xFFFFFF
});
averageRatingText.anchor.set(0.5, 0.5);
averageRatingText.x = 2048 / 2;
averageRatingText.y = 200;
averageRatingText.visible = false;
game.addChild(averageRatingText);
// Function to switch between camera and review states
function switchToState(newState) {
currentState = newState;
if (newState === STATE_CAMERA) {
cameraFrame.visible = true;
filterContainer.visible = true;
captureButton.visible = true;
judgeContainer.visible = false;
returnButton.visible = false;
averageRatingText.visible = false;
// Reset any effects
voiceEffectActive = false;
// Start background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
} else if (newState === STATE_REVIEW) {
cameraFrame.visible = false;
filterContainer.visible = false;
captureButton.visible = false;
judgeContainer.visible = true;
returnButton.visible = true;
averageRatingText.visible = true;
// Generate random ratings from judges
generateRatings();
// Stop background music
LK.stopMusic();
// Play applause sound
LK.getSound('applause').play();
}
}
// Function to handle filter selection
function selectFilter(filterId) {
if (currentFilter === filterId) {
return;
}
// Deselect current filter
filterPreviews[currentFilter].setSelected(false);
// Set and select new filter
currentFilter = filterId;
filterPreviews[currentFilter].setSelected(true);
// Apply the selected filter using facekit
switch (filterId) {
case "normal":
facekit.applyFilter("normal");
break;
case "grayscale":
facekit.applyFilter("grayscale");
break;
case "sepia":
facekit.applyFilter("sepia");
break;
case "vibrant":
facekit.applyFilter("vibrant");
break;
case "blur":
facekit.applyFilter("blur");
break;
case "pixelate":
facekit.applyFilter("pixelate");
break;
case "rainbow":
facekit.applyFilter("rainbow");
break;
}
}
// Generate ratings from judges
function generateRatings() {
currentRatings = [];
var totalRating = 0;
// Reset judges and prepare for animation
judgeObjects.forEach(function (judge) {
judge.setRating(0);
judge.setComment("");
});
// Generate a rating for each judge
judges.forEach(function (judgeData, index) {
// Base rating is random but weighted toward the middle
var baseRating = Math.floor(Math.random() * 3) + 2; // 2-4
// Use coins to increase the chance of getting a higher rating
if (storage.coins >= 10) {
var chanceBoost = Math.random();
if (chanceBoost > 0.5) {
baseRating += 1; // Increase base rating by 1
storage.coins -= 10; // Deduct 10 coins for the boost
console.log("Used 10 coins for a rating boost. Remaining coins: " + storage.coins);
}
}
// Adjust based on current filter (bonus for using advanced filters)
var filterIndex = availableFilters.findIndex(function (f) {
return f.id === currentFilter;
});
var filterBonus = filterIndex / 10; // Small bonus for advanced filters
// Calculate final rating (1-5)
var finalRating = Math.min(5, Math.max(1, Math.round(baseRating + filterBonus)));
currentRatings.push(finalRating);
totalRating += finalRating;
// Set rating and comment with delay
(function (judgeObj, rating, comments) {
var delay = 1000 + index * 1000; // Stagger judges' responses
LK.setTimeout(function () {
judgeObj.animateEntrance(0);
judgeObj.setRating(rating);
judgeObj.setComment(comments[rating]);
LK.getSound('judgeComment').play();
}, delay);
})(judgeObjects[index], finalRating, judgeData.comments);
});
// Calculate and display average rating
var averageRating = totalRating / judges.length;
// Award coins based on average rating
var coinsEarned = Math.round(averageRating * 10); // Earn 10 coins per star
storage.coins = (storage.coins || 0) + coinsEarned;
console.log("Coins earned: " + coinsEarned + ", Total coins: " + storage.coins);
coinText.setText("Coins: " + storage.coins); // Update coin display
// Update the highest rating if this is better
if (averageRating > storage.highestRating) {
storage.highestRating = averageRating;
// Unlock new filters based on rating
availableFilters.forEach(function (filter) {
if (filter.unlockRating <= averageRating && storage.unlockedFilters.indexOf(filter.id) === -1) {
storage.unlockedFilters.push(filter.id);
}
});
}
// Display average rating
LK.setTimeout(function () {
averageRatingText.setText("Rating: " + averageRating.toFixed(1) + " / 5.0");
averageRatingText.alpha = 0;
averageRatingText.visible = true;
tween(averageRatingText, {
alpha: 1
}, {
duration: 500
});
}, 4000);
}
// Handle touch events for game elements
game.down = function (x, y, obj) {
// Handle filter selection
if (currentState === STATE_CAMERA) {
for (var filterId in filterPreviews) {
var preview = filterPreviews[filterId];
if (preview.interactive && preview.getBounds().contains(x, y)) {
selectFilter(filterId);
return;
}
}
}
};
// Capture button event handler
captureButton.down = function (x, y, obj) {
if (currentState !== STATE_CAMERA) {
return;
}
// Play camera click sound
LK.getSound('cameraClick').play();
// Flash screen effect
LK.effects.flashScreen(0xffffff, 500);
// Switch to review mode after a short delay
LK.setTimeout(function () {
switchToState(STATE_REVIEW);
}, 600);
};
// Return button event handler
returnButton.down = function (x, y, obj) {
if (currentState !== STATE_REVIEW) {
return;
}
// Deduct 10 coins if player has 10 or more coins
if (storage.coins >= 10) {
storage.coins -= 10;
console.log("Spent 10 coins for a new selfie. Remaining coins: " + storage.coins);
coinText.setText("Coins: " + storage.coins); // Update coin display
}
// Update filter previews to show newly unlocked filters
availableFilters.forEach(function (filter) {
var preview = filterPreviews[filter.id];
var isUnlocked = storage.unlockedFilters.indexOf(filter.id) !== -1;
preview.setLocked(!isUnlocked);
});
// Switch back to camera mode
switchToState(STATE_CAMERA);
};
// Game update function
game.update = function () {
// Handle voice-activated effects in camera mode
if (currentState === STATE_CAMERA) {
// Detect voice volume changes
var volume = facekit.volume;
// Update effect indicator based on current volume
if (volume > lastVoiceVolume && volume > voiceEffectThreshold) {
effectIndicator.pulse(volume);
// Activate voice effect if over threshold
if (volume > voiceEffectThreshold && !voiceEffectActive) {
voiceEffectActive = true;
// Apply random effect when voice detected
var effect = Math.floor(Math.random() * 3);
// Effects could include:
// 1. Temporary color flash
// 2. Scale animation
// 3. Rotation effect
switch (effect) {
case 0:
// Temporary color tint
var randomColor = Math.random() * 0xFFFFFF;
cameraFrame.tint = randomColor;
LK.setTimeout(function () {
tween(cameraFrame, {
tint: 0xFFFFFF
}, {
duration: 500
});
}, 500);
break;
case 1:
// Scale animation
tween(cameraFrame, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
onFinish: function onFinish() {
tween(cameraFrame, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 400
});
}
});
break;
case 2:
// Rotation effect
var startRotation = cameraFrame.rotation;
var targetRotation = startRotation + Math.PI * 0.1;
tween(cameraFrame, {
rotation: targetRotation
}, {
duration: 300,
onFinish: function onFinish() {
tween(cameraFrame, {
rotation: startRotation
}, {
duration: 400
});
}
});
break;
}
}
} else if (volume < voiceEffectThreshold && voiceEffectActive) {
// Reset voice effect flag when volume drops
voiceEffectActive = false;
}
lastVoiceVolume = volume;
}
};
// Start with camera state
switchToState(STATE_CAMERA);