User prompt
give the fireworks effect variable size of expansion
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: tint is not defined' in or related to this line: 'particle.init(self.x, self.y, angle, speed, tint);' Line Number: 1235
Code edit (8 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: tint is not defined' in or related to this line: 'particle.init(self.x, self.y, angle, speed, tint);' Line Number: 1235
User prompt
Please fix the bug: 'Timeout.tick error: fireworkEffect is not defined' in or related to this line: 'LK.gui.center.addChild(fireworkEffect);' Line Number: 2096
User prompt
Please fix the bug: 'Timeout.tick error: tint is not defined' in or related to this line: 'particle.init(self.x, self.y, angle, speed, tint);' Line Number: 1235
Code edit (1 edits merged)
Please save this source code
User prompt
When triggering firework effects, do more of them and with random delays between them to look more interesting.
User prompt
In the FireworkParticle class, ensure that move is called properly.
User prompt
Refactor the fireworkeffect to use containers.expand()
User prompt
Please fix the firework effect.
User prompt
Trigger firework on various places on screen when setting the text happy new years
User prompt
You have only created a class for one firework particle. This firework particle would be inside a firework effect that calls on many firework particles.
User prompt
Create a firework effect which is a ring of many particles expanding, an expanding ring resembling fireworks. Create such a class.
User prompt
Please fix the bug: 'Timeout.tick error: requestAnimationFrame is not a function' in or related to this line: 'requestAnimationFrame(_animate);' Line Number: 1259
User prompt
Please fix the bug: 'Timeout.tick error: requestAnimationFrame is not a function' in or related to this line: 'requestAnimationFrame(_animate);' Line Number: 1259
User prompt
Correct. Please proceed with that plan.
User prompt
Please fix the bug: 'Timeout.tick error: currentTime is not defined' in or related to this line: 'var progress = (currentTime - startTime) / duration;' Line Number: 1240
User prompt
Please fix the bug: 'Timeout.tick error: progress is not defined' in or related to this line: 'self.y += Math.sin(angle) * speed - 9.8 * progress * progress; // Gravity effect' Line Number: 1240
User prompt
The firework effect should be like a circle of particles expanding, similar to the sparks of fireworks commonly seen in the air, in the sky.
User prompt
Improve the firework effect to have more particles and look nicer.
Code edit (9 edits merged)
Please save this source code
User prompt
trigger fireworks on the screen when setting the text 'happy new year!'
User prompt
Create a function that makes a firework particle effect
/****
* Classes
****/
// Board class
var Board = Container.expand(function () {
var self = Container.call(this);
// Function to shuffle gems around randomly
Board.prototype.shuffleGems = function () {
console.log("shuffleGems");
self.isShuffling = true;
// Removed usage of Set for compatibility
for (var i = this.gems.length - 1; i > 0; i--) {
this.gems[i].newPosition = false;
}
for (var i = this.gems.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
// Swap the gems
var tempNewPosition = this.gems[i].newPosition || {
x: this.gems[i].x,
y: this.gems[i].y
};
this.gems[i].newPosition = this.gems[j].newPosition || {
x: this.gems[j].x,
y: this.gems[j].y
};
this.gems[j].newPosition = tempNewPosition;
}
// The rest of your method remains unchanged
function animateGemToPosition(gem, x, y) {
var animationDuration = 1000; // Duration of the animation in milliseconds
var startX = gem.x;
var startY = gem.y;
var deltaX = x - startX;
var deltaY = y - startY;
var startTime = Date.now();
var animate = function animate() {
var now = Date.now();
var progress = Math.min(1, (now - startTime) / animationDuration);
gem.x = startX + deltaX * progress;
gem.y = startY + deltaY * progress;
if (progress < 1) {
LK.setTimeout(animate, 16); // Aim for roughly 60fps
} else {
gem.x = x;
gem.y = y;
self.isShuffling = false;
}
};
LK.setTimeout(animate, 16);
}
// Update the positions of the shuffled gems and ensure they have the correct new position in the gems array
var newGemsArray = new Array(this.gems.length);
this.gems.forEach(function (gem, index) {
if (gem.newPosition) {
var newPositionIndex = this.gems.findIndex(function (g) {
return g.x === gem.newPosition.x && g.y === gem.newPosition.y;
});
var aNewPosition = this.snapToGrid(gem.newPosition.x, gem.newPosition.y);
animateGemToPosition(gem, aNewPosition.x, aNewPosition.y);
newGemsArray[newPositionIndex] = gem;
}
}.bind(this));
this.gems = newGemsArray.filter(function (g) {
return g !== undefined;
});
LK.setTimeout(self.checkForMatches, 1000);
};
// Method to round or snap any position to the nearest position in the grid made by the 6x8 gems
this.snapToGrid = function (x, y) {
// Ensure there is at least one gem in the array before accessing its properties
var margin = 10;
var boardWidth = game.width * .9;
var boardHeight = game.height * .9;
var gemsPerRow = 6;
var gemsPerColumn = 8;
var totalMarginWidth = margin * (gemsPerRow + 1);
var totalMarginHeight = margin * (gemsPerColumn + 1);
var availableWidth = boardWidth - totalMarginWidth;
var availableHeight = boardHeight - totalMarginHeight;
var scaledGemSize = Math.min(availableWidth / gemsPerRow, availableHeight / gemsPerColumn);
var xOffset = (game.width - boardWidth) / 2 + scaledGemSize / 2;
var yOffset = (game.height - boardHeight) / 2 + scaledGemSize / 2 + 80;
var columnWidth = (boardWidth - margin) / 6;
var rowHeight = (boardHeight - margin) / 8;
var snappedX = Math.round((x - xOffset) / columnWidth) * columnWidth + xOffset;
var snappedY = Math.round((y - yOffset) / rowHeight) * rowHeight + yOffset;
return {
x: snappedX,
y: snappedY
};
};
// Method to show a hint for a possible match
this.showHint = function () {
console.log('showHint function started');
var possibleMatches = this.checkIfAnyMoveCausesMatch();
if (possibleMatches.length > 0) {
var animateMove = function animateMove(repeatCount) {
if (move.gem.isUsed) {
// Start fade-out effect for hint overlay
var fadeOutDuration = 500; // Fade out over 500ms
var startTime = Date.now();
var fadeStep = function fadeStep() {
var currentTime = Date.now();
var progress = (currentTime - startTime) / fadeOutDuration;
hintOverlay.alpha = 1 - progress; // Fade out effect
if (progress < 1) {
LK.setTimeout(fadeStep, 16); // Continue fading
} else {
hintOverlay.destroy(); // Destroy after faded out
}
};
fadeStep();
return;
}
var totalDuration = 1000; // Half a second for each back and forth movement
var repeatLimit = 1; // Repeat the animation three times
var animationCount = 0;
var startTime = Date.now();
var animateStep = function animateStep() {
if (move.gem.isUsed || !hintOverlay) {
if (hintOverlay) {
hintOverlay.destroy();
}
return;
}
var currentTime = Date.now();
var progress = (currentTime - startTime) / totalDuration;
var waveProgress = (Math.sin(progress * Math.PI * 2) + 1) / 2; // Adjusted to ensure it never goes below zero
hintOverlay.x = move.gemStartPosition.x + moveDirection.dx * moveDistance * waveProgress;
hintOverlay.y = move.gemStartPosition.y + moveDirection.dy * moveDistance * waveProgress;
if (progress >= 1) {
animationCount++;
if (animationCount < repeatLimit) {
startTime = Date.now(); // Reset start time for the next cycle
animateStep(); // Continue animation
} else {
hintOverlay.destroy();
}
} else {
LK.setTimeout(animateStep, 16); // Continue animation
}
};
animateStep();
};
console.log('Possible matches:', possibleMatches);
var move = possibleMatches[0];
var hintOverlay = LK.getAsset('hintOverlay', {});
self.lastHintOverlay = hintOverlay;
hintOverlay.anchor.set(0, 0);
self.addChild(hintOverlay);
hintOverlay.x = move.gem.x;
hintOverlay.y = move.gem.y;
move.gemStartPosition = {
x: move.gem.x,
y: move.gem.y
}; // Track starting position for animation
var moveDirection = move.move;
var moveDistance = move.gem.spacing; // Distance to move back and forth
var moveDuration = 500; // Duration of each move
animateMove();
} else {
console.log("no possible matches");
if (!self.fillingEmptySpaces && !self.gemsFalling && !self.isShuffling && !isDragoning) {
triggerDragon();
}
}
};
// Method to find possible matches on the board
// Method to find possible matches on the board
// Method to find possible matches on the board
this.findPossibleMatches = function () {
var matches = [];
var width = 6; // Board width
var height = 8; // Board height
for (var i = 0; i < height; i++) {
for (var j = 0; j < width; j++) {
var currentGem = this.gems[i * width + j];
// Check right and down for potential matches
var directions = [{
dx: 1,
dy: 0
},
// Right
{
dx: 0,
dy: 1
} // Down
];
directions.forEach(function (dir) {
var match = [currentGem];
for (var k = 1; k < 3; k++) {
var nextGemX = j + dir.dx * k;
var nextGemY = i + dir.dy * k;
if (nextGemX < width && nextGemY < height) {
var nextGem = this.gems[nextGemY * width + nextGemX];
if (nextGem && currentGem && nextGem.color === currentGem.color) {
match.push(nextGem);
} else {
break;
}
}
}
if (match.length >= 3) {
// Allows for matches longer than 3
matches.push(match);
}
}, this);
}
}
return matches;
};
// Method to check if moving any gem results in a match
this.checkIfAnyMoveCausesMatch = function () {
var matches = [];
var width = 6; // Board width
var height = 8; // Board height
// Simulate moving each gem in all four directions and check for matches
for (var i = 0; i < height; i++) {
for (var j = 0; j < width; j++) {
var currentGem = this.gems[i * width + j];
if (!currentGem) {
continue;
}
// Possible moves: up, down, left, right
var moves = [{
dx: -1,
dy: 0
}, {
dx: 1,
dy: 0
}, {
dx: 0,
dy: -1
}, {
dx: 0,
dy: 1
}];
moves.forEach(function (move) {
var newX = j + move.dx;
var newY = i + move.dy;
// Check if the new position is within the board
if (newX >= 0 && newX < width && newY >= 0 && newY < height) {
var targetGem = this.findGemByPosition(currentGem.x + currentGem.spacing * move.dx, currentGem.y + currentGem.spacing * move.dy);
if (targetGem && this.wouldSwapResultInMatch(currentGem, targetGem)) {
matches.push({
gem: currentGem,
move: move
});
}
}
}, this);
}
}
return matches;
};
// Check if swapping two gems would result in a match
this.wouldSwapResultInMatch = function (gemA, gemB) {
var gemAIndex = this.gems.indexOf(gemA);
var gemBIndex = this.gems.indexOf(gemB);
this.gems[gemAIndex] = gemB;
this.gems[gemBIndex] = gemA;
// Check for matches
var matchFound = false;
var matchedGems = [];
// Check for horizontal matches
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 6; j++) {
// Adjust to allow checks across all columns
var gem1 = this.gems[i * 6 + j];
var nowMatchingGems = [];
for (var k = j; k < 6; k++) {
var nextGem = this.gems[i * 6 + k];
if (nextGem && nextGem.color === gem1.color) {
nowMatchingGems.push(nextGem);
} else {
break;
}
}
if (nowMatchingGems.length >= 3) {
matchFound = true;
matchedGems = matchedGems.concat(nowMatchingGems.filter(function (gem) {
return matchedGems.indexOf(gem) === -1;
}));
}
}
}
// Check for vertical matches
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 8; j++) {
// Adjust to allow checks across all rows
var gem1 = this.gems[j * 6 + i];
var nowMatchingGems = [];
for (var k = j; k < 8; k++) {
var nextGem = this.gems[k * 6 + i];
if (nextGem && nextGem.color === gem1.color) {
nowMatchingGems.push(nextGem);
} else {
break;
}
}
if (nowMatchingGems.length >= 3) {
matchFound = true;
matchedGems = matchedGems.concat(nowMatchingGems.filter(function (gem) {
return matchedGems.indexOf(gem) === -1;
}));
}
}
}
// Swap back
this.gems[gemAIndex] = gemA;
this.gems[gemBIndex] = gemB;
return matchFound;
};
this.swapGems = function (gem1, gem2) {
var gem1Index = this.gems.indexOf(gem1);
var gem2Index = this.gems.indexOf(gem2);
if (gem1Index !== -1 && gem2Index !== -1) {
// Animate swap positions with easing
var swapDuration = 150; // Duration in milliseconds
var gem1StartPos = {
x: gem1.x,
y: gem1.y
};
if (!gem2) {
return;
} // Prevent TypeError if gem2 is null
var gem2StartPos = {
x: gem2.x,
y: gem2.y
};
gem1.isUsed = true;
gem2.isUsed = true;
gem1.alpha = 1;
gem2.alpha = 1;
var startTime = Date.now();
var animateSwap = function animateSwap() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / swapDuration);
var easeInOut = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
gem1.x = gem1StartPos.x + (gem2StartPos.x - gem1StartPos.x) * easeInOut;
gem1.y = gem1StartPos.y + (gem2StartPos.y - gem1StartPos.y) * easeInOut;
gem2.x = gem2StartPos.x + (gem1StartPos.x - gem2StartPos.x) * easeInOut;
gem2.y = gem2StartPos.y + (gem1StartPos.y - gem2StartPos.y) * easeInOut;
if (progress < 1) {
LK.setTimeout(animateSwap, 16); // Aim for roughly 60fps
} else {
gem1.isUsed = false;
gem2.isUsed = false;
var snappedOne = self.snapToGrid(gem1.x, gem1.y);
gem1.x = snappedOne.x;
gem1.y = snappedOne.y;
var snappedOne = self.snapToGrid(gem2.x, gem2.y);
gem2.x = snappedOne.x;
gem2.y = snappedOne.y;
self.checkForMatches();
}
};
animateSwap();
// Swap in gems array
this.gems[gem1Index] = gem2;
this.gems[gem2Index] = gem1;
// Check for matches after swap
}
};
this.faintSwapGems = function (gem1, gem2, firstFaint) {
var gem1Index = this.gems.indexOf(gem1);
var gem2Index = this.gems.indexOf(gem2);
if (gem1Index !== -1 && gem2Index !== -1) {
// Animate swap positions with easing
var swapDuration = 150; // Duration in milliseconds
var gem1StartPos = {
x: gem1.x,
y: gem1.y
};
var gem2StartPos = {
x: gem2.x,
y: gem2.y
};
var startTime = Date.now();
var animateSwap = function animateSwap() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / swapDuration);
var easeInOut = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
gem1.x = gem1StartPos.x + (gem2StartPos.x - gem1StartPos.x) * easeInOut;
gem1.y = gem1StartPos.y + (gem2StartPos.y - gem1StartPos.y) * easeInOut;
gem2.x = gem2StartPos.x + (gem1StartPos.x - gem2StartPos.x) * easeInOut;
gem2.y = gem2StartPos.y + (gem1StartPos.y - gem2StartPos.y) * easeInOut;
if (progress < 1) {
LK.setTimeout(animateSwap, 16); // Aim for roughly 60fps
} else if (firstFaint) {
self.faintSwapGems(gem1, gem2);
}
};
animateSwap();
// Swap in gems array
this.gems[gem1Index] = gem2;
this.gems[gem2Index] = gem1;
}
};
// Find a gem by its position
this.findGemByPosition = function (x, y, exceptThisGem) {
for (var i = 0; i < this.gems.length; i++) {
var gem = this.gems[i];
if (gem == exceptThisGem) {
continue;
}
if (gem) {
var tolerance = gem.spacing / 2; // Tolerance in pixels for approximate position
if (Math.abs(x - gem.x) < tolerance && Math.abs(y - gem.y) < tolerance) {
return gem;
}
}
}
return null;
};
this.fillEmptySpaces = function () {
self.fillingEmptySpaces = true;
var _animateGemDown = function animateGemDown(newGem, finalY, initialY) {
var snappedOne = self.snapToGrid(newGem.x, finalY);
finalY = snappedOne.y;
var animationDuration = 250; // Duration in milliseconds
var startTime = Date.now();
var animate = function animate() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / animationDuration);
// Apply easing for smoother animation
var easedProgress = Math.sin(progress * Math.PI / 2);
if (progress < 1) {
newGem.y = initialY + (finalY - initialY) * easedProgress;
LK.setTimeout(animate, 16); // Aim for roughly 60fps
} else {
newGem.y = finalY; // Ensure final position is accurate
self.fillingEmptySpaces = false;
}
};
animate();
};
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 6; j++) {
var index = i * 6 + j;
if (!self.gems[index]) {
var possibleColors = ['gemBlue', 'gemGreen', 'gemRed', 'gemPurple', 'gemYellow', 'gemOrange', 'gemCyan'];
// Filter colors to ensure at least one possible match
var colors = possibleColors.filter(function (color) {
return true;
}, this);
var color = colors.length > 0 ? colors[Math.floor(Math.random() * colors.length)] : possibleColors[Math.floor(Math.random() * possibleColors.length)];
var newGem = new Gem(color);
// Calculate x and y position for new gems when there are no existing gems to reference
var gemSize = 100;
var margin = 10;
var boardWidth = 1800; // Assuming the board width is known
var boardHeight = 2400; // Assuming the board height is known
var gemsPerRow = 6;
var gemsPerColumn = 8;
var totalMarginWidth = margin * (gemsPerRow + 1);
var totalMarginHeight = margin * (gemsPerColumn + 1);
var availableWidth = boardWidth - totalMarginWidth;
var availableHeight = boardHeight - totalMarginHeight;
var scaledGemSize = Math.min(availableWidth / gemsPerRow, availableHeight / gemsPerColumn);
var xOffset = (2048 - boardWidth) / 2 + scaledGemSize / 2; // Assuming game width is 2048
var yOffset = (2732 - boardHeight) / 2 + scaledGemSize / 2; // Assuming game height is 2732
var snapped = self.snapToGrid(xOffset + (scaledGemSize + margin) * j, yOffset + (scaledGemSize + margin) * i);
newGem.x = snapped.x;
// Calculate initial y position for animation start
// Calculate initial y position for animation start
var initialY = -gemSize; // Start above the screen to simulate falling into place
newGem.y = initialY;
// Animate gem to its final position
var finalY = snapped.y;
_animateGemDown(newGem, finalY, initialY);
newGem.spacing = scaledGemSize + margin;
newGem.scale.set(scaledGemSize / gemSize);
newGem.baseScale = scaledGemSize / gemSize;
self.addChild(newGem);
self.gems[index] = newGem;
self.handleGemClick(newGem);
}
}
}
};
self.gems = [];
this.handleFallingGems = function () {
console.log("handle Falling gems");
var didFall = false;
for (var i = 0; i < 6; i++) {
for (var j = 7; j >= 0; j--) {
var index = j * 6 + i;
if (index >= 0 && index < self.gems.length && !self.gems[index]) {
var emptySpaces = 1;
for (var k = j - 1; k >= 0; k--) {
var aboveIndex = k * 6 + i;
if (!self.gems[aboveIndex]) {
emptySpaces++;
} else {
var gemAbove = self.gems[aboveIndex];
var targetIndex = (k + emptySpaces) * 6 + i;
self.gems[targetIndex] = gemAbove;
self.gems[aboveIndex] = null;
// Calculate the new Y position based on the number of empty spaces
var margin = 10;
var snapped = self.snapToGrid(gemAbove.x, gemAbove.y + gemAbove.spacing * emptySpaces);
var newY = snapped.y;
// Animate the gem moving to the new position
gemAbove.alpha = 1;
animateGemToPosition(gemAbove, gemAbove.x, newY);
didFall = true;
break;
}
}
}
}
}
if (didFall) {
self.gemsFalling = true;
LK.setTimeout(function () {
self.fillEmptySpaces();
LK.setTimeout(function () {
self.gemsFalling = false;
self.checkForMatches();
}, 250);
}, 250);
} else {
// Trigger fillEmptySpaces even if no gems fell to ensure no gaps are left
self.fillEmptySpaces();
LK.setTimeout(function () {
self.checkForMatches();
}, 250);
}
};
function animateGemToPosition(gem, newX, newY) {
var fallDuration = 500; // Duration for the gem to fall to its new position
var bounceDuration = 300; // Duration for the bounce effect, slightly longer for realism
var scaleDuration = 150; // Duration for the scale effect after bouncing
var startTime = Date.now();
var animateStep = function animateStep() {
var currentTime = Date.now();
var elapsedTime = currentTime - startTime;
var progress = elapsedTime / fallDuration;
// First, handle the falling animation with a linear or ease-in effect
if (progress < 1) {
var fallProgress = Math.min(1, progress); // Ensure progress doesn't exceed 1
// Simple linear interpolation for falling
gem.y = gem.y + (newY - gem.y) * fallProgress;
if (fallProgress < 1) {
LK.setTimeout(animateStep, 16); // Continue the fall animation
} else {
gem.y = newY;
gem.isUsed = false;
}
}
};
animateStep(); // Start the animation with the fall
}
this.handleGemMatched = function (gem) {
if (gem.color == goalGemType) {
matchedGemCount++;
goalTxt.setText(matchedGemCount + "/" + goalGemCount);
if (matchedGemCount >= goalGemCount) {
game.timer += 10;
timerTxt.setText(game.timer.toString());
stopTimer();
// Show modal pop-up for 10 more seconds
var modalContainer = new Container();
LK.gui.center.addChild(modalContainer);
var modalBackground = LK.getAsset('goalCompleteBg', {});
modalBackground.anchor.set(.5, .5);
modalBackground.alpha = .75;
modalContainer.addChild(modalBackground);
// Animate scale of the modal container for excitement
var scaleStartTime = Date.now();
var scaleDuration = 500; // Scale animation duration in milliseconds
var animateScale = function animateScale() {
var currentTime = Date.now();
var progress = (currentTime - scaleStartTime) / scaleDuration;
var scale = 1 + 0.1 * Math.sin(progress * Math.PI * 2); // Oscillate scale between 1 and 1.1
modalContainer.scale.set(scale);
if (progress < 1) {
LK.setTimeout(animateScale, 16);
}
};
animateScale();
// Trigger lots of confetti balls on mission complete
for (var i = 0; i < 100; i++) {
var confetti = new ConfettiParticle();
confetti.init(Math.random() * game.width, Math.random() * game.height);
game.addChild(confetti);
}
showPastGoalSprite = LK.getAsset(goalGemType, {
// Align with the timer's top margin
anchorX: .5,
// Anchor right for right alignment
anchorY: .5 // Anchor top for top alignment
});
goalGemType = false;
// Add hourglass sprite next to the timer
var pastGoalBackground = LK.getAsset('newSpriteId', {});
pastGoalBackground.y = 0;
pastGoalBackground.x = -100;
pastGoalBackground.anchor.set(0.5, 0.5); // Align with the timer's top margin
modalContainer.addChild(pastGoalBackground);
pastGoalBackground.alpha = .75;
showPastGoalSprite.y = pastGoalBackground.y;
showPastGoalSprite.x = pastGoalBackground.x;
showPastGoalSprite.anchor.set(.5, 0.5); // Align with the timer's top margin
modalContainer.addChild(showPastGoalSprite);
showPastGoalSprite.rotation = -.2;
var showPastGoalText = new Text2(matchedGemCount + "/" + goalGemCount, {
size: 100,
weight: 600,
fill: "#ffffff",
x: 1024,
y: 1366,
anchorX: 0.5,
anchorY: 0.5,
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 8,
dropShadowOffsetX: 4,
dropShadowOffsetY: 4,
stroke: true,
strokeColor: '#000000',
strokeThickness: 4
});
showPastGoalText.y = pastGoalBackground.y;
showPastGoalText.x = 0;
showPastGoalText.anchor.set(0, 0.5); // Align with the timer's top margin
modalContainer.addChild(showPastGoalText);
var modalInfoText = new Text2('MISSION COMPLETE:', {
size: 50,
weight: 600,
fill: "#ffffff",
x: 1024,
y: 1366,
anchorX: 0.5,
anchorY: 0.5,
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 8,
dropShadowOffsetX: 4,
dropShadowOffsetY: 4,
stroke: true,
strokeColor: '#000000',
strokeThickness: 2
});
modalInfoText.anchor.set(.5);
modalInfoText.y = -100;
modalContainer.addChild(modalInfoText);
var modalText = new Text2('+10 seconds!', {
size: 100,
weight: 600,
fill: "#ffffff",
x: 1024 + 70,
// Adjust x position to make space for the hourglass sprite
y: 1366,
anchorX: 0.5,
anchorY: 0.5,
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 8,
dropShadowOffsetX: 4,
dropShadowOffsetY: 4,
stroke: true,
strokeColor: '#000000',
strokeThickness: 2
});
modalText.anchor.set(.5);
modalText.y = 100;
modalContainer.addChild(modalText);
// Add hourglass sprite next to the '+10 seconds!' text
var hourglassSpriteModal = LK.getAsset('hourglass', {
anchorX: .5,
anchorY: .5
});
hourglassSpriteModal.x = 1024 - 70; // Position hourglass to the left of the text
hourglassSpriteModal.y = 1366;
modalContainer.addChild(hourglassSpriteModal);
var thumbUpSprite = LK.getAsset('thumbUp', {
// Align with the timer's top margin
anchorX: .5,
// Anchor right for right alignment
anchorY: .5 // Anchor top for top alignment
});
thumbUpSprite.y = 0;
thumbUpSprite.x = -500;
thumbUpSprite.anchor.set(.5, 0.5); // Align with the timer's top margin
modalContainer.addChild(thumbUpSprite);
var thumbUpSprite2 = LK.getAsset('woodLockAcid', {
// Align with the timer's top margin
anchorX: .5,
// Anchor right for right alignment
anchorY: .5 // Anchor top for top alignment
});
thumbUpSprite2.y = 0;
thumbUpSprite2.x = 500;
thumbUpSprite2.anchor.set(.5, 0.5); // Align with the timer's top margin
modalContainer.addChild(thumbUpSprite2);
var modalText = new Text2('+', {
size: 120,
weight: 600,
fill: "#ffffff",
x: 1024 + 70,
// Adjust x position to make space for the hourglass sprite
y: 1366,
anchorX: 0.5,
anchorY: 0.5,
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 8,
dropShadowOffsetX: 4,
dropShadowOffsetY: 4,
stroke: true,
strokeColor: '#000000',
strokeThickness: 2
});
modalText.anchor.set(.5);
modalText.x = 400;
modalText.y = 0;
modalContainer.addChild(modalText);
// Automatically remove the modal and background after 2 seconds
// Start animation for modal elements
var duration = 2000; // 3 seconds for the animation
LK.setTimeout(function () {
var startTime = Date.now();
var simpleCountdownInterval = LK.setInterval(function () {
var currentTime = Date.now();
var progress = (currentTime - startTime) / duration;
var moveDistance = 2048; // Move to the right side off-screen
modalContainer.x += moveDistance * progress;
if (progress >= 1) {
LK.clearInterval(simpleCountdownInterval);
modalContainer.destroy();
startTimer();
}
}, 16);
}, 2000);
goalLevel++;
updateBackground();
setRandomGoalGemType();
}
}
};
this.checkForMatches = function (matchFoundPreviously) {
var matchFound = false;
var matchedGems = [];
// Check for horizontal matches
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 6; j++) {
// Adjust to allow checks across all columns
if (!this.gems || !this.gems[i * 6 + j] || typeof this.gems[i * 6 + j] === 'undefined') {
continue;
}
var gem1 = this.gems[i * 6 + j];
if (!gem1) {
continue;
}
var gem1 = this.gems[i * 6 + j];
var nowMatchingGems = [];
for (var k = j; k < 6; k++) {
var nextGem = this.gems[i * 6 + k];
if (nextGem && nextGem.color === gem1.color) {
nowMatchingGems.push(nextGem);
} else {
break;
}
}
if (nowMatchingGems.length >= 3) {
matchFound = true;
matchedGems = matchedGems.concat(nowMatchingGems.filter(function (gem) {
return matchedGems.indexOf(gem) === -1;
}));
}
}
}
// Check for vertical matches
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 8; j++) {
// Adjust to allow checks across all rows
if (!this.gems || !this.gems[j * 6 + i]) {
continue;
}
var gem1 = this.gems[j * 6 + i];
var nowMatchingGems = [];
for (var k = j; k < 8; k++) {
var nextGem = this.gems[k * 6 + i];
if (nextGem && nextGem.color === gem1.color) {
nowMatchingGems.push(nextGem);
} else {
break;
}
}
if (nowMatchingGems.length >= 3) {
matchFound = true;
matchedGems = matchedGems.concat(nowMatchingGems.filter(function (gem) {
return matchedGems.indexOf(gem) === -1;
}));
}
}
}
var matchesHandled = 0;
matchedGems.forEach(function (gem) {
if (gem.color == goalGemType) {
self.handleGemMatched(gem);
// Move gem to the goalGemSprite instead of destroying it
matchesHandled++;
game.addChild(gem);
var moveGemToGoal = function moveGemToGoal(gem) {
LK.setTimeout(function () {
var goalGemSpriteX = currentGoalGemSprite ? currentGoalGemSprite.x + (currentGoalGemSprite.parent ? currentGoalGemSprite.parent.x : 0) : 0;
var goalGemSpriteY = currentGoalGemSprite ? currentGoalGemSprite.y + (currentGoalGemSprite.parent ? currentGoalGemSprite.parent.y : 0) : 0;
if (currentGoalGemSprite) {
var goalGemSpriteScale = currentGoalGemSprite.scale.x;
}
var moveDuration = 500 + matchesHandled * 100; // Duration in milliseconds
var startTime = Date.now();
var animateMove = function animateMove() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / moveDuration);
var newX = gem.x + (goalGemSpriteX - gem.x) * progress;
var newY = gem.y + (goalGemSpriteY - gem.y) * progress;
var newScale = gem.scale.x + (goalGemSpriteScale - gem.scale.x) * progress;
gem.x = newX;
gem.y = newY;
gem.scale.set(newScale);
if (progress < 1) {
LK.setTimeout(animateMove, 16); // Aim for roughly 60fps
} else {
gem.destroy(); // Destroy gem after reaching the goal
}
};
animateMove();
}, matchesHandled * 100);
};
moveGemToGoal(gem);
} else {
self.handleGemMatched(gem);
gem.scaleUpAndDisappear();
// Trigger glowing particles effect at the gem's position
var glowingParticles = new GlowingParticles();
glowingParticles.init(gem.x, gem.y);
self.addChild(glowingParticles);
}
var index = self.gems.indexOf(gem);
if (index > -1) {
self.gems[index] = false;
// Increase score based on combo multiplier
var pointsAwarded = 10 * self.comboMultiplier;
score += pointsAwarded; // Update score with points awarded based on combo multiplier
LK.setScore(score);
// Display points at the gem's location with animation
var pointsText = new Text2("+" + pointsAwarded.toString(), {
size: 80,
weight: 600,
fill: "#ffffff",
anchorX: 0.5,
anchorY: 0.5,
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 8,
dropShadowOffsetX: 4,
dropShadowOffsetY: 4,
outline: true,
outlineColor: '#000000',
outlineThickness: 5
});
pointsText.y -= 20; // Make it a little bit higher
pointsText.anchor.set(.5);
pointsText.x = gem.x;
pointsText.y = gem.y;
game.addChild(pointsText);
// Animate points text: scale up and fade out
var scaleUpDuration = 500; // Duration to scale up in milliseconds
var fadeOutDuration = 500; // Duration to fade out in milliseconds
var maxScale = 1.5; // Maximum scale factor
var originalScale = 1; // Original scale
var startTime = Date.now();
var animate = function animate() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleUpDuration);
pointsText.scale.set(originalScale + (maxScale - originalScale) * progress);
pointsText.alpha = 1 - progress; // Fade out
if (progress < 1) {
LK.setTimeout(animate, 16); // Aim for roughly 60fps
} else {
pointsText.destroy(); // Destroy text after animation
}
};
animate();
// Increase combo multiplier for each consecutive match
self.comboMultiplier++;
scoreTxt.setText(score.toString()); // Update score display
}
});
if (matchFound) {
// If no match was found previously and it's not the first check, reset the combo multiplier
if (!matchFoundPreviously && matchFound) {
self.comboMultiplier = 1;
} else if (matchFound) {
// Increase combo multiplier for each consecutive match
self.comboMultiplier++;
}
self.checkForMatches(true);
} else if (matchFoundPreviously) {
LK.setTimeout(function () {
this.handleFallingGems();
}.bind(this), 200);
}
return matchFound;
};
self.handleGemClick = function (gem) {
gem.on('down', function (obj) {
self.dragStartGem = gem;
self.dragStartGemStartPosition = {
x: gem.x,
y: gem.y
};
var currentPos = obj.event.getLocalPosition(game);
self.dragStartPos = {
x: currentPos.x,
y: currentPos.y
};
// Highlight the drag start gem
self.dragStartGem.alpha = 0.5;
self.dragStartGem.scale.set(self.dragStartGem.baseScale * 1.1);
});
gem.on('move', function (obj) {
if (!self.dragStartGem) {
return;
}
var currentPos = obj.event.getLocalPosition(game);
//self.dragStartGem.x = self.dragStartGemStartPosition.x + currentPos.x - self.dragStartPos.x;
//self.dragStartGem.y = self.dragStartGemStartPosition.y + currentPos.y - self.dragStartPos.y;
var dx = currentPos.x - self.dragStartPos.x;
var dy = currentPos.y - self.dragStartPos.y;
if (Math.abs(dx) > gem.spacing / 2 || Math.abs(dy) > gem.spacing / 2) {
var directionX = dx > 0 ? 1 : -1;
var directionY = dy > 0 ? 1 : -1;
// Correctly identify if we should swap horizontally or vertically
if (Math.abs(dx) > Math.abs(dy)) {
// Swap horizontally
var swapGem = self.findGemByPosition(self.dragStartGem.x + gem.spacing * directionX, self.dragStartGem.y, self.dragStartGem);
} else {
// Swap vertically
var swapGem = self.findGemByPosition(self.dragStartGem.x, self.dragStartGem.y + gem.spacing * directionY, self.dragStartGem);
}
if (self.lastHintOverlay) {
self.lastHintOverlay.destroy();
}
if (swapGem && self.wouldSwapResultInMatch(self.dragStartGem, swapGem)) {
self.swapGems(self.dragStartGem, swapGem);
} else {
self.faintSwapGems(self.dragStartGem, swapGem, true);
}
self.dragStartGem.alpha = 1;
self.dragStartGem.scale.set(self.dragStartGem.baseScale * 1);
self.dragStartGem = null;
self.dragStartPos = null;
}
});
gem.on('up', function () {
if (self.dragStartGem) {
self.dragStartGem.alpha = 1; // Reset alpha to unhighlight the gem
self.dragStartGem.scale.set(self.dragStartGem.baseScale * 1);
}
self.dragStartGem = null;
self.dragStartPos = null;
});
};
self.initBoard = function () {
var colors = game.timer > 60 ? ['gemBlue', 'gemGreen', 'gemRed', 'gemPurple', 'gemYellow', 'gemOrange', 'gemCyan'] : ['gemBlue', 'gemGreen', 'gemRed', 'gemPurple', 'gemYellow', 'gemOrange'];
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 6; j++) {
var color = colors[Math.floor(Math.random() * colors.length)];
var gem = new Gem(color);
var gem = new Gem(color);
var gemSize = 100;
var margin = 10;
var boardWidth = game.width * .9;
var boardHeight = game.height * .9;
var gemsPerRow = 6;
var gemsPerColumn = 8;
var totalMarginWidth = margin * (gemsPerRow + 1);
var totalMarginHeight = margin * (gemsPerColumn + 1);
var availableWidth = boardWidth - totalMarginWidth;
var availableHeight = boardHeight - totalMarginHeight;
var scaledGemSize = Math.min(availableWidth / gemsPerRow, availableHeight / gemsPerColumn);
var xOffset = (game.width - boardWidth) / 2 + scaledGemSize / 2;
var yOffset = (game.height - boardHeight) / 2 + scaledGemSize / 2;
gem.spacing = scaledGemSize + margin;
self.spacing = gem.spacing;
var snappedPos = self.snapToGrid(xOffset + (scaledGemSize + margin) * j, yOffset + (scaledGemSize + margin) * i);
gem.x = snappedPos.x;
gem.y = snappedPos.y;
gem.scale.set(scaledGemSize / gemSize);
gem.scale.set(scaledGemSize / gemSize);
gem.baseScale = scaledGemSize / gemSize;
self.addChild(gem);
self.gems.push(gem);
self.handleGemClick(gem);
}
}
self.comboMultiplier = 1; // Initialize combo multiplier
self.checkForMatches();
};
});
// ChineseRedEnvelope class
var ChineseRedEnvelope = Container.expand(function () {
var self = Container.call(this);
var envelopeGraphics = self.attachAsset('redEnvelope', {
anchorX: 0.5,
anchorY: 0.5
});
self.init = function (x, y) {
self.x = x;
self.y = y;
var scaleAnimation = function scaleAnimation() {
var scaleUp = true;
var scaleValue = 1;
LK.setInterval(function () {
if (scaleUp) {
scaleValue += 0.01;
} else {
scaleValue -= 0.01;
}
if (scaleValue >= 1.1) {
scaleUp = false;
}
if (scaleValue <= 1) {
scaleUp = true;
}
self.scale.set(scaleValue * 2.0); // Make the envelope significantly larger
}, 100);
};
scaleAnimation();
self.on('down', function () {
var targetX = timerTxt.x;
var targetY = timerTxt.y;
var moveDuration = 1000; // Duration in milliseconds
var startTime = Date.now();
var animateMove = function animateMove() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / moveDuration);
// Apply a quadratic easing for a smooth curve
var curveProgress = Math.pow(progress, 2);
self.x = self.x + (targetX - self.x) * curveProgress;
self.y = self.y - 75 * Math.sin(Math.PI * progress) + (targetY - self.y) * curveProgress; // Add a sine wave pattern for vertical movement
if (progress < 1) {
LK.setTimeout(animateMove, 16);
} else {
game.timer += 5; // Grant 5 more seconds
timerTxt.setText(game.timer.toString()); // Update timer display
self.destroy(); // Remove the envelope after reaching the timer
}
};
animateMove();
});
// Initiate continuous glowing effect
function glowEffect() {
var glowParticle = new GlowingParticlesForRedEnvelopes(.3);
glowParticle.init(0, 0);
self.addChildAt(glowParticle, 0);
}
;
glowEffect();
// LK.setInterval(glowEffect, 500); // Add a glowing particle effect every 500ms
};
});
// ConfettiParticle class
var ConfettiParticle = Container.expand(function () {
var self = Container.call(this);
var confettiColors = ['confettiRed', 'confettiBlue', 'confettiGreen', 'confettiYellow', 'confettiPurple'];
var randomColor = confettiColors[Math.floor(Math.random() * confettiColors.length)];
var confettiGraphics = self.attachAsset(randomColor, {
anchorX: 0.5,
anchorY: 0.5
});
self.init = function (x, y) {
self.x = x;
self.y = y;
var angle = Math.random() * Math.PI * 2;
var speed = 0.5 + Math.random(); // Reduced speed for smoother appearance
var duration = 1500 + Math.random() * 2500; // Extended duration for smoother fade
var startTime = Date.now();
var animate = function animate() {
var currentTime = Date.now();
var progress = (currentTime - startTime) / duration;
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.alpha = Math.sin(progress * Math.PI); // Smooth in and out fading effect
if (progress < 1) {
LK.setTimeout(animate, 16);
} else {
self.destroy();
}
};
animate();
};
});
// Dragon class
var Dragon = Container.expand(function (gem) {
var self = Container.call(this);
var dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
dragonGraphics.anchor.set(1, .7);
self.speed = 5;
var hasTakenGem = false;
self.move = function () {
var endX = 2048 + self.width; // Ensure dragon ends off-screen to the right
var startX = -self.width; // Start off-screen to the left
var travelDistance = endX - startX;
var travelTime = 3000; // Time in milliseconds for the dragon to cross the screen
var startTime = Date.now();
var particleParts = [];
function animate() {
var currentTime = Date.now();
var elapsedTime = currentTime - startTime;
var progress = elapsedTime / travelTime;
self.x = startX + travelDistance * progress;
if (self.x > gem.x && !hasTakenGem) {
hasTakenGem = true;
self.addChild(gem);
// Animate gem scale upon grabbing
var scaleAnimationDuration = 300; // Duration of the scale animation in milliseconds
var scaleAnimationStartTime = Date.now();
var animateGemScale = function animateGemScale() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - scaleAnimationStartTime) / scaleAnimationDuration);
gem.scale.set(gem.baseScale * (.8 + .2 * Math.sin(progress * Math.PI * 2))); // Animate scale
if (progress < 1) {
LK.setTimeout(animateGemScale, 16);
} else {
gem.scale.set(gem.baseScale * .8);
}
};
animateGemScale();
gem.x = 50;
gem.y = 0;
var index = board.gems.indexOf(gem);
if (index > -1) {
if (board.gems[index] == gem) {
board.gems[index] = false;
}
}
LK.setTimeout(function () {
board.handleFallingGems();
}, 200);
}
if (hasTakenGem) {
self.addChild(gem);
//gem.scale.set(gem.baseScale * .8);
gem.x = 50;
gem.y = 0;
}
// Generate particle trail
if (progress < 1) {
LK.setTimeout(animate, 16); // Aim for roughly 60fps
} else {
var fadeoutparticle = function fadeoutparticle(particle) {
// Start fade out effect
var fadeOutDuration = 500; // Duration for the fade out in milliseconds
var fadeStartTime = Date.now();
var fadeStep = function fadeStep() {
var currentTime = Date.now();
var progress = (currentTime - fadeStartTime) / fadeOutDuration;
particle.alpha = 1 - progress; // Fade out
if (progress < 1) {
LK.setTimeout(fadeStep, 16);
} else {
particle.destroy(); // Destroy particle after fade out
}
};
fadeStep();
};
;
// Spawn a red envelope at a random position
//var envelope = new ChineseRedEnvelope();
//envelope.init(Math.random() * game.width, self.y);
//game.addChild(envelope);
// Destroy the dragon instance once it crosses the screen
isDragoning = false;
particleParts.forEach(function (particle) {
fadeoutparticle(particle);
});
self.destroy();
}
}
animate();
};
});
// FireworkParticle class
var FireworkParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('confettiRed', {
anchorX: 0.5,
anchorY: 0.5
});
self.init = function (x, y) {
self.x = x;
self.y = y;
var angle = Math.random() * Math.PI * 2;
var speed = 5 + Math.random() * 10; // Increased speed for firework effect
var duration = 500 + Math.random() * 500; // Shorter duration for quick explosion effect
var startTime = Date.now();
var animate = function animate() {
var currentTime = Date.now();
var progress = (currentTime - startTime) / duration;
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed - 9.8 * progress * progress; // Gravity effect
self.alpha = 1 - progress; // Fade out effect
if (progress < 1) {
LK.setTimeout(animate, 16);
} else {
self.destroy();
}
};
animate();
};
});
// Gem class
var Gem = Container.expand(function (color) {
var self = Container.call(this);
self.scaleUpAndDown = function (delay) {
LK.setTimeout(function () {
var scaleUpDuration = 150; // Duration to scale up in milliseconds
var scaleDownDuration = 150; // Duration to scale down in milliseconds
var maxScale = self.baseScale * 1.3; // Maximum scale factor
var originalScale = self.baseScale; // Remember the original scale
var scaleUp = function scaleUp() {
var startTime = Date.now();
var scaleStep = function scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleUpDuration);
self.scale.set(originalScale + (maxScale - originalScale) * progress);
if (progress < 1) {
LK.setTimeout(scaleStep, 16);
} else {
scaleDown();
}
};
scaleStep();
};
var scaleDown = function scaleDown() {
var startTime = Date.now();
var scaleStep = function scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleDownDuration);
self.scale.set(maxScale - (maxScale - originalScale) * progress);
if (progress < 1) {
LK.setTimeout(scaleStep, 16);
}
};
scaleStep();
};
scaleUp();
}, delay);
};
self.scaleUpAndDisappear = function scaleUpAndDisappear() {
var scaleUpDuration = 100; // Duration to scale up in milliseconds
var scaleDownDuration = 200; // Duration to scale down to zero
var maxScale = self.baseScale * 1.2; // Maximum scale factor
var disappearScale = 0; // Scale factor to disappear
var originalScale = self.baseScale; // Remember the original scale
// Animate scale up
// Start scale up
var scaleUpDuration = 100; // Duration to scale up in milliseconds
var disappearDuration = 200; // Duration to scale down to zero
var maxScale = self.baseScale * 1.2; // Maximum scale factor
var disappearScale = 0; // Scale factor to disappear
var originalScale = self.baseScale; // Remember the original scale
// Animate scale up
var startTime = Date.now();
var _scaleStep2 = function _scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleUpDuration);
self.scale.set(originalScale + (maxScale - originalScale) * progress);
if (progress < 1) {
LK.setTimeout(_scaleStep2, 16);
} else {
// Once scaled up, start disappearing
startTime = Date.now();
_scaleStep2 = function scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / disappearDuration);
self.scale.set(maxScale - (maxScale - disappearScale) * progress);
if (progress < 1) {
LK.setTimeout(_scaleStep2, 16);
} else {
self.destroy();
}
};
_scaleStep2();
}
};
_scaleStep2();
};
var gemGraphics = self.attachAsset(color, {
anchorX: 0.5,
anchorY: 0.5
});
self.color = color;
self.isSelected = false;
self.toggleSelect = function () {
self.isSelected = !self.isSelected;
if (self.isSelected) {
gemGraphics.alpha = 0.5;
self.scale.set(self.baseScale * 1.1);
} else {
gemGraphics.alpha = 1;
self.scale.set(self.baseScale);
}
};
});
// GlowingParticles class enhancement
var GlowingParticles = Container.expand(function () {
var self = Container.call(this);
scaleMultiplier = 1;
var _animateParticle = function animateParticle(particle) {
var currentTime = Date.now();
var elapsedTime = currentTime - particle.startTime;
var progress = elapsedTime / particle.duration;
if (progress < 1) {
particle.x += Math.cos(particle.angle) * particle.speed;
particle.y += Math.sin(particle.angle) * particle.speed;
particle.alpha = Math.cos(progress * Math.PI); // Smooth in and out fading effect
particle.rotation += particle.rotationVelocity; // Add rotation to each particle
LK.setTimeout(function () {
_animateParticle(particle);
}, 16);
} else {
particle.destroy();
}
};
self.init = function (x, y) {
for (var i = 0; i < 50; i++) {
var particle = self.attachAsset('glowEffect', {
x: x,
y: y,
anchorX: 0.5,
anchorY: 0.5
});
particle.blendMode = 1;
particle.angle = Math.random() * Math.PI * 2; // Random angle for direction
particle.speed = 1 + Math.random() * 2.5; // Adjusted speed for varied particle movement
particle.duration = 500 + Math.random() * 1000; // Keeping the duration dynamic
// Introduce gravity effect to some particles
for (var i = 0; i < 50; i++) {
var particle = self.attachAsset('glowEffect', {
x: x,
y: y,
anchorX: 0.5,
anchorY: 0.5
});
particle.blendMode = 1;
particle.angle = Math.random() * Math.PI * 2; // Random angle for direction
particle.speed = 1 + Math.random() * 2.5; // Adjusted speed for varied particle movement
particle.duration = 500 + Math.random() * 1000; // Keeping the duration dynamic
particle.gravity = Math.random() > 0.5 ? 0.01 : 0; // Half the particles have a gravity effect
particle.targetScale = 0.5 + Math.random() * 1.5; // Varied scale for more visual variety
particle.scale.set(particle.targetScale * scaleMultiplier); // Initial scale set based on the random scale variable
particle.startTime = Date.now();
particle.rotationVelocity = -0.1 + Math.random() * .2;
particle.x += Math.cos(particle.angle) * Math.random() * 80;
particle.y += Math.sin(particle.angle) * Math.random() * 80;
_animateParticle(particle);
}
particle.targetScale = 0.5 + Math.random() * 1.5; // Varied scale for more visual variety
particle.scale.set(particle.targetScale * scaleMultiplier); // Initial scale set based on the random scale variable
particle.startTime = Date.now();
particle.rotationVelocity = -0.1 + Math.random() * .2;
particle.x += Math.cos(particle.angle) * Math.random() * 80;
particle.y += Math.sin(particle.angle) * Math.random() * 80;
_animateParticle(particle);
}
};
});
// Define the GlowingParticlesForRedEnvelope class
var GlowingParticlesForRedEnvelope = Container.expand(function (scaleMultiplier) {
var self = Container.call(this);
var _animateParticle = function animateParticle(particle) {
var currentTime = Date.now();
var elapsedTime = currentTime - particle.startTime;
var progress = elapsedTime / particle.duration;
if (progress < 1) {
// Update particle properties for movement, fading, and rotation
particle.x += Math.cos(particle.angle) * particle.speed;
particle.y += Math.sin(particle.angle) * particle.speed;
particle.alpha = Math.cos(progress * Math.PI); // Fading effect
particle.rotation += particle.rotationVelocity;
} else {
// Reset particle to create a continuous effect
particle.startTime = Date.now(); // Reset start time
// Optionally, re-randomize properties for varied continuous effect
particle.angle = Math.random() * Math.PI * 2;
particle.speed = 1 + Math.random() * 1.5;
particle.duration = 500 + Math.random() * 1000;
particle.rotationVelocity = -0.1 + Math.random() * 0.2;
particle.x = particle.initialX + Math.cos(particle.angle) * Math.random() * 50;
particle.y = particle.initialY + Math.sin(particle.angle) * Math.random() * 50;
}
LK.setTimeout(function () {
_animateParticle(particle);
}, 16); // Continue animation loop
};
self.init = function (x, y) {
for (var i = 0; i < 50; i++) {
var particle = self.attachAsset('glowEffect', {
x: x,
y: y,
anchorX: 0.5,
anchorY: 0.5
});
particle.blendMode = 1;
particle.alpha = 0;
particle.initialX = x; // Store initial position
particle.initialY = y;
particle.angle = Math.random() * Math.PI * 2;
particle.speed = 1 + Math.random() * 1.5;
particle.duration = 500 + Math.random() * 1000;
particle.targetScale = 0.5 + Math.random() * 1.5;
particle.scale.set(particle.targetScale * scaleMultiplier);
particle.startTime = Date.now();
particle.rotationVelocity = -0.1 + Math.random() * 0.2;
particle.x += Math.cos(particle.angle) * Math.random() * 70;
particle.y += Math.sin(particle.angle) * Math.random() * 70;
_animateParticle(particle);
}
};
});
var GlowingParticlesForRedEnvelopes = Container.expand(function (scaleMultiplier) {
var self = Container.call(this);
var _animateParticle = function animateParticle(particle) {
var currentTime = Date.now();
var elapsedTime = currentTime - particle.startTime;
var progress = elapsedTime / particle.duration;
if (progress < 1) {
// Update particle properties for movement, fading, and rotation
particle.x += Math.cos(particle.angle) * particle.speed;
particle.y += Math.sin(particle.angle) * particle.speed;
particle.alpha = Math.cos(progress * Math.PI); // Fading effect
particle.rotation += particle.rotationVelocity;
} else {
// Reset particle to create a continuous effect
particle.startTime = Date.now(); // Reset start time
// Optionally, re-randomize properties for varied continuous effect
particle.angle = Math.random() * Math.PI * 2;
particle.speed = 1 + Math.random() * 1.5;
particle.duration = 500 + Math.random() * 1000;
particle.rotationVelocity = -0.1 + Math.random() * 0.2;
particle.x = particle.initialX + Math.cos(particle.angle) * Math.random() * 50;
particle.y = particle.initialY + Math.sin(particle.angle) * Math.random() * 50;
}
LK.setTimeout(function () {
_animateParticle(particle);
}, 16); // Continue animation loop
};
self.init = function (x, y) {
for (var i = 0; i < 50; i++) {
var particle = self.attachAsset('glowEffect', {
x: x,
y: y,
anchorX: 0.5,
anchorY: 0.5
});
particle.blendMode = 1;
particle.alpha = 0;
particle.initialX = x; // Store initial position
particle.initialY = y;
particle.angle = Math.random() * Math.PI * 2;
particle.speed = 1 + Math.random() * 1.5;
particle.duration = 500 + Math.random() * 1000;
particle.targetScale = 0.5 + Math.random() * 1.5;
particle.scale.set(particle.targetScale * scaleMultiplier);
particle.startTime = Date.now();
particle.rotationVelocity = -0.1 + Math.random() * 0.2;
particle.x += Math.cos(particle.angle) * Math.random() * 70;
particle.y += Math.sin(particle.angle) * Math.random() * 70;
_animateParticle(particle);
}
};
});
// LineSprite class
var LineSprite = Container.expand(function () {
var self = Container.call(this);
self.updateLine = function (startX, startY, endX, endY) {
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.width = distance;
self.height = 5; // Fixed height for the line
self.rotation = Math.atan2(dy, dx);
self.x = startX + dx / 2;
self.y = startY + dy / 2;
self.anchorX = 0.5;
self.anchorY = 0.5;
};
});
// RowBlasterGem class
var RowBlasterGem = Container.expand(function (color) {
var self = Container.call(this);
var gemGraphics = self.attachAsset(color, {
anchorX: 0.5,
anchorY: 0.5
});
self.color = color;
// Unique behavior for RowBlasterGem
self.activate = function () {
// Logic to blast the entire row
console.log('Blasting row...');
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
// Initialize a timer for showing hints
// Initialize 2-minute timer
// Initialize score
// Initialize large countdown at the beginning of the game
// Goal gem type and count
// Dragon spawn timer
// SagaMap class
// SagaMap class
var SagaMap = /*#__PURE__*/function (_Container) {
_inherits(SagaMap, _Container);
function SagaMap() {
var _this;
_classCallCheck(this, SagaMap);
_this = _callSuper(this, SagaMap);
_this.levels = [];
_this.currentLevel = 0;
return _this;
}
_createClass(SagaMap, [{
key: "addLevel",
value: function addLevel(level) {
this.levels.push(level);
}
}, {
key: "goToLevel",
value: function goToLevel(index) {
this.currentLevel = index;
// Logic to switch to the specified level
console.log('Switching to level:', index);
}
}, {
key: "nextLevel",
value: function nextLevel() {
if (this.currentLevel < this.levels.length - 1) {
this.goToLevel(this.currentLevel + 1);
} else {
console.log('No more levels!');
}
}
}]);
return SagaMap;
}(Container);
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof2(o);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) {
descriptor.writable = true;
}
Object.defineProperty(target, _toPropertyKey2(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) {
_defineProperties(Constructor.prototype, protoProps);
}
if (staticProps) {
_defineProperties(Constructor, staticProps);
}
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _toPropertyKey2(t) {
var i = _toPrimitive2(t, "string");
return "symbol" == _typeof2(i) ? i : String(i);
}
function _toPrimitive2(t, r) {
if ("object" != _typeof2(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof2(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _possibleConstructorReturn(self, call) {
if (call && (_typeof2(call) === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
return !!t;
})();
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) {
_setPrototypeOf(subClass, superClass);
}
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
var SagaMap = /*#__PURE__*/function (_Container) {
_inherits(SagaMap, _Container);
function SagaMap() {
var _this;
_classCallCheck(this, SagaMap);
_this = _callSuper(this, SagaMap);
_this.levels = [];
_this.currentLevel = 0;
return _this;
}
_createClass(SagaMap, [{
key: "addLevel",
value: function addLevel(level) {
this.levels.push(level);
}
}, {
key: "goToLevel",
value: function goToLevel(index) {
this.currentLevel = index;
// Logic to switch to the specified level
console.log('Switching to level:', index);
}
}, {
key: "nextLevel",
value: function nextLevel() {
if (this.currentLevel < this.levels.length - 1) {
this.goToLevel(this.currentLevel + 1);
} else {
console.log('No more levels!');
}
}
}]);
return SagaMap;
}(Container);
var dragonSpawnTimer;
var isDragoning = false;
function triggerDragon() {
if (dragonSpawnTimer) {
LK.clearTimeout(dragonSpawnTimer);
}
if (!isDragoning && board && board.gems && board.gems.length > 0) {
isDragoning = true;
var randomIndex = Math.floor(Math.random() * board.gems.length);
var gemToRemove = board.gems[randomIndex];
if (gemToRemove) {
var dragon = new Dragon(gemToRemove);
dragon.x = -100; // Ensure dragon starts off-screen to the left
dragon.y = gemToRemove.y; // Random y position within game bounds
game.addChild(dragon);
dragon.move();
}
}
var nextSpawnTime = 5000 + Math.random() * 10000; // Random interval between 5 to 15 seconds
dragonSpawnTimer = LK.setTimeout(triggerDragon, nextSpawnTime);
}
triggerDragon();
var goalGemType;
var matchedGemCount = 0;
var hintTimer;
var currentGoalGemSprite = false;
var goalLevel = 0;
// Function to randomly set the goal gem type from the available gem colors
function setRandomGoalGemType() {
var gemColors = ['gemBlue', 'gemGreen', 'gemRed', 'gemPurple', 'gemYellow', 'gemOrange', 'gemCyan'];
goalGemType = gemColors[Math.floor(Math.random() * gemColors.length)];
goalGemCount = 3 + Math.floor(Math.random() * goalLevel);
matchedGemCount = 0;
LK.setTimeout(function () {
// Update the goal text with the chosen gem type
goalTxt.setText(matchedGemCount + '/' + goalGemCount);
// Add hourglass sprite next to the timer
if (currentGoalGemSprite) {
currentGoalGemSprite.destroy();
}
currentGoalGemSprite = LK.getAsset(goalGemType, {
x: 2048 - 100,
// Position next to the timer
y: 50,
// Align with the timer's top margin
anchorX: .5,
// Anchor right for right alignment
anchorY: .5 // Anchor top for top alignment
});
currentGoalGemSprite.y = goalTxt.y;
currentGoalGemSprite.x = goalBackground.x; // Position next to the timer
currentGoalGemSprite.anchor.set(0.5, 0.5); // Align with the timer's top margin
currentGoalGemSprite.rotation = -.2;
currentGoalGemSprite.scale.set(1.6);
if (goalBackground.parent) {
goalBackground.parent.removeChild(goalBackground);
}
if (goalTxt.parent) {
goalTxt.parent.removeChild(goalTxt);
}
if (currentGoalGemSprite.parent) {
currentGoalGemSprite.parent.removeChild(currentGoalGemSprite);
}
LK.setTimeout(function () {
board.addChild(goalBackground);
game.addChild(goalBackground);
game.addChild(goalTxt);
game.addChild(currentGoalGemSprite);
}, 1000);
}, 1000);
}
// setRandomGoalGemType(); // Initialize the goal gem type at the start of the game
// This call has been moved to after the definition of goalTxt to fix the bug
// Function to reset and start the hint timer
function resetHintTimer() {
if (hintTimer) {
LK.clearTimeout(hintTimer);
}
hintTimer = LK.setTimeout(function () {
board.showHint();
resetHintTimer();
}, 5000); // Show hint after 5 seconds of inactivity
}
resetHintTimer();
// Reset the hint timer whenever a move is made
LK.on('tick', function () {
// This is a placeholder for any game action, e.g., gem swap, that resets the hint timer
// resetHintTimer();
});
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : String(i);
}
function _toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
var welcomeText = new Text2("Year of the Dragon", {
size: 110,
fill: "#ffff00",
x: 1024,
// Center of the screen
y: 1366,
// Middle of the screen
anchorX: 0.5,
anchorY: 0.5,
stroke: true,
weight: 800,
dropShadow: true,
dropShadowDistance: 20,
strokeColor: '#ff0000',
strokeThickness: 14
});
welcomeText.anchor.set(.5);
LK.gui.center.addChild(welcomeText); // Add countdown display to the center GUI layer
welcomeText.y = -200;
var countdownValue = 3; // Start countdown from 3
var countdownTxt = new Text2(countdownValue.toString(), {
size: 300,
fill: "#ffffff",
x: 1024,
// Center of the screen
y: 1366,
// Middle of the screen
anchorX: 0.5,
anchorY: 0.5,
stroke: true,
weight: 800,
dropShadow: true,
strokeThickness: 14
});
countdownTxt.anchor.set(.5);
LK.gui.center.addChild(countdownTxt); // Add countdown display to the center GUI layer
var countdownInterval = LK.setInterval(function () {
countdownValue -= 1;
if (countdownValue > 0) {
countdownTxt.setText(countdownValue.toString());
// Bounce effect for countdown numbers
var scaleUpDuration = 100; // Duration to scale up in milliseconds
var scaleDownDuration = 100; // Duration to scale down in milliseconds
var maxScale = 1.2; // Maximum scale factor
var originalScale = 1; // Remember the original scale
var scaleUp = function scaleUp() {
var startTime = Date.now();
var scaleStep = function scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleUpDuration);
countdownTxt.scale.set(originalScale + (maxScale - originalScale) * progress);
if (progress < 1) {
LK.setTimeout(scaleStep, 16);
} else {
scaleDown();
}
};
scaleStep();
};
var scaleDown = function scaleDown() {
var startTime = Date.now();
var scaleStep = function scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleDownDuration);
countdownTxt.scale.set(maxScale - (maxScale - originalScale) * progress);
if (progress < 1) {
LK.setTimeout(scaleStep, 16);
}
};
scaleStep();
};
scaleUp();
} else if (countdownValue === 0) {
countdownTxt.setText('Happy new year!');
countdownTxt.setStyle({
size: 80,
fill: "#ffffff",
x: 1024,
// Center of the screen
y: 1366,
// Middle of the screen
anchorX: 0.5,
anchorY: 0.5,
stroke: true,
weight: 800,
dropShadow: true,
dropShadowDistance: 20,
strokeColor: '#ff0000',
strokeThickness: 14
});
spinHourglass();
// Bounce effect
var scaleUpDuration = 200; // Duration to scale up in milliseconds
var scaleDownDuration = 200; // Duration to scale down in milliseconds
var maxScale = 1.5; // Maximum scale factor
var originalScale = 1; // Remember the original scale
var scaleUp = function scaleUp() {
var startTime = Date.now();
var scaleStep = function scaleStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / scaleUpDuration);
countdownTxt.scale.set(originalScale + (maxScale - originalScale) * progress);
if (progress < 1) {
LK.setTimeout(scaleStep, 16);
} else {
scaleDown();
}
};
scaleStep();
};
var scaleDown = function scaleDown() {
var fadeOutDuration = 1500; // Duration for the fade out in milliseconds
var startTime = Date.now();
var fadeStep = function fadeStep() {
var currentTime = Date.now();
var progress = Math.min(1, (currentTime - startTime) / fadeOutDuration);
countdownTxt.alpha = 1 - progress; // Fade out
welcomeText.alpha = 1 - progress; // Fade out
if (progress < 1) {
LK.setTimeout(fadeStep, 16);
} else {
welcomeText.destroy(); // Remove countdown text after animation
countdownTxt.destroy(); // Remove countdown text after animation
LK.clearInterval(countdownInterval);
setRandomGoalGemType();
}
};
fadeStep();
};
scaleUp();
}
}, 1000); // Update countdown every second
game.timer = 120; // 2 minutes in seconds
// Implement a three second delay before starting the timer text interval
LK.setTimeout(function () {
// Timer control is now handled inside the modal display logic to pause during the modal display.
}, 3000);
var score = 0; // Starting score
var scoreBg;
var scoreBgNode = LK.getAsset('scoreBg', {
x: 1024 - 150,
// Centered based on the background size
y: 0,
anchorX: 0.5,
anchorY: 0
});
scoreBgNode.anchor.set(.5);
scoreBgNode.y = 50;
scoreBgNode.alpha = 1; // Set the background transparency to fully opaque to ensure visibility
LK.gui.top.addChild(scoreBgNode);
var scoreTxt = new Text2(score.toString(), _defineProperty(_defineProperty({
size: 110,
weight: 500,
fill: "#ffffff",
x: 1024,
// Center of the screen
y: 0,
// Adjusted to be within the background
anchorX: 0.5,
// Center horizontally
anchorY: 0,
// Anchor at the top
dropShadow: true,
dropShadowColor: '#000000',
shadowBlur: 4,
shadowOffsetX: 2,
shadowOffsetY: 2,
stroke: true,
strokeColor: '#000000'
}, "stroke", '#000000'), "strokeThickness", 7));
scoreTxt.anchor.set(.5, .5);
scoreTxt.y = 50;
LK.gui.top.addChild(scoreTxt); // Add score display to the top GUI layer
// List of background images for different goal levels
var backgroundImages = ['magicalBackground', 'enchantedForest', 'mysticCave', 'celestialRealm'];
// Function to update the game background according to the current goal level
function updateBackground() {
var backgroundImageId = backgroundImages[goalLevel % backgroundImages.length];
var oldBackground = game.background;
if (oldBackground) {
LK.setTimeout(function () {
oldBackground.destroy();
}, 1000);
}
var background = LK.getAsset(backgroundImageId, {
anchorX: 0.5,
anchorY: 0.5
});
background.x = game.width / 2;
background.y = game.height / 2;
background.scale.set(Math.max(game.height / background.height, game.width / background.width));
background.alpha = 0; // Start fully transparent
var fadeInDuration = 1000; // Duration for the fade in milliseconds
var fadeInStartTime = Date.now();
var fadeInStep = function fadeInStep() {
var currentTime = Date.now();
var progress = (currentTime - fadeInStartTime) / fadeInDuration;
background.alpha = progress; // Fade in
if (progress < 1) {
LK.setTimeout(fadeInStep, 16);
} else {
background.alpha = 1;
if (oldBackground) {}
}
};
fadeInStep();
// This line is removed to prevent script errors related to incorrect usage of addChildAt.
// Instead, we'll use addChild and manage layering through careful addition order.
game.addChildAt(background, Math.min(1, game.children.length));
game.background = background;
}
// Initially set the background
updateBackground();
// Add the game board background to the game
var gameBoardBg = game.addChild(LK.getAsset('gameBoardBg', {
x: 0,
y: 0,
anchorX: 0,
anchorY: 0
}));
gameBoardBg.width = game.width * 0.9;
gameBoardBg.height = game.height * 0.9;
gameBoardBg.x = (game.width - gameBoardBg.width) / 2;
gameBoardBg.y = (game.height - gameBoardBg.height) / 2 + 80;
gameBoardBg.alpha = 0.6; // Set the background transparency to make it slightly visible
// Initialize the board
// Define assets for the game
var board = new Board();
game.addChild(board);
board.initBoard();
function animateGemsInWave(board) {
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 6; j++) {
var gem = board.gems[i * 6 + j];
if (gem && typeof gem.scaleUpAndDown === 'function') {
gem.scaleUpAndDown((i + j) * 50);
}
}
}
}
animateGemsInWave(board);
// Game logic
LK.on('tick', function () {
// Add game logic that needs to run every frame
// For example, checking for matches, handling animations, etc.
});
// Add a label with the same styling as the timer text, but with the opposite x-coordinate
var goalTxt = new Text2('', {
size: 100,
weight: 500,
fill: "#ffffff",
x: 0,
// Opposite x-coordinate
y: 50,
anchorX: 0,
anchorY: 0,
dropShadow: true,
dropShadowColor: '#000000',
shadowBlur: 4,
shadowOffsetX: 2,
shadowOffsetY: 2,
strokeThickness: 7
});
board.addChild(goalTxt);
goalTxt.anchor.set(0, .5);
goalTxt.y = 100;
goalTxt.x = 450;
// Add hourglass sprite next to the timer
var goalBackground = LK.getAsset('goalBackgroundSprite', {
x: 2048 - 100,
// Position next to the timer
y: 50,
// Align with the timer's top margin
anchorX: .5,
// Anchor right for right alignment
anchorY: .5 // Anchor top for top alignment
});
goalBackground.y = goalTxt.y;
goalBackground.x = goalTxt.x - 100; // Position next to the timer
goalBackground.anchor.set(0.5, 0.5); // Align with the timer's top margin
goalBackground.alpha = .6;
var timerTxt = new Text2(game.timer.toString(), {
size: 100,
// Made the text smaller
weight: 500,
fill: "#ffffff",
x: 2048 - 200,
y: 50,
anchorX: 1,
anchorY: 0,
dropShadow: true,
dropShadowColor: '#000000',
shadowBlur: 4,
shadowOffsetX: 2,
shadowOffsetY: 2,
strokeThickness: 7
});
// Add hourglass sprite next to the timer
var hourglassSprite = LK.getAsset('hourglass', {
x: 2048 - 100,
// Position next to the timer
y: 50,
// Align with the timer's top margin
anchorX: .5,
// Anchor right for right alignment
anchorY: .5 // Anchor top for top alignment
});
function stopTimer() {
if (board.timerInterval) {
LK.clearInterval(board.timerInterval);
}
}
function startTimer() {
// Resume the game timer after the modal disappears
stopTimer();
board.timerInterval = LK.setInterval(function () {
game.timer -= 1;
timerTxt.setText(game.timer.toString());
if (game.timer <= 0) {
LK.showGameOver('Final Score: ' + score);
}
}, 1000);
}
// Logic to spin the hourglass
var spinHourglass = function spinHourglass() {
var rotationDuration = 500; // Duration of the spin in milliseconds
var startTime = Date.now();
var spinStep = function spinStep() {
var currentTime = Date.now();
var progress = (currentTime - startTime) / rotationDuration;
hourglassSprite.rotation = progress * 2 * Math.PI; // Complete rotation
if (progress < 1) {
LK.setTimeout(spinStep, 16); // Aim for roughly 60fps
} else {
hourglassSprite.rotation = 0;
startTimer();
}
};
spinStep();
};
board.addChild(hourglassSprite);
timerTxt.anchor.set(1, .5);
timerTxt.y = 100;
timerTxt.x = 2048 - 240;
board.addChild(timerTxt); // Add timer display to the top GUI layer
hourglassSprite.y = timerTxt.y;
hourglassSprite.x = timerTxt.x + 70; // Position next to the timer
hourglassSprite.anchor.set(0.5, 0.5); // Align with the timer's top margin
Magic, purple gem. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
glow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Hourglass icon white. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Glow glare star. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Cute toony red cool dragon in flight sideview. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Shiny red envelope bao, chinese new years. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Magic greem gem in odd shape. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Magic Orange Gem. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Magic Blue Drop Shaped Gem. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
remove
Brilliant Gold Checkmark. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Magic diamond. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Mystic cavern. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Chinese new years, magical landscape, year of the dragon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.