У меня проблема с точностью моей игры в рулеткеJavascript

Форум по Javascript
Ответить
Anonymous
 У меня проблема с точностью моей игры в рулетке

Сообщение Anonymous »

Вы можете видеть, что точное число, при котором приземлилась стрелка, не является правильным, показанным в сообщении, это то, что рядом с ним. Я хочу исправить выравнивание и разделение и метод, который получает число. Это происходит с некоторыми числами, а некоторые показаны правильно. Я считаю, что это метод GetPointernumber (). < /P>





🎰 Roulette Game | Free Casino









🏠 Home



Roulette Game 🎰




Balance:
$1000
















0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36



-
Bet: $100
+


SPIN















< /code>
html, body {
min-height: 100%;
height: auto;
overflow-y: auto;
}

body {
display: flex;
justify-content: center;
align-items: flex-start;
padding: 2rem 0;
}

/* Roulette Game Styles */
.roulette-container {
z-index: 2;
width: 90%;
max-width: 800px;
margin: 2rem auto;
display: flex;
flex-direction: column;
align-items: center;
}

.balance-display {
background: rgba(0, 0, 0, 0.7);
padding: 0.8rem 1.5rem;
border-radius: 50px;
margin-bottom: 2rem;
font-size: 1.2rem;
display: flex;
align-items: center;
gap: 0.5rem;
border: 2px solid rgba(255, 215, 0, 0.3);
box-shadow: 0 0 15px rgba(255, 215, 0, 0.2);
}

.balance-label {
color: #aaa;
}

.balance-amount {
color: #ffd700;
font-weight: bold;
font-size: 1.3rem;
}

.roulette-game {
width: 100%;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(8px);
border-radius: 16px;
padding: 2rem;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7),
inset 0 0 30px rgba(255, 215, 0, 0.1);
border: 2px solid rgba(255, 215, 0, 0.3);
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
position: relative;
}

/* Roulette Wheel */
.roulette-wheel-container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin: 0.5rem 0;
}

.roulette-wheel {
width: 320px;
height: 320px;
border-radius: 50%;
background: conic-gradient(
from 90deg,
#ff0000 0deg 9.73deg, /* 34 - red */
#000000 9.73deg 19.46deg, /* 6 - black */
#ff0000 19.46deg 29.19deg, /* 27 - red */
#000000 29.19deg 38.92deg, /* 13 - black */
#ff0000 38.92deg 48.65deg, /* 36 - red */
#000000 48.65deg 58.38deg, /* 11 - black */
#ff0000 58.38deg 68.11deg, /* 30 - red */
#000000 68.11deg 77.84deg, /* 8 - black */
#ff0b0b 77.84deg 87.57deg, /* 23 - red */
#000000 87.57deg 97.3deg, /* 10 - black */
#ff0000 97.3deg 107.03deg, /* 5 - red */
#000000 107.03deg 116.76deg, /* 24 - black */
#ff0000 116.76deg 126.49deg, /* 16 - red */
#000000 126.49deg 136.22deg, /* 33 - black */
#ff0000 136.22deg 145.95deg, /* 1 - red */
#000000 145.95deg 155.68deg, /* 20 - black */
#ff0000 155.68deg 165.41deg, /* 14 - red */
#000000 165.41deg 175.14deg, /* 31 - black */
#ff0000 175.14deg 184.87deg, /* 9 - red */
#000000 184.87deg 194.6deg, /* 22 - black */
#ff0000 194.6deg 204.33deg, /* 18 - red */
#000000 204.33deg 214.06deg, /* 29 - black */
#ff0000 214.06deg 223.79deg, /* 7 - red */
#000000 223.79deg 233.52deg, /* 28 - black */
#ff0000 233.52deg 243.25deg, /* 12 - red */
#000000 243.25deg 252.98deg, /* 35 - black */
#ff0000 252.98deg 262.71deg, /* 3 - red */
#000000 262.71deg 272.44deg, /* 26 - black */
#07ac3e 272.44deg 282.17deg, /* 0 - green */
#dc2626 282.17deg 291.9deg, /* 32 - red */
#000000 291.9deg 301.63deg, /* 15 - black */
#dc2626 301.63deg 311.36deg, /* 19 - red */
#000000 311.36deg 321.09deg, /* 4 - black */
#dc2626 321.09deg 330.82deg, /* 21 - red */
#000000 330.82deg 340.55deg, /* 2 - black */
#dc2626 340.55deg 350.28deg, /* 25 - red */
#000000 350.28deg 360deg /* 17 - black */
);
position: relative;
box-shadow: 0 0 30px rgba(255, 215, 0, 0.3),
inset 0 0 50px rgba(0, 0, 0, 0.5);
border: 8px solid #ffd700;
transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99);
}

