crypto-slots
Version:
A minimal test server is provided, see server
305 lines (268 loc) • 8.83 kB
JavaScript
import define from './../../../node_modules/backed/src/utils/define.js';
import { lottery } from './../../../node_modules/lucky-numbers/index.js';
import SlotSound from './../sound'
import './slot-ring.js';
export default define(class SlotReel extends HTMLElement {
set name(value) {
// let i = 0;
// for (const ring of this.rings) {
// ring.index = i;
// ring.name = value;
// ++i;
// }
this._name = value;
}
set value(value) {
}
get value() {
}
set icon(value) {
}
showBonusRound() {
return new Promise((resolve, reject) => {
this.bonusHero.classList.add('opened');
setTimeout(() => {
this.bonusHero.classList.remove('opened');
resolve();
}, 2000);
});
}
promisSpins() {
return new Promise(async (resolve, reject) => {
// await this.multiplier.forEach(async multi => {
this.wins += await this.spin(this.betAmount);
--this.multiplier;
if (this.multiplier > 1) await this.promisSpins();
resolve();
// })
});
}
promiseFil(slot, joker) {
return new Promise((resolve, reject) => {
for (const child of slot) {
const fil = slot.filter(r => {
if (child._name === r._name || r._name === joker) return true;
return false;
});
if (fil.length === 5) return resolve(fil);
}
resolve([])
});
}
promiseResult(fil) {
const multiplier = Number(this.game.multiplier);
return new Promise(async (resolve, reject) => {
const spins = []
if (fil.length === 5) {
const result = fil.filter(f => {
if (f._name !== 'btc') return f;
});
for (const f of fil) {
await f.win();
}
if (result.length === 0) {
this.multiplier = this.multiplier * multiplier;
await this.showBonusRound();
await this.promisSpins();
this.multiplier = 1;
this.winAmount = this.wins;
this.wins = 0;
resolve(this.winAmount);
} else {
// console.log();
console.log(this.winAmount, Math.round((this.multiplier * this.bet)));
this.winAmount += Math.round((this.multiplier * this.bet ));
console.log(this.winAmount);
resolve(this.winAmount)
}
} else {
resolve(this.winAmount)
}
});
}
async onSpinEnd(rings) {
this.game = window.slots.get(this._name);
const s = this.game.slots;
const joker = this.game.bonus;
const wins = this.game.wins;
const horizontalRings = [];
for (let i = 0; i < rings.length; ++i) {
if (!horizontalRings[i]) horizontalRings[i] = [];
horizontalRings[i].push(rings[i])
}
for (var i = 0; i < horizontalRings.length; i++) {
rings.push(horizontalRings[i])
}
for (const slot of rings) {
const fil = await this.promiseFil(slot, joker);
const result = await this.promiseResult(fil);
}
this.amount = Number(localStorage.getItem('amount')) + this.winAmount;
localStorage.setItem('amount', this.amount);
document.dispatchEvent(new CustomEvent('spin-end'));
console.log({win: this.winAmount});
this.wins += this.winAmount;
// this.multiplier = 1;
this.winAmount = 0;
console.log('END');
}
async setupSound() {
this.source = [new SlotSound('start.mp3'), new SlotSound('spin.mp3'), new SlotSound('done.mp3')]
// if (!this.gainNode) {
// this.audioContext = this.audioContext || new AudioContext()
// this.gainNode = this.audioContext.createGain()
//
// const audio = [this.shadowRoot.querySelector('audio[name="start"]'), this.shadowRoot.querySelector('audio[name="spin"]')]
// console.log(audio);
// this.source = [this.audioContext.createMediaElementSource(audio[0]), this.audioContext.createMediaElementSource(audio[1])]
//
//
// this.source[0].connect(this.gainNode)
// this.source[1].connect(this.gainNode)
// this.gainNode.connect(this.audioContext.destination)
//
// this.gainNode.gain.value = 1
// return
// }
}
async spin(bet) {
// if (!this.source) await this.setupSound()
console.log(this.source);
this.source[0].startTime = 0.5
this.source[0].gainNode.gain.value = 0.35
this.source[0].play()
return setTimeout(() => {
// }
this.bet = bet;
console.log('START');
// TODO: change to contract
// await fetch('')
this.currentSymbols = this.nextSymbols || [
lottery(3, 12),
lottery(3, 12),
lottery(3, 12),
lottery(3, 12),
lottery(3, 12),
];
this.nextSymbols = [
lottery(3, 12),
lottery(3, 12),
lottery(3, 12),
lottery(3, 12),
lottery(3, 12),
];
this.source[0].gainNode.gain.value = 1
this.source[1].play()
return Promise.all(
this.rings.map((ring, i) => {
return ring.renderSymbols(
this.currentSymbols[i],
this.nextSymbols[i],
);
// return ring.spin();
}),
).then(resolved => {
this.source[1].stop()
this.source[0].stop()
setTimeout(() => {
this.source[2].play()
setTimeout(() => {
this.source[2].stop()
}, 500);
}, 320);
this.onSpinEnd(resolved)
});
}, 160);
}
get bonusHero() {
return this.shadowRoot.querySelector('.bonus-hero');
}
constructor() {
super();
this.setupSound()
this.attachShadow({ mode: 'open' });
this.multiplier = 1;
this.winAmount = 0;
this.wins = 0;
this.shadowRoot.innerHTML = `<style>
:host, .container {
display: flex;
flex-direction: row;
background: #265a74ba;
border-radius: 10%;
/* width: calc(100% - 80px); */
}
:host {
/* box-shadow: 15px -15px 20px 0px #5C6BC0, 15px 15px 20px 0px #7986CB, -15px 15px 20px 0px #5C6BC0, -15px -15px 20px 0px #7986CB; */
}
.container {
width: var(--slot-reel-size);
height: var(--slot-reel-size);
overflow: hidden;
border-radius: 10%;
}
slot-ring {
/* position: absolute; */
top: 0;
bottom: 0;
}
.bonus-hero {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 240px;
width: 240px;
background: #fff;
opacity: 0;
pointer-events: none;
}
.opened {
opacity: 1;
}
audio {
display: none;
}
</style>
<audio name="start" src="start.mp3"></audio>
<audio name="spin" src="spin.mp3"></audio>
<span class="container">
</span>
<span class="bonus-hero">
<h2 style="color: #111;">Bonus Round!</h2>
</span>
`;
}
connectedCallback() {
this.game = globalThis.slots.get(globalThis.slots.get('game'))
console.log(this.game);
for (var i = 0; i < this.game.columns; i++) {
const ring = document.createElement('slot-ring')
ring.setAttribute('slots', this.game.slots.length)
ring.index = i
ring.name = globalThis.slots.get('game')
this.shadowRoot.querySelector('.container').appendChild(ring)
}
this.rings = Array.from(this.shadowRoot.querySelectorAll('slot-ring'));
const matches = (x) => {
const { height, width } = document.body.getBoundingClientRect();
let ringSlotHeight = height / this.game.columns;
let ringSlotWidth = width / this.game.rows;
if (!x.matches) {
// width = width - 15;
// ringSlotWidth = width / 5;
document.body.style.setProperty('--slot-reel-size', `${width - 60}px`);
document.body.style.setProperty('--slot-ring-width', '100%');
document.body.style.setProperty('--slot-ring-height', '100%');
document.body.style.setProperty('--slot-ring-slot-size', `${ringSlotWidth - 12}px`);
} else {
ringSlotHeight = height - 320;
document.body.style.setProperty('--slot-reel-size', `${ringSlotHeight}px`);
document.body.style.setProperty('--slot-ring-slot-size', `${ringSlotHeight / 5}px`);
}
}
var x = window.matchMedia("(min-width: 640px)");
matches(x)
x.addListener(matches.bind(this))
}
})