/****
* 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_migrated = 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_migrated();
});
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
LK.getSound('Gem').play(); // Play Gem sound when a tile containing a coin is destroyed
}
} else {
// Destroy the domino after it shoots its projectile
self.destroy();
LK.getSound('Pop').play(); // Play Pop sound when tile is destroyed
}
// directionLabel removal code has been deprecated
// Tip animation logic here
LK.effects.flashObject(self, 0xffa500, 500);
// Decrement lives only for direct player actions and immediately refill if a coin is discovered
if (isPlayerAction) {
lives -= 1; // Deduct a life for the action of tipping
// 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
}
// Refill life if a coin is discovered under the tipped domino
if (self.hiddenCoin) {
replenishLife();
}
// 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 = 20;
self._move_migrated = function () {
// Decrease acceleration factor
var acceleration = 2; // Increased acceleration
// 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_migrated();
// 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 (x, y, obj) {
// Check if a projectile is in motion before allowing domino tipping
if (isProjectileInMotion) {
return;
}
var pos = game.toLocal(obj.global);
// 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);
}
});
Terrain de golf avec un seul trou. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Drapeau de golf avec un flèche vers le haut. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Drapeau de golf avec un flèche vers le bas. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Drapeau de golf avec un flèche vers la gauche. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Drapeau de golf avec un flèche qui montre vers la droite. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Balle de golf en or. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Balle de golf. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.