/* Wheel separators for clear divisions */
.wheel-separators {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}

.wheel-separator {
position: absolute;
width: 3px;
height: 50%;
background: linear-gradient(to bottom, #ffd700 0%, #ffd700 85%, transparent 100%);
left: 50%;
top: 0;
transform-origin: bottom center;
box-shadow: 0 0 5px rgba(255, 215, 0, 0.9);
z-index: 3;
}

/* Wheel numbers - smaller and better positioned */
.wheel-number {
position: absolute;
width: 24px;
height: 24px;
color: white;
font-weight: bold;
font-size: 11px;
display: flex;
align-items: center;
justify-content: center;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 1);
transform-origin: center;
border-radius: 50%;
background: rgba(0, 0, 0, 0.85);
border: 1px solid rgba(255, 255, 255, 0.7);
z-index: 5;
font-family: 'Arial', sans-serif;
box-shadow: 0 0 5px rgba(255, 215, 0, 0.3);
}

.wheel-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
background: linear-gradient(45deg, #ffd700, #daa520);
border-radius: 50%;
box-shadow: 0 0 15px rgba(255, 215, 0, 0.5),
inset 0 0 10px rgba(0, 0, 0, 0.3);
z-index: 10;
}

.wheel-pointer {
position: absolute;
top: -18px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 18px solid transparent;
border-right: 18px solid transparent;
border-top: 36px solid #ffd700;
z-index: 15;
filter: drop-shadow(0 0 15px rgba(255, 215, 0, 0.9));
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}

.game-controls {
width: 100%;
display: flex;
flex-direction: column;
gap: 1.5rem;
}

/* Home button */
.home-btn {
position: fixed;
top: 20px;
left: 20px;
background: rgba(255, 215, 0, 0.2);
color: #ffd700;
border: 2px solid rgba(255, 215, 0, 0.5);
padding: 10px 20px;
border-radius: 25px;
font-weight: bold;
text-decoration: none;
transition: all 0.3s ease;
z-index: 1000;
display: flex;
align-items: center;
gap: 8px;
backdrop-filter: blur(10px);
}

.home-btn:hover {
background: rgba(255, 215, 0, 0.3);
transform: scale(1.05);
box-shadow: 0 0 20px rgba(255, 215, 0, 0.4);
}

/* Number selection grid */
.number-selection {
display: flex;
justify-content: center;
}

.number-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 0.4rem;
max-width: 500px;
padding: 0.8rem;
background: rgba(0, 0, 0, 0.3);
border-radius: 10px;
border: 1px solid rgba(255, 215, 0, 0.2);
}

.number-btn {
width: 45px;
height: 45px;
border-radius: 8px;
border: 2px solid rgba(255, 255, 255, 0.3);
color: white;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
transition: all 0.2s;
position: relative;
overflow: hidden;
}

.number-btn.red {
background: linear-gradient(145deg, #dc2626, #b91c1c);
}

.number-btn.black {
background: linear-gradient(145deg, #1f2937, #111827);
}

.number-btn.green {
background: linear-gradient(145deg, #059669, #047857);
grid-column: span 6;
width: 100%;
}

.number-btn:hover {
transform: scale(1.05);
box-shadow: 0 0 15px rgba(255, 215, 0, 0.3);
}

.number-btn.selected {
border-color: #ffd700;
box-shadow: 0 0 20px rgba(255, 215, 0, 0.6);
transform: scale(1.1);
}

.number-btn.selected::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 215, 0, 0.2);
pointer-events: none;
}

/* Bet controls */
.bet-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
background: rgba(0, 0, 0, 0.5);
padding: 0.8rem 1rem;
border-radius: 50px;
border: 1px solid rgba(255, 215, 0, 0.3);
}

