User prompt
haz que no se pueda mover manualmente mientras estan en gravedad
User prompt
haz que las roturas por gravedad empiecen una vez finalicen las caidas
User prompt
si se empieza una nueva roptura de meme que no continue con el delay del anterior
User prompt
haz que a medida que se rompen caigan nuevos memes
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(cell1).to({' Line Number: 138
User prompt
Please fix the bug: 'Uncaught TypeError: tween.to is not a function' in or related to this line: 'tween.to(cell1, {' Line Number: 138
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'tween(cell1, {' Line Number: 138
User prompt
mejora la animación de salida de nuevos memes ara que sea más agradable ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz que a medida que se van rompiendo caigan nuevos memes
User prompt
Haz que el grid sea de 8*8 y aumenta su tamaño un 30%
User prompt
haz que la cuadricula sea 8*8 y aumenta su tamaño un 50%
User prompt
Si hay memes juntos, no se romperán después de unir un meme, solo se romperán cuando se junten con su mismo tipo por el jugador o por gravedad.
User prompt
Si hay memes juntos no se romperán después de romper un meme, solo se romperan cuando se junten con su mismo tipo por el jugador. Los memes juntados por la gravedad no cumlen esta regla
User prompt
agregale sonido al romperse los memes. agregale diley de roptura a los memes unido para hacerlo satisfactorio
User prompt
Haz que la rotura de los memes tenga diley entre cada una y agregale sonido
User prompt
has que despues de que se rompa un meme, los memes de superiores a el bajaran ocupando el espacio vacio
User prompt
Optimiza el codigo
User prompt
Analiza y busca el error que hace que no se pueda hacer cambios de lugar despues del primer movimiento
User prompt
agrega la característica de cambiar de posiciones los memes con sus adyacentes (vertical y horizontal)
User prompt
agrega la caracteristica de poder cambiar de posiciones los memes con sus adyacentes laterales
Code edit (1 edits merged)
Please save this source code
User prompt
Elimina el feedback de agarre y las variables relacionadas
User prompt
agrega una nueva funcionalidad para mover de lugar los memes de manera correcta
Code edit (1 edits merged)
Please save this source code
User prompt
ELimina la funcionalidad para cambiar de lugar los memes
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GridCell = Container.expand(function () {
var self = Container.call(this);
// Create the background square for the cell
var background = self.attachAsset('cuadricula', {
anchorX: 0.5,
anchorY: 0.5
});
// Add a slight shadow/glow effect to background for depth
background.alpha = 0.8;
// Initialize properties
self.value = 0;
self.sprite = null;
self.row = -1; // Initialize row property
self.col = -1; // Initialize col property
// Method to set value and corresponding sprite
self.setValue = function (newValue) {
self.value = newValue;
// Remove previous sprite if exists
if (self.sprite) {
self.removeChild(self.sprite);
}
// Create new sprite based on value
var spriteId = 'meme' + newValue;
self.sprite = LK.getAsset(spriteId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.9,
scaleY: 0.9
});
// Add sprite with a little animation for new cells
self.addChild(self.sprite);
self.sprite.alpha = 0;
self.sprite.scaleX = 0.5;
self.sprite.scaleY = 0.5;
// Animate in with a little bounce effect
tween(self.sprite, {
alpha: 1,
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 200,
easing: tween.easing.outBack
});
};
// Handle cell tap events
self.down = function (x, y, obj) {
// Pass this cell to the tap handler
handleCellTap(self);
};
return self;
});
/****
* Initialize Game
****/
// Grid configuration
var game = new LK.Game({
backgroundColor: 0xF4FFFF
});
/****
* Game Code
****/
// Initialize tween.easing if needed
// Grid configuration
if (!tween.easing) {
tween.easing = {
outBack: function outBack(t) {
return 1 - --t * t * (-3.5 * t + 2.5);
},
outQuad: function outQuad(t) {
return t * (2 - t);
},
outBounce: function outBounce(t) {
return t < 0.36363636 ? 7.5625 * t * t : t < 0.72727272 ? 7.5625 * (t -= 0.54545454) * t + 0.75 : t < 0.90909090 ? 7.5625 * (t -= 0.81818181) * t + 0.9375 : 7.5625 * (t -= 0.95454545) * t + 0.984375;
}
};
}
// Variables to track cell selection
var selectedCell = null;
function handleCellTap(tappedCell) {
// If no cell is currently selected
if (selectedCell === null) {
// Select this cell
selectedCell = tappedCell;
// Visual feedback for selection
LK.effects.flashObject(tappedCell.sprite, 0xFFFF00, 150);
// Add a small scale effect to show it's selected
tween(tappedCell.sprite, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easing.outQuad
});
} else {
// Check if the tapped cell is adjacent to the selected cell
var isAdjacent =
// Same row, adjacent column
selectedCell.row === tappedCell.row && Math.abs(selectedCell.col - tappedCell.col) === 1 ||
// Same column, adjacent row
selectedCell.col === tappedCell.col && Math.abs(selectedCell.row - tappedCell.row) === 1;
// If cells are adjacent, swap them
if (isAdjacent && !animationInProgress) {
animationInProgress = true;
// Store original positions for animation
var pos1 = {
x: selectedCell.x,
y: selectedCell.y
};
var pos2 = {
x: tappedCell.x,
y: tappedCell.y
};
// Swap cells in the grid array
var row1 = selectedCell.row;
var col1 = selectedCell.col;
var row2 = tappedCell.row;
var col2 = tappedCell.col;
// Swap cells in the gridCells array
gridCells[row1][col1] = tappedCell;
gridCells[row2][col2] = selectedCell;
// Update row/col properties on the cell objects
selectedCell.row = row2;
selectedCell.col = col2;
tappedCell.row = row1;
tappedCell.col = col1;
// Animate the swap
tween(selectedCell, {
x: pos2.x,
y: pos2.y
}, {
duration: 300,
easing: tween.easing.outQuad
});
tween(tappedCell, {
x: pos1.x,
y: pos1.y
}, {
duration: 300,
easing: tween.easing.outQuad,
onComplete: function onComplete() {
// Return selected cell sprite to normal size
tween(selectedCell.sprite, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 150,
easing: tween.easing.outQuad
});
// Check for matches after swap animation is complete
var foundMatches = checkForAndDestroyMatches(selectedCell, tappedCell);
// If no matches found from the initial swap, checkForAndDestroyMatches has reversed it.
// The animation for this specific user interaction (the swap and potential reversal) is done.
if (!foundMatches) {
animationInProgress = false;
}
// If foundMatches is true, checkForAndDestroyMatches has initiated a chain of events
// (destruction, refill, further checks). The final checkForAndDestroyMatches() in that
// chain (which finds no more matches) will set animationInProgress = false.
// Reset selected cell, allowing a new selection attempt.
// If animationInProgress is still true (due to ongoing cascades),
// a new swap attempt will be correctly blocked by the `!animationInProgress` check
// at the beginning of the swap logic.
selectedCell = null;
}
});
} else {
// If not adjacent or animation in progress, deselect first cell
// Return previously selected cell sprite to normal scale
tween(selectedCell.sprite, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 150,
easing: tween.easing.outQuad
});
// Reset selection
selectedCell = null;
// If not in animation, select the new cell
if (!animationInProgress) {
handleCellTap(tappedCell);
}
}
}
}
// Helper functions for match detection and destruction
function getMatches() {
var matches = [];
var cell1, nextCell, currentMatchValue, currentMatchCells;
// Horizontal matches - optimized loop
for (var r = 0; r < gridSize; r++) {
for (var c = 0; c < gridSize;) {
// Early exit optimization
if (c > gridSize - 3) {
// Not enough cells left for a match of 3
break; // Exit this row completely
}
cell1 = gridCells[r][c];
if (!cell1) {
// Skip empty cells
c++;
continue;
}
currentMatchValue = cell1.value;
currentMatchCells = [cell1];
// Find consecutive matching cells
var k = c + 1;
while (k < gridSize) {
nextCell = gridCells[r][k];
if (nextCell && nextCell.value === currentMatchValue) {
currentMatchCells.push(nextCell);
k++;
} else {
break; // End of current potential match
}
}
if (currentMatchCells.length >= 3) {
matches.push(currentMatchCells);
}
c += currentMatchCells.length; // Advance index by match length
}
}
// Vertical matches - optimized loop
for (var c = 0; c < gridSize; c++) {
for (var r = 0; r < gridSize;) {
// Early exit optimization
if (r > gridSize - 3) {
// Not enough cells left for a match of 3
break; // Exit this column completely
}
cell1 = gridCells[r][c];
if (!cell1) {
// Skip empty cells
r++;
continue;
}
currentMatchValue = cell1.value;
currentMatchCells = [cell1];
// Find consecutive matching cells
var k = r + 1;
while (k < gridSize) {
nextCell = gridCells[k][c];
if (nextCell && nextCell.value === currentMatchValue) {
currentMatchCells.push(nextCell);
k++;
} else {
break; // End of current potential match
}
}
if (currentMatchCells.length >= 3) {
matches.push(currentMatchCells);
}
r += currentMatchCells.length; // Advance index by match length
}
}
return matches;
}
function destroyCells(cellsToDestroy) {
// Process cells with staggered animation for visual appeal
for (var i = 0; i < cellsToDestroy.length; i++) {
var cell = cellsToDestroy[i];
// Defensive checks: ensure cell exists and is the one we expect in the grid
if (cell && gridCells[cell.row] && gridCells[cell.row][cell.col] === cell) {
// Visual effect before removal: flash and then explode
LK.effects.flashObject(cell, 0xFFFFFF, 100);
// Delayed animation for staggered effect
var delay = i * 30; // Stagger animations
// Animate the cell before removing it
tween(cell.sprite, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5,
rotation: Math.PI * 2
}, {
duration: 200,
delay: delay,
easing: tween.easing.outQuad,
onComplete: function onComplete() {
// Closure to capture the correct cell reference
var currentCell = cell;
return function () {
gridContainer.removeChild(currentCell); // Remove from display
currentCell.destroy(); // Destroy the cell object (releases resources)
gridCells[currentCell.row][currentCell.col] = null; // Mark as empty in the logical grid
};
}()
});
}
}
}
function refillGrid() {
// First move existing cells down to fill gaps
var hasMoved = false;
// Process each column
for (var col = 0; col < gridSize; col++) {
// Start from the bottom row and move up
for (var row = gridSize - 1; row > 0; row--) {
if (gridCells[row][col] === null) {
// Find the closest non-null cell above
var sourceRow = row - 1;
while (sourceRow >= 0 && gridCells[sourceRow][col] === null) {
sourceRow--;
}
if (sourceRow >= 0) {
// Move this cell down to the empty space
var movingCell = gridCells[sourceRow][col];
var targetY = startY + row * (cellSize + cellSpacing);
// Update the grid references
gridCells[row][col] = movingCell;
gridCells[sourceRow][col] = null;
// Update the cell's internal coordinates
movingCell.row = row;
// Animate the move
tween(movingCell, {
y: targetY
}, {
duration: 300,
easing: tween.easing.outQuad
});
hasMoved = true;
}
}
}
}
// Create new cells for any remaining empty spaces at the top
for (var col = 0; col < gridSize; col++) {
for (var row = 0; row < gridSize; row++) {
if (gridCells[row][col] === null) {
// Create a new cell
var newCell = new GridCell();
// Position cell (start above the grid and animate down)
newCell.x = startX + col * (cellSize + cellSpacing);
newCell.y = startY + (row - 3) * (cellSize + cellSpacing); // Start above grid
// Assign coordinates
newCell.row = row;
newCell.col = col;
// Generate random value
var randomValue = Math.floor(Math.random() * 5) + 1;
newCell.setValue(randomValue);
// Add to grid and animate down
gridContainer.addChild(newCell);
gridCells[row][col] = newCell;
// Animate falling into place
tween(newCell, {
y: startY + row * (cellSize + cellSpacing)
}, {
duration: 300,
delay: Math.min(50 * row, 200),
easing: tween.easing.outBounce
});
hasMoved = true;
}
}
}
return hasMoved;
}
function checkForAndDestroyMatches(swappedCellA, swappedCellB) {
var allMatchGroupsOnBoard = getMatches(); // Get all potential matches on the board
if (allMatchGroupsOnBoard.length === 0) {
// If this check is part of a cascade (i.e., not an initial swap check initiated by user)
// and no matches are found, it means the cascade sequence has ended.
// Thus, animations are considered complete.
if (!swappedCellA && !swappedCellB) {
// This condition checks if it's a cascade call
animationInProgress = false;
}
return false; // No matches found anywhere, nothing to do
}
var relevantMatchGroups = [];
// If swapped cells are provided, only check matches involving them
if (swappedCellA && swappedCellB) {
// Filter to find groups containing one of the swapped cells
for (var g = 0; g < allMatchGroupsOnBoard.length; g++) {
var group = allMatchGroupsOnBoard[g];
var groupIsRelevant = false;
for (var i = 0; i < group.length; i++) {
if (group[i] === swappedCellA || group[i] === swappedCellB) {
groupIsRelevant = true;
break;
}
}
if (groupIsRelevant) {
relevantMatchGroups.push(group);
}
}
// If this was a move that didn't create a match, swap cells back
if (relevantMatchGroups.length === 0) {
// Swap back the cells in the grid array
var row1 = swappedCellA.row;
var col1 = swappedCellA.col;
var row2 = swappedCellB.row;
var col2 = swappedCellB.col;
// Swap cells in the gridCells array
gridCells[row1][col1] = swappedCellB;
gridCells[row2][col2] = swappedCellA;
// Swap row/col properties on the cell objects
swappedCellA.row = row2;
swappedCellA.col = col2;
swappedCellB.row = row1;
swappedCellB.col = col1;
// Animate the swap back
tween(swappedCellA, {
x: startX + col2 * (cellSize + cellSpacing),
y: startY + row2 * (cellSize + cellSpacing)
}, {
duration: 300
});
tween(swappedCellB, {
x: startX + col1 * (cellSize + cellSpacing),
y: startY + row1 * (cellSize + cellSpacing)
}, {
duration: 300
});
return false;
}
} else {
// If no specific cells provided, check all matches (for cascade effects)
relevantMatchGroups = allMatchGroupsOnBoard;
}
// Proceed with destroying cells from the relevant match groups
var cellsToDestroy = [];
var uniqueCellTracker = {}; // To ensure each cell is added only once
for (var g = 0; g < relevantMatchGroups.length; g++) {
var group = relevantMatchGroups[g];
// Calculate points for this match
var matchPoints = group.length * 10;
// Bonus points for matches larger than 3
if (group.length > 3) {
matchPoints += (group.length - 3) * 10;
}
// Update score
LK.setScore(LK.getScore() + matchPoints);
// Add cells to destroy list
for (var c = 0; c < group.length; c++) {
var cell = group[c];
var cellKey = cell.row + "_" + cell.col;
if (!uniqueCellTracker[cellKey]) {
cellsToDestroy.push(cell);
uniqueCellTracker[cellKey] = true;
}
}
}
if (cellsToDestroy.length > 0) {
destroyCells(cellsToDestroy);
// After a short delay to allow destruction animations to complete,
// refill the grid and check for new matches
LK.setTimeout(function () {
refillGrid();
// Check for cascading matches after refill (with a delay)
LK.setTimeout(function () {
checkForAndDestroyMatches();
}, 500);
}, 300);
return true;
}
return false;
}
// Game variables
var gridSize = 9;
var cellSpacing = 10;
var cellSize = 160; // Width/height of the cell background
var gridCells = [];
// Calculate total grid width and height
var totalGridWidth = gridSize * cellSize + (gridSize - 1) * cellSpacing;
var totalGridHeight = totalGridWidth; // Grid is square
// Calculate starting position to center the grid
var startX = (2048 - totalGridWidth) / 2 + cellSize / 2;
var startY = (2732 - totalGridHeight) / 2 + cellSize / 2;
// Set up score display with improved visuals
var scoreText = new Text2("Score: 0", {
size: 80,
fill: 0x333333,
shadow: true,
shadowColor: 0xFFFFFF,
shadowBlur: 5,
shadowDistance: 3
});
scoreText.anchor.set(0.5, 0);
scoreText.x = 1024; // Center horizontally
scoreText.y = 50; // Top padding
LK.gui.top.addChild(scoreText);
// Variable to track last score value to avoid unnecessary updates
var lastScoreValue = 0;
// Create grid container
var gridContainer = new Container();
game.addChild(gridContainer);
// Add game update listener to handle score display updates
LK.on('tick', function () {
// Only update score text when the value changes
var currentScore = LK.getScore();
if (currentScore !== lastScoreValue) {
scoreText.setText("Score: " + currentScore);
// Add subtle animation when score changes
tween(scoreText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
easing: tween.easing.outQuad,
onComplete: function onComplete() {
tween(scoreText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easing.outQuad
});
}
});
lastScoreValue = currentScore;
}
});
// Flag to track if animations are in progress
var animationInProgress = false;
// Initialize score to 0
LK.setScore(0);
// Create grid cells
for (var row = 0; row < gridSize; row++) {
gridCells[row] = [];
for (var col = 0; col < gridSize; col++) {
// Create new cell
var cell = new GridCell();
// Position cell
cell.x = startX + col * (cellSize + cellSpacing);
cell.y = startY + row * (cellSize + cellSpacing);
// Assign row and column to the cell
cell.row = row;
cell.col = col;
// Generate random value between 1 and 5
var randomValue = Math.floor(Math.random() * 5) + 1;
cell.setValue(randomValue);
// Add to grid container and store reference
gridContainer.addChild(cell);
gridCells[row][col] = cell;
}
}
// Check and clear any initial matches that might exist on the grid
LK.setTimeout(function () {
checkForAndDestroyMatches();
}, 500); ===================================================================
--- original.js
+++ change.js
@@ -157,19 +157,20 @@
easing: tween.easing.outQuad
});
// Check for matches after swap animation is complete
var foundMatches = checkForAndDestroyMatches(selectedCell, tappedCell);
- // If no matches found, the swap will be reversed by checkForAndDestroyMatches
- // Reset animation status when everything is complete
+ // If no matches found from the initial swap, checkForAndDestroyMatches has reversed it.
+ // The animation for this specific user interaction (the swap and potential reversal) is done.
if (!foundMatches) {
animationInProgress = false;
- } else {
- // Set timeout to reset animation status after cascading effects
- LK.setTimeout(function () {
- animationInProgress = false;
- }, 1500);
}
- // Reset selected cell
+ // If foundMatches is true, checkForAndDestroyMatches has initiated a chain of events
+ // (destruction, refill, further checks). The final checkForAndDestroyMatches() in that
+ // chain (which finds no more matches) will set animationInProgress = false.
+ // Reset selected cell, allowing a new selection attempt.
+ // If animationInProgress is still true (due to ongoing cascades),
+ // a new swap attempt will be correctly blocked by the `!animationInProgress` check
+ // at the beginning of the swap logic.
selectedCell = null;
}
});
} else {
@@ -364,9 +365,16 @@
}
function checkForAndDestroyMatches(swappedCellA, swappedCellB) {
var allMatchGroupsOnBoard = getMatches(); // Get all potential matches on the board
if (allMatchGroupsOnBoard.length === 0) {
- return false; // No matches found anywhere, nothing to do
+ // If this check is part of a cascade (i.e., not an initial swap check initiated by user)
+ // and no matches are found, it means the cascade sequence has ended.
+ // Thus, animations are considered complete.
+ if (!swappedCellA && !swappedCellB) {
+ // This condition checks if it's a cascade call
+ animationInProgress = false;
+ }
+ return false; // No matches found anywhere, nothing to do
}
var relevantMatchGroups = [];
// If swapped cells are provided, only check matches involving them
if (swappedCellA && swappedCellB) {
la figura de una casa color blanca simple para una interfaz. In-Game asset. 2d. High contrast. No shadows
haz el fondo color morado
circular check logo. In-Game asset. 2d. High contrast. No shadows
Cuadrado con los bordes redondeado negro. In-Game asset. 2d. High contrast. No shadows
hazlo un gris claro
Que sea blanco
Que sea blanco