User prompt
when a tile containing a coin is destroyed, play the Gem sound
User prompt
whenever any of the 4 tiles is destroyed, play the Pop sound
Code edit (1 edits merged)
Please save this source code
User prompt
when a tile is destroyed play the pop sound
User prompt
when a tile is destroyed play the pop sound
User prompt
Migrate to the latest version of LK
Code edit (5 edits merged)
Please save this source code
User prompt
right now the lives refill but only if a coin is discovered through a chain reaction. manual input should be considered as well, so if a coin is hidden under the domino flipped by the player's input, that should refill a life as well. so first deduct a life as the cost for tipping the domino, and if that domino happened to have a coin underneath, refill the life immediatelly afterwards
Code edit (1 edits merged)
Please save this source code
User prompt
increase the projectile acceleration
User prompt
after a projectile is destroyed at the edge of the screen, randomize the direction of the remaining dominos
User prompt
display the domino asset over the dominos containing a hidden coin
User prompt
show the domino asset over the dominos containing a hidden coin
User prompt
sometimes finding a coin doesnt refill a life. this happens in specific scenarioswhere the coin is found directly from a domino tilted by a player tap. so the example is that I start the game with 3 lifes. if a coin is hidden under the first domino I tilt, a life should be deducted since I just tilted a domino, and since there was a coin under the domino, it should refill the life afterwards, however in this specific scenarion, the life never refills. so first deduct a life since I tapped the domino, and if the domino contains a coin, immeditelly refill the life
User prompt
sometimes finding a coin doesnt refill a life. this happens in specific scenarioswhere the coin is found directly from a domino tilted by a player tap. so the example is that I start the game with 3 lifes. if a coin is hidden under the first domino I tilt, a life should be deducted since I just tilted a domino, and since there was a coin under the domino, it should refill the life afterwards, however in this specific scenarion, the life never refills. so first deduct a life since I tapped the domino, and if the domino contains a coin, immeditelly refill the life
User prompt
remove the domino asset from the dominos that contain a hidden coin
User prompt
remove the domino asset from the tiles containing a hidden coin, i nthis part of the code if (hasHiddenCoin) { domino.attachAsset('domino', { anchorX: 0.5, anchorY: 0.5 }); }
User prompt
sometimes finding a coin doesnt refill a life. this happens in specific scenarioswhere the coin is found directly from a domino tilted by a player tap. so the example is that I start the game with 3 lifes. if a coin is hidden under the first domino I tilt, a life should be deducted since I just tilted a domino, and since there was a coin under the domino, it should refill the life afterwards, however in this specific scenarion, the life never refills. so first deduct a life since I tapped the domino, and if the domino contains a coin, immeditelly refill the life
User prompt
display the asset called domino over the dominos that contain the hidden coins
User prompt
sometimes finding a coin doesnt refill a life. this happens in specific scenarioswhere the coin is found directly from a domino tilted by a player tap. so the example is that I start the game with 3 lifes. if a coin is hidden under the first domino I tilt, a life should be deducted since I just tilted a domino, and since there was a coin under the domino, it should refill the life afterwards, however in this specific scenarion, the life never refills. fix it
Code edit (1 edits merged)
Please save this source code
/**** * Classes ****/ // Assets will be automatically generated based on usage in the code. // Domino class var Domino = Container.expand(function () { var self = Container.call(this); // Assuming directionsList is a shuffled array of directions ['U', 'L', 'R', 'D'] repeated to match the number of dominos self.direction = directionsList.shift(); // Updated asset attachment logic based on direction switch (self.direction) { case 'U': dominoGraphics = self.attachAsset('D_Up', { anchorX: 0.5, anchorY: 0.5 }); break; case 'D': dominoGraphics = self.attachAsset('D_Down', { anchorX: 0.5, anchorY: 0.5 }); break; case 'L': dominoGraphics = self.attachAsset('D_Left', { anchorX: 0.5, anchorY: 0.5 }); break; case 'R': dominoGraphics = self.attachAsset('D_Right', { anchorX: 0.5, anchorY: 0.5 }); break; } self.isTipped = false; self.hiddenCoin = false; // Indicates whether a coin is hidden underneath // Direction is already set at the beginning of the constructor. // Direction label code removed as it's no longer necessary with direction-specific assets self.tip = function (projectile, isPlayerAction) { if (projectile) { projectilePool.put(projectile); // Recycle the projectile immediately var index = projectiles.indexOf(projectile); if (index !== -1) { projectiles.splice(index, 1); // Remove from tracking array } } if (!self.isTipped) { self.isTipped = true; if (self.hiddenCoin) { // Change appearance to a coin and increase score by 10 points self.destroy(); var coin = new Container(); // Initialize frame index and timestamps for animation coin.frameIndex = 0; coin.lastFrameTimestamp = 0; coin.frames = ['coin', 'Coin_1', 'Coin_2', 'Coin_3']; // Initialize frame index for animation and set last frame change time to 0 coin.frameIndex = 0; coin.lastFrameChangeTime = 0; coin.frames = ['coin', 'Coin_1', 'Coin_2', 'Coin_3']; // Attach the first frame of the coin animation coin.attachAsset(coin.frames[coin.frameIndex], { anchorX: 0.5, anchorY: 0.5 }); // Update method to handle frame change coin.update = function () { // Get current time in milliseconds var currentTime = Date.now(); // Change frame every second if (currentTime - coin.lastFrameChangeTime >= 200) { coin.frameIndex = (coin.frameIndex + 1) % coin.frames.length; coin.removeChildAt(0); // Remove the current frame // Attach the next frame coin.attachAsset(coin.frames[coin.frameIndex], { anchorX: 0.5, anchorY: 0.5 }); coin.lastFrameChangeTime = currentTime; } }; // Add the coin to the game's update loop LK.on('tick', function () { coin.update(); }); game.addChild(coin); coin.x = self.x; coin.y = self.y; score += 10; // Increase score by 10 points for revealing a coin // This block is intentionally left unchanged as it correctly implements the requirement. if (self.hiddenCoin) { replenishLife(); // Call replenishLife function only if a hidden coin is discovered } } else { // Destroy the domino after it shoots its projectile self.destroy(); } // directionLabel removal code has been deprecated // Tip animation logic here LK.effects.flashObject(self, 0xffa500, 500); // Decrement lives only for direct player actions if (isPlayerAction) { lives -= 1; // Update UI_Projectile color to indicate a life has been used if (lives >= 0 && lives < livesIndicators.length) { livesIndicators[lives].alpha = 0; // Hide the life indicator } // Check for game over condition after the 3rd domino is tipped if (lives <= 0) { // Ensure this flag is checked in the projectile's edge collision logic isProjectileInMotion = true; } } // Increment score by 1 for all domino flips score += 1; scoreTxt.setText(score.toString()); background.alpha = Math.min(score * 0.0025, 1); // Increase alpha by 0.2 for each score point, up to a maximum of 1 // Shoot a projectile in the direction specified by the domino's symbol var projectile = projectilePool.get(); projectile.direction = self.direction; projectile.x = self.x; projectile.y = self.y; // Update the projectile's grid position projectile.gridX = Math.floor(projectile.x / 100); projectile.gridY = Math.floor(projectile.y / 100); game.addChild(projectile); projectiles.push(projectile); } // Update the domino's grid position self.gridX = Math.floor(self.x / 100); self.gridY = Math.floor(self.y / 100); }; }); // Factory class var Factory = Container.expand(function () { var self = Container.call(this); self.dominos = []; self.addDomino = function (x, y, hasHiddenCoin) { var domino = new Domino(); domino.x = x; domino.y = y; domino.hiddenCoin = hasHiddenCoin || false; self.addChild(domino); self.dominos.push(domino); }; self.reset = function () { self.dominos.forEach(function (domino) { domino.destroy(); // Destroy domino instance // Remove any event listeners attached to domino here if any }); self.dominos.length = 0; // Clear the array without creating a new one }; }); // Projectile class var Projectile = Container.expand(function () { var self = Container.call(this); var projectileGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5 }); self.direction = ''; self.speed = 10; self.move = function () { // Decrease acceleration factor var acceleration = 0.5; // Update speed with decreased acceleration self.speed += acceleration; switch (self.direction) { case 'U': self.y -= self.speed; break; case 'L': self.x -= self.speed; break; case 'R': self.x += self.speed; break; case 'D': self.y += self.speed; break; } // Update the projectile's grid position and check for collisions with dominos self.gridX = Math.floor(self.x / 100); self.gridY = Math.floor(self.y / 100); // Check for domino collisions after moving factory.dominos.forEach(function (domino) { if (!domino.isTipped && self.raycast(domino)) { domino.tip(self); // Pass this projectile to the domino's tip method // Reset projectile's speed to its original value after tipping a domino self.speed = 10; } }); }; self.raycast = function (domino) { // Calculate the distance between the projectile and the domino var dx = domino.x - self.x; var dy = domino.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // If the distance is less than the sum of their radii, there is an intersection return distance < self.width / 2 + domino.width / 2; }; }); /**** * Initialize Game ****/ // Initialize a new projectile pool var game = new LK.Game({ backgroundColor: 0xd3d3d3 // Set game background to light grey }); /**** * Game Code ****/ // Function to replenish a life function replenishLife() { if (lives < 3) { lives += 1; // Update the visual indicator for lives to fully opaque and visible to signify an active life livesIndicators[lives - 1].alpha = 1; livesIndicators[lives - 1].visible = true; } } var backgroundAsset = LK.getAsset('background', { anchorX: 0.0, anchorY: 0.0 }); var baseBackground = game.addChild(LK.getAsset('background', { x: 0, y: 0, width: game.width, height: game.height, tint: 0x000000 })); var background = game.addChild(LK.getAsset('background', { x: 0, y: 0, width: game.width, height: game.height, alpha: 0 })); // Function to shuffle an array function shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var _ref = [array[j], array[i]]; array[i] = _ref[0]; array[j] = _ref[1]; } } // Calculate total number of dominos based on grid size (16 columns * 20 rows) var totalDominos = 16 * 20; // Divide total by 4 to get number of dominos for each direction var dominosPerDirection = totalDominos / 4; // Create a list of directions with an equal number of 'U', 'L', 'R', 'D' var directionsList = []; ['U', 'L', 'R', 'D'].forEach(function (direction) { for (var i = 0; i < dominosPerDirection; i++) { directionsList.push(direction); } }); // Shuffle the directions list shuffleArray(directionsList); // Reset game flags and counters at the start of a new game session var score = 0; // Reset score to 0 var lives = 3; // Reset lives to 3 var isProjectileInMotion = false; // Reset projectile motion flag var awaitingLastProjectile = false; // Reset awaiting last projectile flag // Display score // Initialize UI_Projectile assets as lives indicators var livesIndicators = []; for (var i = 0; i < 3; i++) { var lifeIndicator = game.addChild(LK.getAsset('UI_Projectile', { x: 1600 + i * 150, // Moved 500 pixels to the right y: 130, anchorX: 0.5, anchorY: 0.5 })); livesIndicators.push(lifeIndicator); } var scoreTxt = new Text2(score.toString(), { size: 150, fill: "#ffffff", stroke: "#000000", // Black outline strokeThickness: 8 // Thickness of the outline }); scoreTxt.anchor.set(0.5, 0); // Center the score text horizontally LK.gui.top.addChild(scoreTxt); // Add the score text to the GUI overlay at the top-center of the screen // Custom intersects function for accurate collision detection function intersects(projectile, domino) { var projectileBounds = { left: projectile.x - projectile.width / 2, right: projectile.x + projectile.width / 2, top: projectile.y - projectile.height / 2, bottom: projectile.y + projectile.height / 2 }; var dominoBounds = { left: domino.x - domino.width / 2, right: domino.x + domino.width / 2, top: domino.y - domino.height / 2, bottom: domino.y + domino.height / 2 }; return !(projectileBounds.right < dominoBounds.left || projectileBounds.left > dominoBounds.right || projectileBounds.bottom < dominoBounds.top || projectileBounds.top > dominoBounds.bottom); } // Array to store all projectiles // ProjectilePool class var ProjectilePool = function ProjectilePool() { this.pool = []; this.get = function () { if (this.pool.length > 0) { return this.pool.pop(); } else { return new Projectile(); } }; this.put = function (projectile) { // Assuming projectiles might have event listeners attached // Remove event listeners from projectile here if any this.pool.push(projectile); }; }; // Initialize a new projectile pool var projectilePool = new ProjectilePool(); var projectiles = []; // Game tick function to move all projectiles and check for domino tipping LK.on('tick', function () { // Removed life replenishment every 100 points projectiles.forEach(function (projectile, i) { // Set isProjectileInMotion to true when a projectile starts moving isProjectileInMotion = true; // Move the projectile based on its direction projectile.move(); // Check for domino tipping within the same grid cell var tippedDomino = factory.dominos.find(function (domino) { return !domino.isTipped && domino.gridX === projectile.gridX && domino.gridY === projectile.gridY && projectile.intersects(domino); }); if (tippedDomino) { // Recycle the current projectile projectilePool.put(projectile); projectiles.splice(i, 1); // Trigger the projectile of the domino it just hit tippedDomino.tip(); } // Remove projectiles that have moved off screen if (projectile.x < 0 || projectile.x > 2048 || projectile.y < 0 || projectile.y > 2732) { projectile.destroy(); // Destroy the projectile when it hits the edge of the screen projectiles.splice(i, 1); // Remove from tracking array // Re-enable player input after projectile hits screen edge isProjectileInMotion = false; // Check if no lives are left and all projectiles have been processed before showing game over if (lives <= 0 && projectiles.length === 0 && !isProjectileInMotion) { awaitingLastProjectile = true; // Set the flag to true to wait for the last projectile } // Show game over screen if awaitingLastProjectile is true and all projectiles have been processed if (awaitingLastProjectile && projectiles.length === 0) { LK.showGameOver(); // Show game over screen awaitingLastProjectile = false; // Reset the flag after showing game over } } }); }); var factory = game.addChild(new Factory()); // Function to check and trigger domino tipping function checkAndTipDominos(x, y) { factory.dominos.forEach(function (domino) { if (Math.abs(domino.x - x) < 100 && Math.abs(domino.y - y) < 100) { domino.tip(); } }); } // Populate the factory with dominos and randomly select 20 to have hidden coins var dominoIndexesWithCoins = []; while (dominoIndexesWithCoins.length < 15) { var randomIndex = Math.floor(Math.random() * 320); // 320 is the total number of dominos (16*20) if (dominoIndexesWithCoins.indexOf(randomIndex) === -1) { dominoIndexesWithCoins.push(randomIndex); } } var dominoCounter = 0; for (var i = 0; i < 16; i++) { for (var j = 0; j < 20; j++) { factory.addDomino(2048 / 2 - 15 * 120 / 2 + i * 120, 2732 / 2 - 17.3 * 120 / 2 + j * 120, dominoIndexesWithCoins.includes(dominoCounter)); dominoCounter++; } } // Handle touch events to tip dominos // Flag to check if a projectile is in motion and if the game is awaiting the last projectile's conclusion after the last life is lost var isProjectileInMotion = false; var awaitingLastProjectile = false; game.on('down', function (obj) { // Check if a projectile is in motion before allowing domino tipping if (isProjectileInMotion) { return; } var pos = obj.event.getLocalPosition(game); // Find the closest domino to the tap position var closestDomino = factory.dominos.reduce(function (closest, domino) { var distance = Math.sqrt(Math.pow(domino.x - pos.x, 2) + Math.pow(domino.y - pos.y, 2)); if (distance < closest.distance) { return { domino: domino, distance: distance }; } else { return closest; } }, { domino: null, distance: Infinity }); // Tip the closest domino if it is within 100 units of the tap position if (closestDomino.distance < 100) { closestDomino.domino.tip(null, true); } });
/****
* Classes
****/
// Assets will be automatically generated based on usage in the code.
// Domino class
var Domino = Container.expand(function () {
var self = Container.call(this);
// Assuming directionsList is a shuffled array of directions ['U', 'L', 'R', 'D'] repeated to match the number of dominos
self.direction = directionsList.shift();
// Updated asset attachment logic based on direction
switch (self.direction) {
case 'U':
dominoGraphics = self.attachAsset('D_Up', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'D':
dominoGraphics = self.attachAsset('D_Down', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'L':
dominoGraphics = self.attachAsset('D_Left', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'R':
dominoGraphics = self.attachAsset('D_Right', {
anchorX: 0.5,
anchorY: 0.5
});
break;
}
self.isTipped = false;
self.hiddenCoin = false; // Indicates whether a coin is hidden underneath
// Direction is already set at the beginning of the constructor.
// Direction label code removed as it's no longer necessary with direction-specific assets
self.tip = function (projectile, isPlayerAction) {
if (projectile) {
projectilePool.put(projectile); // Recycle the projectile immediately
var index = projectiles.indexOf(projectile);
if (index !== -1) {
projectiles.splice(index, 1); // Remove from tracking array
}
}
if (!self.isTipped) {
self.isTipped = true;
if (self.hiddenCoin) {
// Change appearance to a coin and increase score by 10 points
self.destroy();
var coin = new Container();
// Initialize frame index and timestamps for animation
coin.frameIndex = 0;
coin.lastFrameTimestamp = 0;
coin.frames = ['coin', 'Coin_1', 'Coin_2', 'Coin_3'];
// Initialize frame index for animation and set last frame change time to 0
coin.frameIndex = 0;
coin.lastFrameChangeTime = 0;
coin.frames = ['coin', 'Coin_1', 'Coin_2', 'Coin_3'];
// Attach the first frame of the coin animation
coin.attachAsset(coin.frames[coin.frameIndex], {
anchorX: 0.5,
anchorY: 0.5
});
// Update method to handle frame change
coin.update = function () {
// Get current time in milliseconds
var currentTime = Date.now();
// Change frame every second
if (currentTime - coin.lastFrameChangeTime >= 200) {
coin.frameIndex = (coin.frameIndex + 1) % coin.frames.length;
coin.removeChildAt(0); // Remove the current frame
// Attach the next frame
coin.attachAsset(coin.frames[coin.frameIndex], {
anchorX: 0.5,
anchorY: 0.5
});
coin.lastFrameChangeTime = currentTime;
}
};
// Add the coin to the game's update loop
LK.on('tick', function () {
coin.update();
});
game.addChild(coin);
coin.x = self.x;
coin.y = self.y;
score += 10; // Increase score by 10 points for revealing a coin
// This block is intentionally left unchanged as it correctly implements the requirement.
if (self.hiddenCoin) {
replenishLife(); // Call replenishLife function only if a hidden coin is discovered
}
} else {
// Destroy the domino after it shoots its projectile
self.destroy();
}
// directionLabel removal code has been deprecated
// Tip animation logic here
LK.effects.flashObject(self, 0xffa500, 500);
// Decrement lives only for direct player actions
if (isPlayerAction) {
lives -= 1;
// Update UI_Projectile color to indicate a life has been used
if (lives >= 0 && lives < livesIndicators.length) {
livesIndicators[lives].alpha = 0; // Hide the life indicator
}
// Check for game over condition after the 3rd domino is tipped
if (lives <= 0) {
// Ensure this flag is checked in the projectile's edge collision logic
isProjectileInMotion = true;
}
}
// Increment score by 1 for all domino flips
score += 1;
scoreTxt.setText(score.toString());
background.alpha = Math.min(score * 0.0025, 1); // Increase alpha by 0.2 for each score point, up to a maximum of 1
// Shoot a projectile in the direction specified by the domino's symbol
var projectile = projectilePool.get();
projectile.direction = self.direction;
projectile.x = self.x;
projectile.y = self.y;
// Update the projectile's grid position
projectile.gridX = Math.floor(projectile.x / 100);
projectile.gridY = Math.floor(projectile.y / 100);
game.addChild(projectile);
projectiles.push(projectile);
}
// Update the domino's grid position
self.gridX = Math.floor(self.x / 100);
self.gridY = Math.floor(self.y / 100);
};
});
// Factory class
var Factory = Container.expand(function () {
var self = Container.call(this);
self.dominos = [];
self.addDomino = function (x, y, hasHiddenCoin) {
var domino = new Domino();
domino.x = x;
domino.y = y;
domino.hiddenCoin = hasHiddenCoin || false;
self.addChild(domino);
self.dominos.push(domino);
};
self.reset = function () {
self.dominos.forEach(function (domino) {
domino.destroy(); // Destroy domino instance
// Remove any event listeners attached to domino here if any
});
self.dominos.length = 0; // Clear the array without creating a new one
};
});
// Projectile class
var Projectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = '';
self.speed = 10;
self.move = function () {
// Decrease acceleration factor
var acceleration = 0.5;
// Update speed with decreased acceleration
self.speed += acceleration;
switch (self.direction) {
case 'U':
self.y -= self.speed;
break;
case 'L':
self.x -= self.speed;
break;
case 'R':
self.x += self.speed;
break;
case 'D':
self.y += self.speed;
break;
}
// Update the projectile's grid position and check for collisions with dominos
self.gridX = Math.floor(self.x / 100);
self.gridY = Math.floor(self.y / 100);
// Check for domino collisions after moving
factory.dominos.forEach(function (domino) {
if (!domino.isTipped && self.raycast(domino)) {
domino.tip(self); // Pass this projectile to the domino's tip method
// Reset projectile's speed to its original value after tipping a domino
self.speed = 10;
}
});
};
self.raycast = function (domino) {
// Calculate the distance between the projectile and the domino
var dx = domino.x - self.x;
var dy = domino.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If the distance is less than the sum of their radii, there is an intersection
return distance < self.width / 2 + domino.width / 2;
};
});
/****
* Initialize Game
****/
// Initialize a new projectile pool
var game = new LK.Game({
backgroundColor: 0xd3d3d3 // Set game background to light grey
});
/****
* Game Code
****/
// Function to replenish a life
function replenishLife() {
if (lives < 3) {
lives += 1;
// Update the visual indicator for lives to fully opaque and visible to signify an active life
livesIndicators[lives - 1].alpha = 1;
livesIndicators[lives - 1].visible = true;
}
}
var backgroundAsset = LK.getAsset('background', {
anchorX: 0.0,
anchorY: 0.0
});
var baseBackground = game.addChild(LK.getAsset('background', {
x: 0,
y: 0,
width: game.width,
height: game.height,
tint: 0x000000
}));
var background = game.addChild(LK.getAsset('background', {
x: 0,
y: 0,
width: game.width,
height: game.height,
alpha: 0
}));
// Function to shuffle an array
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var _ref = [array[j], array[i]];
array[i] = _ref[0];
array[j] = _ref[1];
}
}
// Calculate total number of dominos based on grid size (16 columns * 20 rows)
var totalDominos = 16 * 20;
// Divide total by 4 to get number of dominos for each direction
var dominosPerDirection = totalDominos / 4;
// Create a list of directions with an equal number of 'U', 'L', 'R', 'D'
var directionsList = [];
['U', 'L', 'R', 'D'].forEach(function (direction) {
for (var i = 0; i < dominosPerDirection; i++) {
directionsList.push(direction);
}
});
// Shuffle the directions list
shuffleArray(directionsList);
// Reset game flags and counters at the start of a new game session
var score = 0; // Reset score to 0
var lives = 3; // Reset lives to 3
var isProjectileInMotion = false; // Reset projectile motion flag
var awaitingLastProjectile = false; // Reset awaiting last projectile flag
// Display score
// Initialize UI_Projectile assets as lives indicators
var livesIndicators = [];
for (var i = 0; i < 3; i++) {
var lifeIndicator = game.addChild(LK.getAsset('UI_Projectile', {
x: 1600 + i * 150,
// Moved 500 pixels to the right
y: 130,
anchorX: 0.5,
anchorY: 0.5
}));
livesIndicators.push(lifeIndicator);
}
var scoreTxt = new Text2(score.toString(), {
size: 150,
fill: "#ffffff",
stroke: "#000000",
// Black outline
strokeThickness: 8 // Thickness of the outline
});
scoreTxt.anchor.set(0.5, 0); // Center the score text horizontally
LK.gui.top.addChild(scoreTxt); // Add the score text to the GUI overlay at the top-center of the screen
// Custom intersects function for accurate collision detection
function intersects(projectile, domino) {
var projectileBounds = {
left: projectile.x - projectile.width / 2,
right: projectile.x + projectile.width / 2,
top: projectile.y - projectile.height / 2,
bottom: projectile.y + projectile.height / 2
};
var dominoBounds = {
left: domino.x - domino.width / 2,
right: domino.x + domino.width / 2,
top: domino.y - domino.height / 2,
bottom: domino.y + domino.height / 2
};
return !(projectileBounds.right < dominoBounds.left || projectileBounds.left > dominoBounds.right || projectileBounds.bottom < dominoBounds.top || projectileBounds.top > dominoBounds.bottom);
}
// Array to store all projectiles
// ProjectilePool class
var ProjectilePool = function ProjectilePool() {
this.pool = [];
this.get = function () {
if (this.pool.length > 0) {
return this.pool.pop();
} else {
return new Projectile();
}
};
this.put = function (projectile) {
// Assuming projectiles might have event listeners attached
// Remove event listeners from projectile here if any
this.pool.push(projectile);
};
};
// Initialize a new projectile pool
var projectilePool = new ProjectilePool();
var projectiles = [];
// Game tick function to move all projectiles and check for domino tipping
LK.on('tick', function () {
// Removed life replenishment every 100 points
projectiles.forEach(function (projectile, i) {
// Set isProjectileInMotion to true when a projectile starts moving
isProjectileInMotion = true;
// Move the projectile based on its direction
projectile.move();
// Check for domino tipping within the same grid cell
var tippedDomino = factory.dominos.find(function (domino) {
return !domino.isTipped && domino.gridX === projectile.gridX && domino.gridY === projectile.gridY && projectile.intersects(domino);
});
if (tippedDomino) {
// Recycle the current projectile
projectilePool.put(projectile);
projectiles.splice(i, 1);
// Trigger the projectile of the domino it just hit
tippedDomino.tip();
}
// Remove projectiles that have moved off screen
if (projectile.x < 0 || projectile.x > 2048 || projectile.y < 0 || projectile.y > 2732) {
projectile.destroy(); // Destroy the projectile when it hits the edge of the screen
projectiles.splice(i, 1); // Remove from tracking array
// Re-enable player input after projectile hits screen edge
isProjectileInMotion = false;
// Check if no lives are left and all projectiles have been processed before showing game over
if (lives <= 0 && projectiles.length === 0 && !isProjectileInMotion) {
awaitingLastProjectile = true; // Set the flag to true to wait for the last projectile
}
// Show game over screen if awaitingLastProjectile is true and all projectiles have been processed
if (awaitingLastProjectile && projectiles.length === 0) {
LK.showGameOver(); // Show game over screen
awaitingLastProjectile = false; // Reset the flag after showing game over
}
}
});
});
var factory = game.addChild(new Factory());
// Function to check and trigger domino tipping
function checkAndTipDominos(x, y) {
factory.dominos.forEach(function (domino) {
if (Math.abs(domino.x - x) < 100 && Math.abs(domino.y - y) < 100) {
domino.tip();
}
});
}
// Populate the factory with dominos and randomly select 20 to have hidden coins
var dominoIndexesWithCoins = [];
while (dominoIndexesWithCoins.length < 15) {
var randomIndex = Math.floor(Math.random() * 320); // 320 is the total number of dominos (16*20)
if (dominoIndexesWithCoins.indexOf(randomIndex) === -1) {
dominoIndexesWithCoins.push(randomIndex);
}
}
var dominoCounter = 0;
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 20; j++) {
factory.addDomino(2048 / 2 - 15 * 120 / 2 + i * 120, 2732 / 2 - 17.3 * 120 / 2 + j * 120, dominoIndexesWithCoins.includes(dominoCounter));
dominoCounter++;
}
}
// Handle touch events to tip dominos
// Flag to check if a projectile is in motion and if the game is awaiting the last projectile's conclusion after the last life is lost
var isProjectileInMotion = false;
var awaitingLastProjectile = false;
game.on('down', function (obj) {
// Check if a projectile is in motion before allowing domino tipping
if (isProjectileInMotion) {
return;
}
var pos = obj.event.getLocalPosition(game);
// Find the closest domino to the tap position
var closestDomino = factory.dominos.reduce(function (closest, domino) {
var distance = Math.sqrt(Math.pow(domino.x - pos.x, 2) + Math.pow(domino.y - pos.y, 2));
if (distance < closest.distance) {
return {
domino: domino,
distance: distance
};
} else {
return closest;
}
}, {
domino: null,
distance: Infinity
});
// Tip the closest domino if it is within 100 units of the tap position
if (closestDomino.distance < 100) {
closestDomino.domino.tip(null, true);
}
});
red projectile rune. pixelated. 8-bit. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
artistic background of the inside the depths of an unlit dark cave filled with a variety of treasures, and a dragon sleeping over a massive pile of treasure chests at its heart. pixelated. 8-bit. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.