.bet-btn {
background: rgba(255, 215, 0, 0.2);
color: #ffd700;
border: none;
width: 36px;
height: 36px;
border-radius: 50%;
font-size: 1.2rem;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
}

.bet-btn:hover {
background: rgba(255, 215, 0, 0.4);
transform: scale(1.1);
}

.bet-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}

.bet-amount {
color: white;
font-weight: bold;
min-width: 120px;
text-align: center;
font-size: 1.1rem;
}

/* Spin button */
.spin-btn {
background: linear-gradient(to bottom, #ffd700, #daa520);
color: #222;
border: none;
padding: 1rem 3rem;
font-size: 1.2rem;
font-weight: bold;
border-radius: 50px;
cursor: pointer;
transition: all 0.2s;
box-shadow: 0 5px 15px rgba(218, 165, 32, 0.4),
inset 0 1px 1px rgba(255, 255, 255, 0.3);
text-transform: uppercase;
letter-spacing: 1px;
position: relative;
overflow: hidden;
margin-top: 0.5rem;
}

.spin-btn:hover:not(:disabled) {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(218, 165, 32, 0.6);
}

.spin-btn:active:not(:disabled) {
transform: translateY(1px);
box-shadow: 0 3px 10px rgba(218, 165, 32, 0.6);
}

.spin-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}

.spin-btn::after {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(
to bottom right,
rgba(255, 255, 255, 0) 45%,
rgba(255, 255, 255, 0.8) 50%,
rgba(255, 255, 255, 0) 55%
);
transform: rotate(30deg);
animation: shine 3s infinite;
}

@keyframes shine {
0% { transform: translateX(-100%) rotate(30deg); }
100% { transform: translateX(100%) rotate(30deg); }
}

/* Win message - improved visibility */
.win-message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.9);
margin-top: 0;
padding: 2rem 3rem;
background: rgba(0, 0, 0, 0.95);
border-radius: 15px;
font-size: 1.2rem;
font-weight: bold;
color: #ffd700;
text-align: center;
opacity: 0;
transition: all 0.3s ease;
max-width: 90%;
min-width: 400px;
border: 3px solid rgba(255, 215, 0, 0.6);
z-index: 1001;
box-shadow: 0 0 40px rgba(255, 215, 0, 0.4);
backdrop-filter: blur(10px);
}

.win-message.show {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}

.win-message.lose {
color: #ff6b6b;
border-color: rgba(255, 107, 107, 0.6);
box-shadow: 0 0 40px rgba(255, 107, 107, 0.4);
}

.result-section {
margin: 1rem 0;
padding: 1rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.2);
}

.result-title {
font-size: 2rem;
margin-bottom: 1rem;
}

.result-details {
font-size: 1.2rem;
line-height: 1.5;
margin: 0.5rem 0;
}

.payout-info {
font-size: 1rem;
color: #aaa;
margin-top: 1rem;
}

/* Responsive design */
@media (max-width: 768px) {
.roulette-game {
padding: 1rem;
}

.roulette-wheel {
width: 260px;
height: 260px;
}

.number-grid {
grid-template-columns: repeat(4, 1fr);
gap: 0.3rem;
max-width: 400px;
}

.number-btn {
width: 35px;
height: 35px;
font-size: 0.9rem;
}

.bet-amount {
min-width: 100px;
font-size: 1rem;
}

.spin-btn {
padding: 0.8rem 2rem;
font-size: 1rem;
}

.wheel-number {
width: 18px;
height: 18px;
font-size: 9px;
}

.win-message {
min-width: 300px;
padding: 1.5rem 2rem;
font-size: 1.1rem;
}
}

