I made a Roguelike Deckbuilder in Phaser

Hi guys. I finnished the course “Learn Game Development with Phaser.js” three months ago, and since then I have spent pretty much all of my spare time developing and programming this game.

You can try it here: Punk Rock Samurai

Or read the source code here: GitHub - ErlendKK/Punk-Rock-Samurai: Punk Rock Samurai

Hope you will like it :). I would appreciate any feedback.

1 Like

Fun and visually pleasing “mortal kombat” style deckbuilder. About to go to work, so can’t check the source code right now, but if i get around to it i’d love to try to give feedback on it:)
The only thing i noticed (which i imagine will be quite a challenge to “fix”, and is in no way gamebreaking) is that when trying to wiggle between two cards, it stays on the currently focused card until the exact edge of the border.
If you want to change it, i would suggest doing it as in hearthstone - iirc, its more of a smooth transition between all the cards, which makes “wiggles” on the cards seem more fluid.
But again - i have no idea how difficult it would be to implement it. But if you’re up for the challenge, im sure it would be good practice and a QoL update:)
Good luck!

2 Likes

Thanks for the feedback :slight_smile: ! I haven’t played Hearthstone in a while, so I don’t remember how the card animations looks/ feels there, but now that you point it out, I agree that my current implementation is not all that smooth. It might be possible to make a pointerout event fire when the curser has moved to e.g. [the x-coordinate of the center of the card sprite +/- 0.4 times its width] or something, but I’m not sure how to implement that. I would appreciate any suggestions you might have.

That might be possible, but as you point out im not quite sure how to implement it either.
Another way you might be able to do this would be to have a zone wherein your cards are, and then instead of having select/deselected cards, you could have areas where the card is fully chosen, and in a margin of x pixels, you descale the current card and upscale the next one, which (theoretically) would make a sort of wave-animation through the cards.
I’ve added a visualization of what i mean to this comment. hope it makes sense.

I dont use JS myself, so im not sure how one would do it, but i just might take the course you did, learn it, and attempt to implement it if i find the time:)

Good luck!

Okay, i actually made a pseudo program for it to draw inspiration from…
here it is:

zonex = [0,10,20,30,40]
maxdist = zonex[4] - zonex[0]


mousex = get.pointer.x
if zonex[0] < mousex < zonex[4] 
    for i in zonex[]:
        float Card.scale(i) = (maxdist - (Math.abs(mousex-zonex[i]))) / (maxdist/2)  #same as above.

        if Card.scale(i) < 1: #just to make sure the cards dont disappear when they are furthest from the mouse
        Card.scale(i) = 1

Card1.scale = Card.scale(1) #adding the new scale to the cards, one by one.
Card2.scale = Card.scale(2)
Card3.scale = Card.scale(3)
Card4.scale = Card.scale(4)
Card5.scale = Card.scale(5)

You’d also then want to add that if not mousex in the card-zone, then reset all card sizes to whatever you please (1 for example…)

Dont hesitate to reply if something is confusing, and i’d be happy to explain (or try, anyways.)

…okay i actually made a test-script that worked. the above was not quite right, but the general idea.
This actually works:

const gameState = {}

function preload(){
    this.load.image("Card","https://upload.wikimedia.org/wikipedia/en/thumb/a/aa/Magic_the_gathering-card_back.jpg/220px-Magic_the_gathering-card_back.jpg");
}

