2

enter image description hereI have developed a slot machine in Phaser 3. The reels are essentially tile sprites that rotate during spinning. When the reels slow down, I would like to load a tile sprite of symbols representing the outcome of the payout engine. Since I can't load a tile sprite representing the entire reel (each physical reel would contain more than 100 images), the below code I have developed needs to be modified so that instead of loading "symbols", it loads a tile sprite containing predetermined images.

function spin_end(obj){
        //stop obj tilesprite at stop position
        obj.y = get_stop('start', obj.id);
        obj.setTexture('symbols');
        //it should be changed in  obj.setTexture('results') how can i create results???
        self.tweens.add({
            targets: obj,
            y: get_stop('end', obj.id),
            duration: 800,
            ease: 'Back.easeOut',
            onComplete(){
                if(obj.id === 4){
                    calculate();
                    is_spinning = false;
                }
            }
        });
        setTimeout(()=>{
            play_sound('Slot Machine Stop '+Number(obj.id+1), self);
        }, 400);
    }
Diego
  • 37
  • 5
  • Can you elaborate abit more, it is not clear what you want. why should it be `obj.setTexture(...)`? why is the symbols texture not enough? – winner_joiner Jun 08 '23 at 16:29
  • Symbol textures are all the symbols that make up the slot, such as cherry, diamond, etc. So, for example, this slot machine has twelve symbols, and I load a tile sprite on every reel.Of course, the mathematics of the slot machine result in different outcomes compared to what can be achieved with a fixed tile sprite. The slot machine's calculations generate various combinations that may not be present in a static tile sprite.Yes, if the server gives you an outcome such as (cherry, cherry, cherry) for the first reel, you would need to create a tile sprite that contains only those symbols – Diego Jun 08 '23 at 17:02

1 Answers1

0

I don't really understand your problem. You can generate reels with tilesprites and randomly set the result, like in the demo below. you don't need to have all combinations pre created.

Mini Slot-machine - Demo:

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    scene: { create },
    banner: false
}; 

function create () {
    this.add.text(10,10, 'Click to start')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
    this.add.text(250 ,10, 'TileSprite')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
    let graphics = this.make.graphics();
    createReelGraphics(graphics);
    
    this.add.image( 380, 10, 'img' ).setOrigin(0).setScale(1.5);
    
    this.reel1 = this.add.tileSprite(110, 85, 10, 10, 'img').setScale(3);
    this.reel2 = this.add.tileSprite(145, 85, 10, 10, 'img').setScale(3);
    this.reel3 = this.add.tileSprite(180, 85, 10, 10, 'img').setScale(3);

    startSpin(this);

    this.input.on('pointerdown', () => startSpin(this));

}

function startSpin(scene){

    setRandomStartPosition(scene);
    scene.tweens.add({
        targets: [scene.reel1, scene.reel2, scene.reel3] ,
        tilePositionY: '+=100',
        duration: 800,
    });
}

function setRandomStartPosition(scene){
    scene.reel1.tilePositionY = Phaser.Math.Between(0, 8) * 10
    scene.reel2.tilePositionY = Phaser.Math.Between(0, 8) * 10
    scene.reel3.tilePositionY = Phaser.Math.Between(0, 8) * 10
}

new Phaser.Game(config);


function createReelGraphics(graphics){
    let colors = [ 0xFF0000, 0xFF00DC, 0xB200FF, 0x4800FF, 0x0094FF, 0x00FFFF, 0x00FF90, 0x4CFF00, 0xFFD800, 0xFF6A00];
    
    for(let idx in colors){
        graphics.fillStyle(colors[idx]);
        graphics.fillRect(0, (idx * 10), 10, 10 );
    }
    
    graphics.generateTexture('img', 10, colors.length * 10);
}
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

I hope this demo helps abit, or atleast helps to clarify the problem.

Update - Dynamic Reels:
The code might need some improvement.
If you load the sprite with this.load.sprite(...) you don't need all the crazy workaround of the createReelGraphics function.

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    scene: { create },
    banner: false
}; 

new Phaser.Game(config);

console.clear();

function create () {
    this.add.text(10,10, 'Reels - Click to rnd create')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
    let graphics = this.make.graphics();
    createReelGraphics(this, graphics);

    let serverData = rndData();
    this.reels = []
    
    createReels(this, serverData)
    
    this.input.on('pointerdown', () => createReels(this, rndData()) );
    
}

// crazy code, just ignore :)
function rndData(){
    return '1'.repeat(3).split('').map( x => '1'.repeat(4).split('').map( y => Phaser.Math.Between(0,9)) )
}

// create image-textures for the each reels
function createReels(scene, reelData){
    
    for(let reel of scene.reels){
        reel.destroy();
    }
    
    scene.reels = [];
     
    for(let realIdx in reelData){
        let reelKey = `reel${realIdx}`;
        let reelHelper = scene.make.renderTexture(
          {x: 0, y: 0, width: 10, height: 10 * reelData[realIdx].length, add: false}
        );
        
        for(let symbolIdx in reelData[realIdx]){
           let helper = scene.make.image({ x: 0,
                y: 10 * symbolIdx,
                key: 'reel',
                frame: reelData[realIdx][symbolIdx],
                add: false })
                .setOrigin(0);
            reelHelper.draw(helper);
        }
         
        if(scene.textures.exists(reelKey)){
            scene.textures.remove(reelKey);
        }
        reelHelper.saveTexture(reelKey);
        
        scene.reels.push(scene.add.image( 40 + (40 * realIdx), 100, reelKey).setScale(2.5));
    }
}

// If you load the image as a sprite you dont neet all this
function createReelGraphics(scene, graphics){
    let colors = [ '#FF0000', '#FF00DC', '#B200FF', '#4800FF', '#0094FF', '#00FFFF', '#00FF90', '#4CFF00', '#FFD800', '#FF6A00'];
    
    let canvasSprite = scene.textures.createCanvas('reel', 10, 10 * colors.length);
    let ctx = canvasSprite.context;
    
    for(let idx in colors){
        ctx.fillStyle = colors[idx];
        ctx.fillRect(0, (idx * 10), 10, 10 );
        canvasSprite.add(idx, 0, 0, idx * 10, 10, 10);
    }
    canvasSprite.refresh();
}
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
winner_joiner
  • 12,173
  • 4
  • 36
  • 61
  • i don't expose the problem clear or maybe ut's not clear to me how tilesprite works. The problem I'm facing is the following: if the server send combination for example all diamonds on all reels on each position :[D,D,D],[D,D,D],[D,D,D],[D,D,D],[D,D,D]. I cannot create this combination starting from the tileprite that i create from the image above, as i don't have 3 sequentials diamonds. isn't it? – Diego Jun 09 '23 at 06:25
  • Correct. TileSprite just repeats the same sprite, when the size exceeds the size of the image, but you could generate those reels dynamically. I updated my question, with an example. – winner_joiner Jun 09 '23 at 11:36