@media (max-width: 480px) {
.number-grid {
grid-template-columns: repeat(3, 1fr);
max-width: 300px;
}

.roulette-wheel {
width: 220px;
height: 220px;
}

.number-btn {
width: 30px;
height: 30px;
font-size: 0.8rem;
}

.wheel-number {
width: 16px;
height: 16px;
font-size: 8px;
}

.win-message {
min-width: 280px;
padding: 1rem 1.5rem;
font-size: 1rem;
}
}
< /code>
document.addEventListener('DOMContentLoaded', () => {
// Game state
let balance = parseInt(localStorage.getItem('casinoBalance'), 10) || 1000;
let currentBet = 100;
let selectedNumber = null;
let isSpinning = false;
let totalRotation = 0;

// EXACT European roulette wheel layout - reading clockwise from top (0 degrees)
// Based on your image, starting with 0 at the top
const wheelNumbers = [
0, // Green at top (0°)
32, // Red
15, // Black
19, // Red
4, // Black
21, // Red
2, // Black
25, // Red
17, // Black
34, // Red
6, // Black
27, // Red
13, // Black
36, // Red
11, // Black
30, // Red
8, // Black
23, // Red
10, // Black
5, // Red
24, // Black
16, // Red
33, // Black
1, // Red
20, // Black
14, // Red
31, // Black
9, // Red
22, // Black
18, // Red
29, // Black
7, // Red
28, // Black
12, // Red
35, // Black
3, // Red
26 // Black
];

const redNumbers = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36];

// DOM elements
const balanceElement = document.getElementById('balance');
const currentBetElement = document.getElementById('current-bet');
const spinBtn = document.getElementById('spin-btn');
const increaseBetBtn = document.getElementById('increase-bet');
const decreaseBetBtn = document.getElementById('decrease-bet');
const winMessage = document.getElementById('win-message');
const rouletteWheel = document.getElementById('roulette-wheel');
const wheelNumbersContainer = document.getElementById('wheel-numbers');
const wheelSeparatorsContainer = document.getElementById('wheel-separators');
const numberButtons = document.querySelectorAll('.number-btn');

// Sound elements
const spinSound = document.getElementById('spin-sound');
const winSound = document.getElementById('win-sound');
const loseSound = document.getElementById('lose-sound');

// Create wheel separators
function createWheelSeparators() {
wheelSeparatorsContainer.innerHTML = '';
const segmentAngle = 360 / wheelNumbers.length;

for (let i = 0; i < wheelNumbers.length; i++) {
const separator = document.createElement('div');
separator.className = 'wheel-separator';
separator.style.transform = `rotate(${i * segmentAngle}deg)`;
wheelSeparatorsContainer.appendChild(separator);
}
}

// Create wheel numbers
function createWheelNumbers() {
wheelNumbersContainer.innerHTML = '';
const segmentAngle = 360 / wheelNumbers.length;
const radius = (Math.min(rouletteWheel.clientWidth, rouletteWheel.clientHeight) / 2) - 20;

wheelNumbers.forEach((num, i) => {
const numberElement = document.createElement('div');
numberElement.className = 'wheel-number';
numberElement.textContent = num;

// Calculate position - center of each segment
const angleDeg = (i * segmentAngle) + (segmentAngle / 2) - 90; // -90 to start from top
const angleRad = (angleDeg * Math.PI) / 180;
const x = radius * Math.cos(angleRad);
const y = radius * Math.sin(angleRad);

numberElement.style.left = `calc(50% + ${x}px - 12px)`;
numberElement.style.top = `calc(50% + ${y}px - 12px)`;

wheelNumbersContainer.appendChild(numberElement);
});
}

// PERFECT pointer calculation
function getPointerNumber(rotation) {
const segmentAngle = 360 / wheelNumbers.length;

// Normalize rotation to 0-360 range
const normalizedRotation = ((rotation % 360) + 360) % 360;

// The pointer is at 0 degrees (top of wheel)
// Find which segment the pointer is in
const rawSegmentIndex = Math.floor(normalizedRotation / segmentAngle);

// Since the wheel spins clockwise but our array goes clockwise,
// we need to find the opposite segment that ends up under the pointer
const adjustedIndex = (wheelNumbers.length - rawSegmentIndex) % wheelNumbers.length;

return wheelNumbers[adjustedIndex];
}

// Update UI functions
function updateBalance() {
balanceElement.textContent = balance;
localStorage.setItem('casinoBalance', balance);
}

function updateBet() {
currentBetElement.textContent = currentBet;
}

function updateButtons() {
decreaseBetBtn.disabled = currentBet = Math.min(1000, balance);
spinBtn.disabled = balance < currentBet || isSpinning || selectedNumber === null;
}

function changeBet(delta) {
const newBet = currentBet + delta;
if (newBet >= 100 && newBet {
const winningNumber = getPointerNumber(totalRotation);
finishRound(winningNumber);
}, 4000);
}

function finishRound(winningNumber) {
isSpinning = false;
spinBtn.textContent = 'SPIN';
updateButtons();

if (spinSound) {
spinSound.pause();
spinSound.currentTime = 0;
}

if (winningNumber === selectedNumber) {
const winAmount = currentBet * 36;
balance += winAmount;
updateBalance();
showWinMessage(winAmount, winningNumber);

if (winSound) {
try {
winSound.currentTime = 0;
winSound.play();
} catch(e) {}
}

celebrate(winningNumber);
} else {
showLoseMessage(winningNumber);

if (loseSound) {
try {
loseSound.currentTime = 0;
loseSound.play();
} catch(e) {}
}
}
}

// Result messages
function showWinMessage(amount, winningNumber) {
winMessage.innerHTML = `
🎉 WINNER! 🎉

Ball landed on ${winningNumber} (${getNumberColorName(winningNumber)})
Your bet: ${selectedNumber} (${getNumberColorName(selectedNumber)})

You won $${amount}!
35:1 payout - congratulations!
`;
winMessage.classList.add('show');
winMessage.classList.remove('lose');

setTimeout(() => winMessage.classList.remove('show'), 5000);
}

function showLoseMessage(winningNumber) {
winMessage.innerHTML = `
😔 Not This Time

Ball landed on ${winningNumber} (${getNumberColorName(winningNumber)})
Your bet: ${selectedNumber} (${getNumberColorName(selectedNumber)})

You lost $${currentBet}
Better luck next spin!
`;
winMessage.classList.add('show', 'lose');

setTimeout(() => winMessage.classList.remove('show', 'lose'), 4000);
}

function getNumberColorName(number) {
if (number === 0) return 'Green';
return redNumbers.includes(number) ? 'Red' : 'Black';
}

// Celebration effects
function celebrate(number) {
const container = document.querySelector('.roulette-game');
const particleCount = number === 0 ? 30 : 20;
const colors = number === 0 ? ['#07ac3e', '#ffd700', '#ffffff'] : ['#ffd700', '#ffffff'];

colors.forEach((color, index) => {
setTimeout(() => createParticles(particleCount / colors.length, color, container), index * 200);
});
}

function createParticles(count, color, container) {
for (let i = 0; i < count; i++) {
const particle = document.createElement('div');
particle.style.cssText = `
position: absolute;
width: ${4 + Math.random() * 8}px;
height: ${4 + Math.random() * 8}px;
background-color: ${color};
border-radius: 50%;
left: ${50 + (Math.random() - 0.5) * 60}%;
top: 40%;
opacity: 0;
transform: translate(-50%, -50%) scale(0);
box-shadow: 0 0 15px ${color};
transition: all ${1 + Math.random() * 2}s ease-out;
z-index: 1000;
pointer-events: none;
`;
container.appendChild(particle);

setTimeout(() => {
particle.style.opacity = '1';
particle.style.transform = `translate(${(Math.random() - 0.5) * 400}px, ${(Math.random() - 0.5) * 400 - 200}px) scale(${0.5 + Math.random()})`;
}, Math.random() * 100);

setTimeout(() => {
particle.style.opacity = '0';
particle.style.transform += ' scale(0)';
setTimeout(() => {
if (container.contains(particle)) {
container.removeChild(particle);
}
}, 1000);
}, 1500 + Math.random() * 1000);
}
}

// Initialize game
function init() {
createWheelSeparators();
createWheelNumbers();
updateBalance();
updateBet();
updateButtons();

spinBtn.addEventListener('click', startSpin);
increaseBetBtn.addEventListener('click', () => changeBet(100));
decreaseBetBtn.addEventListener('click', () => changeBet(-100));

numberButtons.forEach(btn => {
btn.addEventListener('click', () => {
const number = parseInt(btn.dataset.number, 10);
selectNumber(number);
});
});
}

init();
});
< /code>
Изображение


Подробнее здесь: https://stackoverflow.com/questions/797 ... lette-game
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»