How to make body follow shape movement

Hi everyone !

I’m trying to add to a circle and multiple polygon shapes in order to test collision between those elements.

My problem is that I can’t figure out how to make those shapes body follow the shape they are attached to.

Also I was wondering if there where a way to shape bodies automaticaly according to the shape they are attached to ?

Here is my code if you want to take a look (https://codepen.io/paulbonneau/pen/KGGbGO):

 
<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,
            render: render
        }
    };

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.physics.add.existing(player);
        player.body.isMoving = true
        
        
        
        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);
                this.physics.add.existing(gameObj);
                polygons.push(this.children.add(newPolygon));
            }
        });
    }

    function render(){

    }


</script>

I already answered this in the other forum, but I might as well repeat here what I said there. You are using Arcade Physics, which only support rectangles and circles for performance reasons. If you need the physics bodies to have different shapes, you should either switch to Matter.js or, if you prefer Arcade Physics, check for overlap manually with a library like SAT.js.

3 Likes

Thanks for your answer !
So i’m giving a try to Matter.js but i can’t figure out (as with arcade physics) how to make the boy of my shape follow the shape movements.

For example, I added a matter JS body to my player object. The body keep the rotation but not the origin of the rotation ( in createPlayer function ). Am I doing something wrong ?

    <!DOCTYPE html>
    <html>

    <head>
        <meta charset="UTF-8">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.15.1/phaser.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: 'matter',
                    matter: {
                        gravity: {
                            y: 0
                        },
                        debug: true
                    }
                },
                scene: {
                    preload: preload,
                    create: create,
                    update: update,
                    render: render
                }
            };

            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)
                gameObj.matter.add.gameObject(player);
                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));
                    }
                });
            }

            function render(){

            }


        </script>

    </body>

    </html>