$P@D$3RV£R commited on
Commit ·
f7e450a
1
Parent(s): 33012c5
Fix tile flickering by stabilizing rendering logic and removing inconsistent visibility toggles
Browse files- game.js +41 -32
- styles.css +5 -0
game.js
CHANGED
|
@@ -219,10 +219,9 @@ class Match3Game {
|
|
| 219 |
|
| 220 |
this.lastBoardState = currentState;
|
| 221 |
|
| 222 |
-
//
|
| 223 |
-
|
| 224 |
-
for (let
|
| 225 |
-
for (let col = 0; col < this.boardCols; col++) {
|
| 226 |
let cell = existingCells[row * this.boardCols + col];
|
| 227 |
|
| 228 |
if (!cell || needsFullRender) {
|
|
@@ -261,18 +260,25 @@ class Match3Game {
|
|
| 261 |
const isMatchEnlarge = cell.classList.contains('match-enlarge');
|
| 262 |
const hasActiveAnimation = isMatched || isMatchEnlarge;
|
| 263 |
|
| 264 |
-
// Skip if cell is marked as empty (-1)
|
| 265 |
-
if (gemType === -1
|
| 266 |
-
//
|
| 267 |
-
cell.
|
| 268 |
-
|
| 269 |
-
|
|
|
|
| 270 |
continue;
|
| 271 |
}
|
| 272 |
|
| 273 |
-
//
|
| 274 |
-
if (
|
| 275 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
cell.style.display = '';
|
| 277 |
cell.style.opacity = '';
|
| 278 |
cell.style.visibility = '';
|
|
@@ -286,10 +292,22 @@ class Match3Game {
|
|
| 286 |
cell.style.transition = '';
|
| 287 |
}
|
| 288 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
}
|
| 290 |
}
|
| 291 |
}
|
| 292 |
-
});
|
| 293 |
|
| 294 |
// Add board-level mousemove for better drag tracking
|
| 295 |
boardElement.addEventListener('mousemove', (e) => {
|
|
@@ -919,17 +937,8 @@ class Match3Game {
|
|
| 919 |
matches.forEach(match => {
|
| 920 |
this.board[match.row][match.col] = -1; // Mark as empty
|
| 921 |
|
| 922 |
-
//
|
| 923 |
-
|
| 924 |
-
`[data-row="${match.row}"][data-col="${match.col}"]`
|
| 925 |
-
);
|
| 926 |
-
if (cell) {
|
| 927 |
-
cell.classList.remove('matched');
|
| 928 |
-
// Hide the cell completely
|
| 929 |
-
cell.style.display = 'none';
|
| 930 |
-
cell.style.opacity = '0';
|
| 931 |
-
cell.style.visibility = 'hidden';
|
| 932 |
-
}
|
| 933 |
});
|
| 934 |
|
| 935 |
// Make pieces fall
|
|
@@ -938,8 +947,11 @@ class Match3Game {
|
|
| 938 |
// Fill empty spaces
|
| 939 |
this.fillEmptySpaces();
|
| 940 |
|
| 941 |
-
// Re-render board to show new tiles
|
| 942 |
-
|
|
|
|
|
|
|
|
|
|
| 943 |
|
| 944 |
// Very short delay before checking for new matches
|
| 945 |
await this.sleep(50);
|
|
@@ -947,13 +959,10 @@ class Match3Game {
|
|
| 947 |
|
| 948 |
this.isProcessing = false;
|
| 949 |
|
| 950 |
-
// Render any pending updates after processing completes
|
| 951 |
if (this.renderPending) {
|
| 952 |
this.renderPending = false;
|
| 953 |
-
|
| 954 |
-
requestAnimationFrame(() => {
|
| 955 |
-
this.renderBoard(true);
|
| 956 |
-
});
|
| 957 |
}
|
| 958 |
|
| 959 |
this.checkGameOver();
|
|
|
|
| 219 |
|
| 220 |
this.lastBoardState = currentState;
|
| 221 |
|
| 222 |
+
// Update cells directly without requestAnimationFrame to prevent flickering
|
| 223 |
+
for (let row = 0; row < this.boardRows; row++) {
|
| 224 |
+
for (let col = 0; col < this.boardCols; col++) {
|
|
|
|
| 225 |
let cell = existingCells[row * this.boardCols + col];
|
| 226 |
|
| 227 |
if (!cell || needsFullRender) {
|
|
|
|
| 260 |
const isMatchEnlarge = cell.classList.contains('match-enlarge');
|
| 261 |
const hasActiveAnimation = isMatched || isMatchEnlarge;
|
| 262 |
|
| 263 |
+
// Skip if cell is marked as empty (-1)
|
| 264 |
+
if (gemType === -1) {
|
| 265 |
+
// Hide empty cells but don't manipulate inline styles repeatedly
|
| 266 |
+
if (!cell.classList.contains('empty-cell')) {
|
| 267 |
+
cell.classList.add('empty-cell');
|
| 268 |
+
cell.style.display = 'none';
|
| 269 |
+
}
|
| 270 |
continue;
|
| 271 |
}
|
| 272 |
|
| 273 |
+
// Remove empty-cell class if present
|
| 274 |
+
if (cell.classList.contains('empty-cell')) {
|
| 275 |
+
cell.classList.remove('empty-cell');
|
| 276 |
+
cell.style.display = '';
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
// Only update if not animating
|
| 280 |
+
if (!hasActiveAnimation) {
|
| 281 |
+
// Always ensure cell is visible for non-empty cells
|
| 282 |
cell.style.display = '';
|
| 283 |
cell.style.opacity = '';
|
| 284 |
cell.style.visibility = '';
|
|
|
|
| 292 |
cell.style.transition = '';
|
| 293 |
}
|
| 294 |
}
|
| 295 |
+
} else {
|
| 296 |
+
// Even if no update needed, ensure visibility is correct
|
| 297 |
+
if (gemType === -1) {
|
| 298 |
+
if (!cell.classList.contains('empty-cell')) {
|
| 299 |
+
cell.classList.add('empty-cell');
|
| 300 |
+
cell.style.display = 'none';
|
| 301 |
+
}
|
| 302 |
+
} else {
|
| 303 |
+
if (cell.classList.contains('empty-cell')) {
|
| 304 |
+
cell.classList.remove('empty-cell');
|
| 305 |
+
cell.style.display = '';
|
| 306 |
+
}
|
| 307 |
+
}
|
| 308 |
}
|
| 309 |
}
|
| 310 |
}
|
|
|
|
| 311 |
|
| 312 |
// Add board-level mousemove for better drag tracking
|
| 313 |
boardElement.addEventListener('mousemove', (e) => {
|
|
|
|
| 937 |
matches.forEach(match => {
|
| 938 |
this.board[match.row][match.col] = -1; // Mark as empty
|
| 939 |
|
| 940 |
+
// Mark cell as empty - renderBoard will handle hiding it
|
| 941 |
+
// Don't manipulate DOM directly here to prevent flickering
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 942 |
});
|
| 943 |
|
| 944 |
// Make pieces fall
|
|
|
|
| 947 |
// Fill empty spaces
|
| 948 |
this.fillEmptySpaces();
|
| 949 |
|
| 950 |
+
// Re-render board to show new tiles - do it synchronously to prevent flickering
|
| 951 |
+
// Only render if not already processing (double-check)
|
| 952 |
+
if (!this.isProcessing) {
|
| 953 |
+
this.renderBoard(true);
|
| 954 |
+
}
|
| 955 |
|
| 956 |
// Very short delay before checking for new matches
|
| 957 |
await this.sleep(50);
|
|
|
|
| 959 |
|
| 960 |
this.isProcessing = false;
|
| 961 |
|
| 962 |
+
// Render any pending updates after processing completes - do it synchronously
|
| 963 |
if (this.renderPending) {
|
| 964 |
this.renderPending = false;
|
| 965 |
+
this.renderBoard(true);
|
|
|
|
|
|
|
|
|
|
| 966 |
}
|
| 967 |
|
| 968 |
this.checkGameOver();
|
styles.css
CHANGED
|
@@ -477,6 +477,11 @@ body.dark-theme .level-complete-content {
|
|
| 477 |
display: flex;
|
| 478 |
justify-content: center;
|
| 479 |
align-items: center;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 480 |
font-size: 3.24em;
|
| 481 |
padding: 0;
|
| 482 |
position: relative;
|
|
|
|
| 477 |
display: flex;
|
| 478 |
justify-content: center;
|
| 479 |
align-items: center;
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
.cell.empty-cell {
|
| 483 |
+
display: none !important;
|
| 484 |
+
}
|
| 485 |
font-size: 3.24em;
|
| 486 |
padding: 0;
|
| 487 |
position: relative;
|