function create(){
    //creating cards 1-5
    gameState.card1 = this.add.sprite(724,977,"Card");
    gameState.card2 = this.add.sprite(852,977,"Card");
    gameState.card3 = this.add.sprite(980,977,"Card");
    gameState.card4 = this.add.sprite(1108,977,"Card");
    gameState.card5 = this.add.sprite(1236,977,"Card");
    //setting default sizes.
    gameState.card1.setSize (128,150);
    gameState.card2.setSize (128,150);
    gameState.card3.setSize (128,150);
    gameState.card4.setSize (128,150);
    gameState.card5.setSize (128,150);
    //making cards interactive.
    gameState.card1.setInteractive();
    gameState.card2.setInteractive();
    gameState.card3.setInteractive();
    gameState.card4.setInteractive();
    gameState.card5.setInteractive();
    //creating max card size for later use.
    gameState.maxcardsize = 1.3;
    
    //Checking card for mouse click
    
    //creating debug texts
    gameState.where_mouse_x = this.add.text(100,0, "asd",{fontSize:80});
    gameState.where_mouse_y = this.add.text(100,100,"dsa",{fontSize:80});



  //  gameState.text1 = this.add.text(100,400,"asd",{fontSize:80});
  //  gameState.text2 = this.add.text(100,500,"asd",{fontSize:80});
  //  gameState.text3 = this.add.text(100,600,"asd",{fontSize:80});
  //  gameState.text4 = this.add.text(100,700,"asd",{fontSize:80});
  //  gameState.text5 = this.add.text(100,800,"asd",{fontSize:80});
}

function update(){
    //checking where the mouse is.
    mousex = Math.floor(game.input.mousePointer.x); 
    mousey = Math.floor(game.input.mousePointer.y);

    //writing to debug text where mouse is.
    gameState.where_mouse_x.setText("x: " + mousex);
    gameState.where_mouse_y.setText("y: " + mousey);
    //Resetting depth to ensure Depth is correct and only affected on cards being resized.
    gameState.card1.setDepth(0);
    gameState.card2.setDepth(0);
    gameState.card3.setDepth(0);
    gameState.card4.setDepth(0);
    gameState.card5.setDepth(0); 






        //if in bounds of card box, checks every cards distance from the mouse and rescales if within threshold (both upper and lower)
    if ( 550 < mousex && mousex < 1350){
        
        scale1 = (100/Math.abs(mousex - 724));
        if (scale1 > 1 && scale1 < gameState.maxcardsize){
            gameState.card1.setScale(scale1,scale1);

        }

        scale2 = (100/Math.abs(mousex - 852));
        if (scale2 > 1 && scale2 < gameState.maxcardsize){
            gameState.card2.setScale(scale2,scale2);

        }


        scale3 = (100/Math.abs(mousex - 980));
        if (scale3 > 1 && scale3 < gameState.maxcardsize){
            gameState.card3.setScale(scale3,scale3);
        }

        scale4 = (100/Math.abs(mousex - 1108));
        if (scale4 > 1 && scale4 < gameState.maxcardsize){
            gameState.card4.setScale(scale4,scale4);
        }
        scale5 = (100/Math.abs(mousex - 1236));
        if (scale5 > 1 && scale5 < gameState.maxcardsize){
            gameState.card5.setScale(scale5,scale5);
        }
        gameState.card1.setDepth(scale1);
        gameState.card2.setDepth(scale2);
        gameState.card3.setDepth(scale3);
        gameState.card4.setDepth(scale4);
        gameState.card5.setDepth(scale5);
        
    }



    if ( 550 > mousex || mousex > 1350){ //
        gameState.card1.setScale(1,1);
        gameState.card2.setScale(1,1);
        gameState.card3.setScale(1,1);
        gameState.card4.setScale(1,1);
        gameState.card5.setScale(1,1);        

    }




    
}

const config = {
    width: 1920,
    height:1080,
    backgroundColor:0x00008b,
    scene:{
        preload,
        create,
        update,

    }
};
const game = new Phaser.Game(config);

i just used Magic cards as an example. also note that the cards dont have the slight tilt you have.

Thanks for the effort. I definately think your onto something, the effect looks really cool. I dont think it would be straightforward to implement it in my game though, as the bounds of card box will vary over the game. I.e. you may have anywhere from 0 to 8 cards at hand at various positions, there are cards that let you draw more cards, etc. And I imagine all of this would have to be dynamically updated based on the number of cards and their position. I will try to experiment a bit over the weekend and see if I can get it to work.

No worries! you’re right, you might need a specific function to calculate the card-zone in the game. I primarily wanted to challenge myself and learning a bit of javascript seemed like a fun thing to do.
Have fun experimenting!

fre. 15. sep. 2023 kl. 22.26 skrev java8814854037 via Codecademy Forums <[email protected]>: