onethreefivesevennine Posted November 28 Share Posted November 28 Hello everyone, I'm new to the world of PixiJS and currently experimenting by creating a simple slot machine. I have divided the functionality into different modules. I have a question: How can I determine if a spinning session results in a win or a loss? I have 4 horizontal rows and 5 vertical columns. A winning session is defined when 3, 4, or 5 identical symbols appear consecutively in a row, from left to right. I would like to log a message to the console indicating whether the spin was a win or a loss. Any guidance on how to implement this logic effectively would be greatly appreciated. Thank you! Here is my code: import { Ticker, Texture, Graphics } from "pixi.js"; import { getWeightedRandomFruit } from "./slotLogic.js"; const fruitNames = [ "apple.png", "greenGrapes.png", "olive.png", "orange.png", "purpleGrapes.png", "bar.png", "seven.png", "banana.png", ]; export let isSpinning = false; let activeTickers = []; let lastSpinTime = 0; const spinCooldown = 1700; export function spinReel(reelContainer, onSpinEnd) { const currentTime = Date.now(); if (isSpinning || currentTime - lastSpinTime < spinCooldown) { return; } isSpinning = true; lastSpinTime = currentTime; const fruitContainer = reelContainer.getChildByName("fruitContainer"); const spinDuration = 500; const rows = 4; const columns = fruitContainer.children.length / rows; const fruitHeight = fruitContainer.children[0].height; const stopDelay = 300; let finishedColumns = 0; const tickers = []; const mask = new Graphics(); mask.rect( fruitContainer.x, fruitContainer.y + 20, reelContainer.width, rows * fruitHeight + 45 ); mask.fill({ color: 0x000000, alpha: 0 }); fruitContainer.mask = mask; reelContainer.addChild(mask); const kickInDuration = 300; const startKickIn = Date.now(); const kickInTicker = new Ticker(); activeTickers.push(kickInTicker); kickInTicker.add(() => { const elapsedTime = Date.now() - startKickIn; const progress = Math.min(elapsedTime / kickInDuration, 1); fruitContainer.children.forEach((fruit) => { fruit.y -= 4 * (1 - smoothEaseOut(progress)); }); if (progress >= 1) { kickInTicker.stop(); kickInTicker.destroy(); activeTickers = activeTickers.filter((t) => t !== kickInTicker); startSpinning(); } }); kickInTicker.start(); function startSpinning() { for (let col = 0; col < columns; col++) { const ticker = new Ticker(); tickers.push(ticker); activeTickers.push(ticker); ticker.add(() => { const fruits = []; for (let row = 0; row < rows; row++) { const fruitIndex = col + row * columns; fruits.push(fruitContainer.children[fruitIndex]); } fruits.forEach((fruit) => { if (window.innerWidth < 768) { fruit.y += 100; } else { fruit.y += 40; } if (fruit.y > rows * fruitHeight) { fruit.y = -70; const randomFruitName = getWeightedRandomFruit(); fruit.texture = Texture.from(randomFruitName); } }); }); ticker.start(); } const stopColumn = (col) => { const ticker = tickers[col]; try { const startTime = Date.now(); ticker.add(() => { const elapsedTime = Date.now() - startTime; const progress = Math.min(elapsedTime / spinDuration, 1); const fruits = []; for (let row = 0; row < rows; row++) { const fruitIndex = col + row * columns; fruits.push(fruitContainer.children[fruitIndex]); } const speed = 20 * (1 - smoothEaseOut(progress)); fruits.forEach((fruit) => { fruit.y += speed; if (fruit.y > rows * fruitHeight) { fruit.y = -70; const randomFruitName = fruitNames[Math.floor(Math.random() * fruitNames.length)]; fruit.texture = Texture.from(randomFruitName); } }); if (progress >= 1) { ticker.stop(); ticker.destroy(); activeTickers = activeTickers.filter((t) => t !== ticker); finishAnimation(fruits, () => { finishedColumns++; if ( finishedColumns === columns && typeof onSpinEnd === "function" ) { isSpinning = false; setTimeout(() => {}, spinCooldown); onSpinEnd(); } }); } }); } catch (error) {} // Possible problem }; for (let col = 0; col < columns; col++) { setTimeout(() => stopColumn(col), col * stopDelay); } } } function finishAnimation(fruits, callback) { const bounceDuration = 300; const startBounce = Date.now(); const bounceTicker = new Ticker(); activeTickers.push(bounceTicker); bounceTicker.add(() => { const elapsedTime = Date.now() - startBounce; const progress = Math.min(elapsedTime / bounceDuration, 1); fruits.forEach((fruit) => { const bounce = Math.sin(progress * Math.PI) * 50; fruit.y = fruit.originalY - bounce; }); if (progress >= 1) { bounceTicker.stop(); bounceTicker.destroy(); activeTickers = activeTickers.filter((t) => t !== bounceTicker); callback(); } }); bounceTicker.start(); } export function stopSpin(reelContainer) { setTimeout(() => { if (!isSpinning) return; isSpinning = false; activeTickers.forEach((ticker) => { ticker.stop(); ticker.destroy(); }); activeTickers = []; const fruitContainer = reelContainer.getChildByName("fruitContainer"); const rows = 4; const columns = fruitContainer.children.length / rows; const bounceDuration = 400; const startTime = Date.now(); const bounceTicker = new Ticker(); activeTickers.push(bounceTicker); bounceTicker.add(() => { const elapsedTime = Date.now() - startTime; const progress = Math.min(elapsedTime / bounceDuration, 1); fruitContainer.children.forEach((fruit, index) => { const col = index % columns; const row = Math.floor(index / columns); const randomY = row * fruit.height; if (!fruit.originalY) { fruit.originalY = fruit.y; } if (!fruit.finalY) { fruit.finalY = randomY + Math.random() * 10 + 35; } const bounce = Math.sin(progress * Math.PI) * 20; fruit.y = fruit.finalY - bounce * smoothEaseOut(1 - progress); if (progress === 0) { const randomFruitName = getWeightedRandomFruit(); fruit.texture = Texture.from(randomFruitName); } }); if (progress >= 1) { bounceTicker.stop(); bounceTicker.destroy(); activeTickers = activeTickers.filter((t) => t !== bounceTicker); fruitContainer.children.forEach((fruit) => { fruit.y = fruit.finalY; delete fruit.finalY; }); } }); bounceTicker.start(); }, 500); } function smoothEaseOut(t) { return 1 - Math.pow(1 - t, 3); } getWeightedRandomFruit(); Quote Link to comment Share on other sites More sharing options...
alex181 Posted November 29 Share Posted November 29 To determine if your spinning session results in a win or loss, you can add a function to check for consecutive identical symbols in each row after the reels stop spinning. Since you’ve defined a win as having 3, 4, or 5 identical symbols in a row (left to right), the logic should traverse each row and compare symbols. Here’s a simple breakdown of what you can do: Steps to Implement the Check: Organize the Symbols After the spin ends, get all the visible symbols from your grid and arrange them into a 2D array representing rows and columns. Row Check Logic Loop through each row and count consecutive identical symbols. If you find 3 or more consecutive matches, it’s a win. Log the Result If you detect a winning row, log a "Win" message to the console. If no winning rows are found, log a "Loss" message. Here’s an example function to add to your code: function checkWin(fruitContainer, rows, columns) { const grid = []; const children = fruitContainer.children; // Organize symbols into a 2D grid for (let row = 0; row < rows; row++) { const currentRow = []; for (let col = 0; col < columns; col++) { const fruitIndex = row * columns + col; currentRow.push(children[fruitIndex].texture.textureCacheIds[0]); // Get texture name } grid.push(currentRow); } // Check each row for consecutive matches for (let row of grid) { let consecutiveCount = 1; for (let col = 1; col < row.length; col++) { if (row[col] === row[col - 1]) { consecutiveCount++; if (consecutiveCount >= 3) { console.log("Win! Matching symbols:", row[col]); return true; // Found a win } } else { consecutiveCount = 1; } } } console.log("Loss. No winning rows."); return false; // No win found } How to Use It: Call checkWin(fruitContainer, rows, columns) at the end of your spin (e.g., in the onSpinEnd function). Pass the fruitContainer, the number of rows (4 in your case), and the number of columns (5 in your case). Example Usage: In your onSpinEnd function: onSpinEnd: () => { const isWin = checkWin(fruitContainer, 4, 5); if (isWin) { console.log("Congratulations! It's a win."); } else { console.log("Better luck next time!"); } }; This logic should fit nicely into your existing code and help you determine the outcome of each spin. Let me know if you run into any issues! Quote Link to comment Share on other sites More sharing options...
Milton Posted November 29 Share Posted November 29 (edited) 19 hours ago, onethreefivesevennine said: I have a question: How can I determine if a spinning session results in a win or a loss? That's not how online slot machines work. They 'spin' at the backend (server), send the result to the client, and that software can do whatever it wants, as long as it represents the outcome. Otherwise, imagine you hit the jackpot, and for some reason you lost your connection. Or the software gets hacked, and can send any win code it likes. Edited November 29 by Milton Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.