User prompt
Arregla el bug que el tiempo empieza a subir cuando se tiran los dados y no como un proceso secundario
User prompt
Haz que el tiempo suba desde que se ejecuta el juego y no desde que se toca la pantalla ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Agrega un texto arriba del todo mostrando el tiempo jugado, que se actualice cada segundo(guarda el valor) ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Agrega un texto arriba del todo como de cronómetro: 000:00:00. Que se actualice cada segundo y guarda el valor ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Utiliza la fórmula: "P(\text{exactamente } k) = \frac{1}{6^8} \cdot \sum_{\substack{n_1 + \cdots + n_6 = 8 \\ \max(n_i) = k}} \binom{8}{n_1, ..., n_6}" para la posibilidad de coincidir los dados
User prompt
Agrega más partículas ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega partículas, cuando finaliza el tiro, al grupo más grande ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega partículas, cuando finaliza el tiro, al grupo más grande ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cambia los textos a inglés
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'probabilityNumberText.style.fill = redColor;' Line Number: 256
User prompt
Arregla el error que hace que todo el texto tenga el mismo color
User prompt
Cambia los colores de la posibilidad así: posibilidad(negro): 1 (amarillo) en (negro) N (rojo pastel, mientras más difícil más rojo será)
User prompt
Agrega una fuente más Soft y dale colores a los textos
User prompt
Agranda el texto y replaza la manera de mostrar como posibilidad:
User prompt
Please fix the bug: 'Uncaught RangeError: Maximum call stack size exceeded' in or related to this line: 'var matchingCount = countMatchingDice();' Line Number: 214
User prompt
Agrega un texto abajo de la pantalla que diga la posibilidad de que haya tocado dicho cantidad de dados iguales en los 8 dados
User prompt
Agrega un texto abajo que pone la posibilidad que de que haya tocado dicho grupo de dados (en: 1(color amarillo) en xxxx (color rojo)
User prompt
Haz que los valores mejor, anterior y actual se guarden y carguen ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Haz que anterior copie el valor de actual cuando se toca para cambiar los dados, y haz que actual vuelva a 0/8 hasta que finalice el cambio de dados y tome el nuevo valor
User prompt
Haz que siempre que cambie actual, ese valor pase a ser valor del anterior
User prompt
Modifica el texto de 0/8 de la siguiente forma: Best: 0/8
User prompt
Agrega al texto de 0/8 el mejor y el actual, los dos en la misma fila tipo actual: 0/8 - mejor: 0/8
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Dice = Container.expand(function () { var self = Container.call(this); // Add numeric variable valor self.valor = 1; // Add rolling animation variables self.isRolling = false; self.rollCount = 0; self.rollTarget = 0; self.rollTimer = 0; var diceGraphics = self.attachAsset('Dice' + self.valor, { anchorX: 0.5, anchorY: 0.5 }); // Method to update dice visual based on valor self.updateVisual = function () { // Create new graphics based on valor first var newGraphics = self.attachAsset('Dice' + self.valor, { anchorX: 0.5, anchorY: 0.5 }); // Remove old graphics after new one is created self.removeChild(diceGraphics); // Update reference to new graphics diceGraphics = newGraphics; // Add bounce effect when value changes during rolling if (self.isRolling) { self.playDiceSound(); diceGraphics.scaleX = 1; diceGraphics.scaleY = 1; tween(diceGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, easing: tween.bounceOut, onFinish: function onFinish() { tween(diceGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.bounceOut }); } }); } }; // Method to play dice sound self.playDiceSound = function () { LK.getSound('Roll').play(); }; // Method to start rolling animation self.startRoll = function () { self.isRolling = true; self.rollCount = 0; self.rollTarget = Math.floor(Math.random() * 7) + 6; // 6 to 12 rolls self.rollTimer = 0; }; // Update method for rolling animation self.update = function () { if (self.isRolling) { var rollSpeed = Math.floor(self.rollCount * 1.5) + 3; // Start fast, get slower if (self.rollTimer >= rollSpeed) { self.valor = Math.floor(Math.random() * 6) + 1; self.updateVisual(); self.rollCount++; self.rollTimer = 0; if (self.rollCount >= self.rollTarget) { self.isRolling = false; } } else { self.rollTimer++; } } }; return self; }); /**** * Initialize Game ****/ // Create array to hold all dice var game = new LK.Game({ backgroundColor: 0xFFFFFF }); /**** * Game Code ****/ // Create array to hold all dice var diceArray = []; // Add lanzamiento boolean variable var lanzamiento = false; // Add timer to enforce minimum 1 second wait between rolls var lastRollFinishTime = 0; var minimumWaitTime = 1000; // 1 second in milliseconds // Add best score tracking - load from storage with defaults var bestScore = storage.bestScore || 0; var previousScore = storage.previousScore || 0; var actualScore = storage.actualScore || 0; // Calculate center positions for two columns var centerX = 2048 / 2; var centerY = 2732 / 2; var columnSpacing = 330; // Space between columns var rowSpacing = 300; // Space between rows // Create matching dice counter text var counterText = new Text2('Best: ' + bestScore + '/8\nPrevious: ' + previousScore + '/8 - Current: ' + actualScore + '/8', { size: 80, fill: 0x2E7D32, align: 'center', font: "'Helvetica Neue', 'Arial', sans-serif" }); counterText.anchor.set(0.5, 0); counterText.y = 100; // Move down to make space for status text LK.gui.top.addChild(counterText); // Create status text above dice var statusText = new Text2('Tap to roll', { size: 60, fill: 0x1976D2, font: "'Helvetica Neue', 'Arial', sans-serif" }); statusText.anchor.set(0.5, 0.5); statusText.x = centerX; statusText.y = centerY - 700; // Position above dice grid game.addChild(statusText); // Create countdown text var countdownText = new Text2('', { size: 50, fill: 0xF57C00, font: "'Helvetica Neue', 'Arial', sans-serif" }); countdownText.anchor.set(0.5, 0.5); countdownText.x = centerX; countdownText.y = centerY - 640; // Position below status text game.addChild(countdownText); // Create probability text at bottom of screen var probabilityText = new Text2('', { size: 80, fill: 0x7B1FA2, align: 'center', font: "'Helvetica Neue', 'Arial', sans-serif" }); probabilityText.anchor.set(0.5, 1); probabilityText.x = centerX; probabilityText.y = 2732 - 50; // Position at bottom with margin game.addChild(probabilityText); // Function to count matching dice function countMatchingDice() { var counts = {}; // Count occurrences of each dice value for (var i = 0; i < diceArray.length; i++) { var value = diceArray[i].valor; counts[value] = (counts[value] || 0) + 1; } // Find the highest count var maxCount = 0; for (var value in counts) { if (counts[value] > maxCount) { maxCount = counts[value]; } } return maxCount; } // Function to calculate probability of getting exactly N matching dice in 8 rolls function calculateProbability(n) { if (n < 1 || n > 8) return 0; if (n === 1) { // Probability of getting exactly 1 of each value (all different) is very low for 8 dice // This is a complex calculation, we'll use approximation return 0.015; // ~1.5% } // For n matching dice, we use binomial probability // P(X = n) = C(8,n) * (1/6)^n * (5/6)^(8-n) * 6 (for any of the 6 faces) // Simplified approximation for display purposes var probabilities = { 2: 0.372, // ~37.2% 3: 0.139, // ~13.9% 4: 0.0347, // ~3.47% 5: 0.00695, // ~0.695% 6: 0.00116, // ~0.116% 7: 0.000139, // ~0.0139% 8: 0.0000214 // ~0.00214% }; return probabilities[n] || 0; } // Function to update probability display function updateProbabilityDisplay() { var matchingCount = countMatchingDice(); var probability = calculateProbability(matchingCount); var oneInX = Math.round(1 / probability); probabilityText.setText('Probability:\n1 in ' + oneInX); } // Function to add particle effects to largest matching group function addParticleEffectsToLargestGroup() { var counts = {}; // Count occurrences of each dice value for (var i = 0; i < diceArray.length; i++) { var value = diceArray[i].valor; counts[value] = (counts[value] || 0) + 1; } // Find the highest count and value var maxCount = 0; var maxValue = 0; for (var value in counts) { if (counts[value] > maxCount) { maxCount = counts[value]; maxValue = parseInt(value); } } // Add particle effects to dice in largest group for (var i = 0; i < diceArray.length; i++) { var dice = diceArray[i]; if (dice.valor == maxValue && counts[maxValue] == maxCount && maxCount > 1) { // Create sparkle effect around each dice in largest group createSparkleEffect(dice); } } } // Function to create sparkle particle effect around a dice function createSparkleEffect(dice) { var numParticles = 8; var radius = 80; for (var i = 0; i < numParticles; i++) { // Create particle using existing dice asset var particle = LK.getAsset('Dice' + dice.valor, { anchorX: 0.5, anchorY: 0.5 }); // Calculate position around dice in circle var angle = i / numParticles * Math.PI * 2; var startX = dice.x + Math.cos(angle) * 20; var startY = dice.y + Math.sin(angle) * 20; var endX = dice.x + Math.cos(angle) * radius; var endY = dice.y + Math.sin(angle) * radius; // Position particle particle.x = startX; particle.y = startY; particle.scaleX = 0.3; particle.scaleY = 0.3; particle.alpha = 0.8; particle.tint = 0xFFD700; // Golden color // Add particle to game game.addChild(particle); // Animate particle outward with rotation and fade tween(particle, { x: endX, y: endY, scaleX: 0.1, scaleY: 0.1, alpha: 0, rotation: Math.PI * 2 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(particle); } }); } } // Function to apply tint colors to dice based on matching groups function applyDiceTints() { var counts = {}; // Count occurrences of each dice value for (var i = 0; i < diceArray.length; i++) { var value = diceArray[i].valor; counts[value] = (counts[value] || 0) + 1; } // Find the highest count and value var maxCount = 0; var maxValue = 0; for (var value in counts) { if (counts[value] > maxCount) { maxCount = counts[value]; maxValue = parseInt(value); } } // Generate random colors for smaller groups var randomColors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFECE00, 0xF38BA8]; var colorIndex = 0; var usedColors = {}; // Apply tints to all dice for (var i = 0; i < diceArray.length; i++) { var dice = diceArray[i]; var value = dice.valor; if (value == maxValue && counts[value] == maxCount) { // Largest group gets soft yellow tint dice.children[0].tint = 0xFFFF99; // Soft yellow } else if (counts[value] > 1) { // Smaller matching groups get random colors if (!usedColors[value]) { usedColors[value] = randomColors[colorIndex % randomColors.length]; colorIndex++; } dice.children[0].tint = usedColors[value]; } else { // Single dice get no tint (white) dice.children[0].tint = 0xFFFFFF; } } } // Create 8 dice in two columns (4 rows each) for (var col = 0; col < 2; col++) { for (var row = 0; row < 4; row++) { var dice = new Dice(); // Assign random valor from 1 to 6 dice.valor = Math.floor(Math.random() * 6) + 1; // Update visual based on valor dice.updateVisual(); // Position dice in grid dice.x = centerX + (col - 0.5) * columnSpacing; dice.y = centerY + (row - 1.5) * rowSpacing; // Add to game and array game.addChild(dice); diceArray.push(dice); } // Game update method to handle dice rolling game.update = function () { // Update status and countdown text based on current state var currentTime = Date.now(); var timeSinceLastRoll = currentTime - lastRollFinishTime; var timeRemaining = minimumWaitTime - timeSinceLastRoll; if (lanzamiento) { // Currently rolling statusText.setText('Rolling dice...'); countdownText.setText(''); } else if (timeRemaining > 0) { // Waiting period - show countdown statusText.setText('Wait to roll'); var secondsRemaining = timeRemaining / 1000; countdownText.setText(secondsRemaining.toFixed(2) + 's'); } else { // Ready to roll statusText.setText('Tap to roll'); countdownText.setText(''); } // Check if all dice have finished rolling if (lanzamiento) { var allFinished = true; for (var i = 0; i < diceArray.length; i++) { if (diceArray[i].isRolling) { allFinished = false; break; } } // Reset lanzamiento when all dice are done if (allFinished) { lanzamiento = false; // Record the time when rolling finished lastRollFinishTime = Date.now(); // Update counter text with matching dice count var matchingCount = countMatchingDice(); actualScore = matchingCount; // Update best score if current is better if (matchingCount > bestScore) { bestScore = matchingCount; } // Save scores to storage storage.bestScore = bestScore; storage.previousScore = previousScore; storage.actualScore = actualScore; counterText.setText('Best: ' + bestScore + '/8\nPrevious: ' + previousScore + '/8 - Current: ' + matchingCount + '/8'); // Apply tint colors to dice based on matching groups applyDiceTints(); // Add particle effects to largest group addParticleEffectsToLargestGroup(); // Update probability display updateProbabilityDisplay(); } } }; // Add screen tap handler for lanzamiento event game.down = function (x, y, obj) { // Check if enough time has passed since last roll finished var currentTime = Date.now(); var timeSinceLastRoll = currentTime - lastRollFinishTime; // Only allow new roll if not currently rolling AND minimum wait time has passed if (!lanzamiento && timeSinceLastRoll >= minimumWaitTime) { // Copy current score to previous score when starting new roll var currentMatchingCount = countMatchingDice(); previousScore = currentMatchingCount; // Save previous score to storage storage.previousScore = previousScore; // Update counter text to show actual as 0/8 during rolling counterText.setText('Best: ' + bestScore + '/8\nPrevious: ' + previousScore + '/8 - Current: 0/8'); lanzamiento = true; // Start rolling animation for all dice for (var i = 0; i < diceArray.length; i++) { diceArray[i].startRoll(); } } }; }
===================================================================
--- original.js
+++ change.js
@@ -204,8 +204,76 @@
var probability = calculateProbability(matchingCount);
var oneInX = Math.round(1 / probability);
probabilityText.setText('Probability:\n1 in ' + oneInX);
}
+// Function to add particle effects to largest matching group
+function addParticleEffectsToLargestGroup() {
+ var counts = {};
+ // Count occurrences of each dice value
+ for (var i = 0; i < diceArray.length; i++) {
+ var value = diceArray[i].valor;
+ counts[value] = (counts[value] || 0) + 1;
+ }
+ // Find the highest count and value
+ var maxCount = 0;
+ var maxValue = 0;
+ for (var value in counts) {
+ if (counts[value] > maxCount) {
+ maxCount = counts[value];
+ maxValue = parseInt(value);
+ }
+ }
+ // Add particle effects to dice in largest group
+ for (var i = 0; i < diceArray.length; i++) {
+ var dice = diceArray[i];
+ if (dice.valor == maxValue && counts[maxValue] == maxCount && maxCount > 1) {
+ // Create sparkle effect around each dice in largest group
+ createSparkleEffect(dice);
+ }
+ }
+}
+// Function to create sparkle particle effect around a dice
+function createSparkleEffect(dice) {
+ var numParticles = 8;
+ var radius = 80;
+ for (var i = 0; i < numParticles; i++) {
+ // Create particle using existing dice asset
+ var particle = LK.getAsset('Dice' + dice.valor, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Calculate position around dice in circle
+ var angle = i / numParticles * Math.PI * 2;
+ var startX = dice.x + Math.cos(angle) * 20;
+ var startY = dice.y + Math.sin(angle) * 20;
+ var endX = dice.x + Math.cos(angle) * radius;
+ var endY = dice.y + Math.sin(angle) * radius;
+ // Position particle
+ particle.x = startX;
+ particle.y = startY;
+ particle.scaleX = 0.3;
+ particle.scaleY = 0.3;
+ particle.alpha = 0.8;
+ particle.tint = 0xFFD700; // Golden color
+ // Add particle to game
+ game.addChild(particle);
+ // Animate particle outward with rotation and fade
+ tween(particle, {
+ x: endX,
+ y: endY,
+ scaleX: 0.1,
+ scaleY: 0.1,
+ alpha: 0,
+ rotation: Math.PI * 2
+ }, {
+ duration: 800,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ game.removeChild(particle);
+ }
+ });
+ }
+}
// Function to apply tint colors to dice based on matching groups
function applyDiceTints() {
var counts = {};
// Count occurrences of each dice value
@@ -308,8 +376,10 @@
storage.actualScore = actualScore;
counterText.setText('Best: ' + bestScore + '/8\nPrevious: ' + previousScore + '/8 - Current: ' + matchingCount + '/8');
// Apply tint colors to dice based on matching groups
applyDiceTints();
+ // Add particle effects to largest group
+ addParticleEffectsToLargestGroup();
// Update probability display
updateProbabilityDisplay();
}
}