重新启动旋转轮盘Javascript

重新启动旋转轮盘Javascript,javascript,Javascript,我发现这两个脚本用Javascript制作轮盘赌,第一个脚本制作动画并控制轮盘赌,第二个脚本获取轮盘赌的数据 轮盘赌 // WEAPON CLASS // ------------------------------------------------ ----------------------------- function EvWeapon(id, attrs) { // identifier corresponds to the ordinal in the weapons a

我发现这两个脚本用Javascript制作轮盘赌,第一个脚本制作动画并控制轮盘赌,第二个脚本获取轮盘赌的数据

轮盘赌

// WEAPON CLASS
// ------------------------------------------------ -----------------------------

function EvWeapon(id, attrs) {
    // identifier corresponds to the ordinal in the weapons array
    // EvRoulette class
    this.id          = id; 

    // attributes from the server

// this.skin_name = attrs.skin_name;
// this.rarity = attrs.rarity;
    this.steam_image = attrs.steam_image;

    // DOM element is created in roulette render
    this.el          = null; 
}

EvWeapon.EL_WIDTH = 200;

// ROULETTE CLASS
// ------------------------------------------------ -----------------------------

function EvRoulette(attrs) {
    // attributes for generating this.weapons array
    this.weapon_prize_attrs  = attrs.weapon_prize_attrs;
    this.weapon_actors_attrs = attrs.weapon_actors_attrs;

    // all weapons will be here (prize weapons + actor weapons)
    this.weapons = [];

    // parent DOM element for roulette
    this.el_parent = attrs.el_parent;

    // DOM element of the roulette itself
    this.el = null;

     // parent DOM element for weapon DOM elements
     // (it spins)
    this.el_weapons = null;

     // callback at the start of rotation
    this.beforeparty = attrs.beforeparty;

     // callback at the end of the rotation
     this.afterparty = attrs.afterparty;
}
}

// ROULETTE PARAMETERS
// ------------------------------------------------ -----------------------------

// N_WEAPONS is the total number of weapons in roulette
// (prize + possibly duplicate actors)
//
// all weapons must be at least 8 pieces
// this is how it looks
//
// + --- + --- + --- + + --- + --- + --- + --- + --- +
// | 0 | 1 | 2 | ... | L-5 | L-4 | L-3 | L-2 | L-1 |
// + --- + --- + --- + + --- + --- + --- + --- + --- +
//
// L is N_WEAPONS
// (or after calling the 'set_weapons' method: this.weapons.length)
//
// L-3 - this is where the prize weapon is

// total number of weapons
EvRoulette.N_WEAPONS = 25;

// prize idian
EvRoulette.WEAPON_PRIZE_ID = EvRoulette.N_WEAPONS - 3;

// rotation time
EvRoulette.SPIN_SECS = 10;

// delayed start time
EvRoulette.START_DELAY_MSECS = 100;

// sync interval for spinning sounds
EvRoulette.SOUND_SPIN_INTERVAL = 100;

// interval for waiting for pictures
EvRoulette.IMAGE_LOAD_INTERVAL = 500;

// maximum waiting time for pictures
// after that you have to give up and show broken pictures
EvRoulette.IMAGE_LOAD_WAIT_MSECS = 10 * 1000;

// sounds
EvRoulette.SOUND_START = 'snd / roulette_start.wav';
EvRoulette.SOUND_SPIN = 'snd / roulette_spin.wav';
EvRoulette.SOUND_STOP = 'snd / roulette_stop.wav';

// CREATE WEAPON FROM ATTRIBUTES
// ------------------------------------------------ -----------------------------

// question: what's going on here?
// answer: - an array of N_WEAPONS-1 actors is created
// - the position WEAPON_PRIZE_ID is occupied by the prize

EvRoulette.prototype.set_weapons = function () {
    var
        self              = this,
        weapons           = [],
        weapon_actors_len = self.weapon_actors_attrs.length,
        j                 = 0,
        set_weapon_actors = function (from_i, to_i) {
            var i;
            for (i = from_i; i <= to_i; i += 1) {
                weapons[i] = new EvWeapon(
                    i,
                    self.weapon_actors_attrs[j]
                );
                j = (j === weapon_actors_len - 1) ? 0 : j + 1;
            }
        };

    if (weapon_actors_len === 0) {
        throw new Error('Ошибка! Нет актёров.');
    }

    set_weapon_actors(0, EvRoulette.WEAPON_PRIZE_ID - 1);

    weapons[EvRoulette.WEAPON_PRIZE_ID] = new EvWeapon(
        EvRoulette.WEAPON_PRIZE_ID,
        self.weapon_prize_attrs
    );

    set_weapon_actors(EvRoulette.WEAPON_PRIZE_ID + 1, EvRoulette.N_WEAPONS - 1);

    self.weapons = weapons;
};

// RENDER
// -----------------------------------------------------------------------------

EvRoulette.prototype.render = function () {
    var
        self = this,

        el_roulette      = document.createElement('div'),
        el_target        = document.createElement('div'),
        el_weapons       = document.createElement('div'),

        // counting uploaded images
        n_images_loaded  = 0,
        image_load_wait  = 0,
        image_load_interval;

    el_roulette.id = 'ev-roulette';
    el_target.id   = 'ev-target';
    el_weapons.id  = 'ev-weapons';

    el_weapons.style.width = (EvRoulette.N_WEAPONS * EvWeapon.EL_WIDTH) + 'px';
    
    self.weapons.forEach(function (weapon) {
        var
            el_weapon                = document.createElement('div'),
            el_weapon_inner          = document.createElement('div'),
            el_weapon_rarity         = document.createElement('div'),
            el_weapon_img            = document.createElement('img'),
            el_weapon_text           = document.createElement('div'),
            el_weapon_text_name      = document.createElement('p'),
            el_weapon_text_skin_name = document.createElement('p');

        // important: onload callback before src
        el_weapon_img.onload = function () {
            n_images_loaded += 1;
        };

        el_weapon_img.src                    = weapon.steam_image;
        //el_weapon_img.alt                    = weapon.weapon_name;
        //el_weapon_text_name.textContent      = weapon.weapon_name;
        //el_weapon_text_skin_name.textContent = weapon.skin_name;
    
        el_weapon.className        = 'ev-weapon';
        el_weapon_inner.className  = 'ev-weapon-inner';
        el_weapon_rarity.className = 'ev-weapon-rarity ' +
            'ev-weapon-rarity-' + weapon.rarity;
        el_weapon_text.className   = 'ev-weapon-text';
    
        el_weapon_text.appendChild(el_weapon_text_name);
        el_weapon_text.appendChild(el_weapon_text_skin_name);
        el_weapon_inner.appendChild(el_weapon_rarity);
        el_weapon_inner.appendChild(el_weapon_img);
        el_weapon_inner.appendChild(el_weapon_text);
        el_weapon.appendChild(el_weapon_inner);
    
        weapon.el = el_weapon;  
        
        el_weapons.appendChild(weapon.el);
    });

    el_roulette.appendChild(el_target);
    el_roulette.appendChild(el_weapons);

    // wait for all images to be loaded
    // start spinning when finished
    image_load_interval = setInterval(function () {
        image_load_wait += EvRoulette.IMAGE_LOAD_INTERVAL;

        // full combat readiness or can't wait any longer
        if (
            (n_images_loaded === EvRoulette.N_WEAPONS) ||
            (image_load_wait >= EvRoulette.IMAGE_LOAD_WAIT_MSECS)
        ) {
            clearInterval(image_load_interval);

            self.el_weapons = el_weapons;
            self.el         = el_roulette;

            self.el_parent.appendChild(self.el);
            
            self.spin();
        }
    }, EvRoulette.IMAGE_LOAD_INTERVAL);
    
};

// LEARN ROULETTE TO PRODUCE SOUNDS
// ------------------------------------------------ -----------------------------

EvRoulette.prototype.make_sound = function (sound) {
    var audio    = new Audio(sound);
    audio.volume = 0.2;
    audio.play();
}; 

// ROLLETTE ROTATION
// ------------------------------------------------ -----------------------------

EvRoulette.prototype.spin = function () {
    var
        self = this,

        el_weapon_width_1_2  = Math.floor(EvWeapon.EL_WIDTH / 2),
        el_weapon_width_1_20 = Math.floor(EvWeapon.EL_WIDTH / 20),

        rand = function (min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        },

        // random stop coordinate
        rand_stop = (EvRoulette.N_WEAPONS - 5) * EvWeapon.EL_WIDTH +
                    el_weapon_width_1_2 +
                    rand(el_weapon_width_1_20, (18 * el_weapon_width_1_20)),
        
        // these guys are used to sync the sound
       // (when the target coincides with the start of the next weapon, it should tick)
        sound_spin_interval,
        // counts the number of passed weapons during rotation
        spin_counter = 0;

    // animation is now through 'transition', not through 'animation'
    // 'ease-out' is a smooth slowdown of the roulette
    self.el_weapons.style.transition =
        'left ' + EvRoulette.SPIN_SECS + 's ease-out';

    // a little delayed start
    // (because you cannot immediately set the css property 'left')
    setTimeout(function () {
        // before starting, there may be a need to create something
        self.beforeparty();

        self.make_sound(EvRoulette.SOUND_START);
        self.el_weapons.style.left = '-' + rand_stop + 'px';

        // try to sync rotation sound with animation here
        sound_spin_interval = setInterval(function () {
            var
                current_left = Math.abs(
                    parseInt(window.getComputedStyle(self.el_weapons).left, 10)
                ),
                current_spin_counter = Math.floor(
                    (current_left + el_weapon_width_1_2) / EvWeapon.EL_WIDTH
                );
            // roulette turned to new weapon
            if (current_spin_counter > spin_counter) {
                spin_counter = current_spin_counter;
                self.make_sound(EvRoulette.SOUND_SPIN);
            }
        }, EvRoulette.SOUND_SPIN_INTERVAL);
    
    }, EvRoulette.START_DELAY_MSECS);

    // animation stopped
    // means roulette too
    self.el_weapons.addEventListener('transitionend', function () {
        clearInterval(sound_spin_interval);
        self.make_sound(EvRoulette.SOUND_STOP);
        self.weapons.forEach(function (weapon) {
            if (weapon.id !== EvRoulette.WEAPON_PRIZE_ID) {
                weapon.el.style.opacity = 0.5;
            }
        });

        // that's it, the roulette has stopped
        // then you can do something of your own
        self.afterparty();
    });
};

// START
// -----------------------------------------------------------------------------

EvRoulette.prototype.start = function () {
    // before rendering, you need to create a weapon from the attributes
    this.set_weapons();

    // render, which will call this.spin () after images are loaded successfully
    this.render();
};
稍后我将创建一个脚本,使“index.js”中的数据随机放置

然而,我想知道如何在上一轮轮盘赌结束后重新开始轮盘赌。 我尝试调用
roulette.start()
函数,但显然它在前一个轮盘下创建了另一个轮盘。 另一方面,调用
roulette.spin()
函数时,什么也不会发生

我怎么办

 var
    WEAPON_PRIZE_ATTRS = {
        weapon_name: 'Bitcoin',
        skin_name:   '5x',
        rarity:      'milspec',
        steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Bitcoin-icon.png'
    },
    WEAPON_ACTORS_ATTRS = [
        {
            weapon_name: 'Etherum',
            skin_name:   '2x',
            rarity:      'restricted',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Ethereum-icon.png'
        },
        {
            weapon_name: 'Bitcoin',
            skin_name:   '5x',
            rarity:      'milspec',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Bitcoin-icon.png'
        },
        {
            weapon_name: 'Etherum',
            skin_name:   '2x',
            rarity:      'restricted',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Ethereum-icon.png'
        },
        {
            weapon_name: 'Litecoin',
            skin_name:   '1,5x',
            rarity:      'rare',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Litecoin-icon.png'
        },
        {
            weapon_name: 'Etherum',
            skin_name:   '2x',
            rarity:      'restricted',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Ethereum-icon.png'
        },
        {
            weapon_name: 'Litecoin',
            skin_name:   '1,5x',
            rarity:      'rare',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Litecoin-icon.png'
        },
        {
            weapon_name: 'Etherum',
            skin_name:   '2x',
            rarity:      'restricted',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Ethereum-icon.png'
        },
        {
            weapon_name: 'Litecoin',
            skin_name:   '1,5x',
            rarity:      'rare',
            steam_image: 'https://icons.iconarchive.com/icons/cjdowner/cryptocurrency/256/Litecoin-icon.png'
        }
    ];

// WHEN LOADING THE PAGE, THE ENTIRE ENGINE BEGINS HERE
// ------------------------------------------------ -----------------------------

function main() {
    var
        // where to mount the roulette
        el_parent = document.getElementById('mysite-roulette-container'),

        // initialize the roulette
        roulette = new EvRoulette({
            weapon_prize_attrs:  WEAPON_PRIZE_ATTRS,
            weapon_actors_attrs: WEAPON_ACTORS_ATTRS,
            el_parent:           el_parent,
            beforeparty:         function () {
                console.log('Поехали!');
            },
            afterparty:          function () {
                roulette();
            }
        });

    // rushed
    roulette.start();
    
}


document.addEventListener('DOMContentLoaded', main);