Jump to content

What is the best way to generate multiple shape and animate them


Paul Bonneau
 Share

Recommended Posts

Hi everyone,

I'm working on a javascript clone of superhexagon (https://www.superhexagon.com/) in order to learn to use Phaser 3.

I was wondering what was the best way to generate the same shape multiple time with some rotation tweek and animate them.

I need generate them, display them, once they display I need to be able to rotate them and scale them down. Once their scale <= 0 I need to hide and destroy them.

I know I need to build a kind of Factory but I can't figure out how to do it with gameObj.add.arc

Could you point a part of doc or source code I can dig in to find a solution?

 

I created a pen here https://codepen.io/paulbonneau/pen/KGGbGO

Thanks in advance !

Paul.

Link to comment
Share on other sites

Ok, I think I need to find a way to generate separate arc shape first. Those shape have to be generated without being directly added to the game with gameObj.add.arc (as I did in the pen showed in the preceding post). Those shape will have to be generated along the game, creation of a new shape will be triggered once a shape has reached a certain scale diminution.

My problem here is when I tried to generate a shape using the Arc object :

Phaser.GameObjects.Arc(game.config.width / 2, game.config.height / 2, 300, 0, 300, false)

the following error is returned:

TypeError: t.sys is undefined

Don't know if it's normal or not and if I'm using the cood method in order to do what I want to do. Could someone point if I'm digging in the right way ?

Thanks for your help,

I keep digging

Link to comment
Share on other sites

So, I think I found a good solution to generate my polygon. Could someone tell me if it's "the good way" of doing it ?

Now i'm struggling a bit to detect collision between the player and the polygons I generated ? Is it event possible to do so with the Arc object I am using for my polygons ? I pasted my code under and updated my pen if you want to take a look :)

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser-arcade-physics.min.js"></script>
</head>
<body>

    <script>
        var polygons,player;
        var Polygon = new Phaser.Class({
                Extends: Phaser.GameObjects.Arc,
                initialize:
                    function Polygon(scene) {
                        rotationPosibilities = [0,40,90,140, 280]
                        Phaser.GameObjects.Arc.call(this, scene);
                        this.setPosition(game.config.width / 2, game.config.height / 2);
                        this.setRadius(600);
                        this.setStartAngle(0);
                        this.setEndAngle(300);
                        this.setIterations(0.2);
                        this.setOrigin(2.5);
                        this.lineWidth = 40;
                        this.strokeColor = 0xFF0000;
                        this.strokeAlpha = 1;
                        this.isStroked = true;
                        this.setClosePath(false);
                        this.scale = 1
                        this.rotation = rotationPosibilities[Math.floor(Math.random() * Math.floor(4))]
                    }

            });
    
        var config = {
            type: Phaser.AUTO,
            width: 800,
            height: 600,
            physics: {
                default: 'arcade',
                arcade: {
                    gravity: { y: 0 },
                    debug: true
                }
            },
            scene: {
                preload: preload,
                create: create,
                update: update
            }
        };

        var game = new Phaser.Game(config);
        var polygon, player;
        
        function preload(){}
        function create() {
            polygons = [];
            polygons.push(this.children.add(new Polygon(this)));
            createPlayer(this);
        }
 
        function createPlayer(gameObj) {
            player = gameObj.add.circle(game.config.width / 2, game.config.height / 2, 20, 0x6666ff)
            player.setOrigin(4);
            gameObj.input.on('pointermove', function (pointer) {
                player.rotation = (Math.atan2(pointer.position.x - game.config.width / 2, - (pointer.position.y - game.config.height / 2)) * (180 / Math.PI)) / 10
            });
            
        }
        function update() {
            gameObj = this;
            polygons.forEach((polygon,index,object) => { 
                polygon.scaleX -= 0.004;
                polygon.scaleY -= 0.004;
                polygon.rotation += 0.01;
                if(polygon.scaleX <= 0){
                    object.splice(index,1)
                    polygon.destroy()
                }
                if(polygons.length < 2 && polygon.scaleX < 0.5){
                    var newPolygon = new Polygon(gameObj);
                    polygons.push(this.children.add(newPolygon));
                }
            });
        }


    </script>

</body>
</html>

 

Link to comment
Share on other sites

I looked at your code, I like it, I've never used Arc before but you've made it look like the effect you're going for!

I've updated you Polygon class:

        var Polygon = new Phaser.Class({
                Extends: Phaser.GameObjects.Arc,
                initialize:
                    function Polygon(scene) {
                        rotationPosibilities = [0,40,90,140, 280]
                        Phaser.GameObjects.Arc.call(this, scene, game.config.width / 2, game.config.height / 2, 600, 0, 300)
                        this.setIterations(0.2);
                        this.lineWidth = 40;
                        this.strokeColor = 0xFF0000;
                        this.strokeAlpha = 1;
                        this.isStroked = true;
                        this.setClosePath(false);
                        this.rotation = rotationPosibilities[Math.floor(Math.random() * Math.floor(4))]
                      scene.add.existing(this);
                    }

I've put all of the needed arguments into the call function, which meant I was able to remove the setOrigin code as well, because now it is properly set in the centre. 

I also add scene.add.existing(this) to the end of initialize, which means when you create the object it adds the object to your scene straight away! I had to edit the code near  the bottom to make sure it didn't break it:

            polygons.push(new Polygon(this));

To add the physics to your program, there's a couple of things you could do, but the one I would do would be creating a thin body at the "opening" of the shape and then, if the player doesn't collide with the rectangle during a certain size for the polygon, the polygon sends a "gameover" event. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...