Control ball movement in matter physics

Hi,

I am doing a failing balls game and want to contol final destination of each ball( e.g. slot 1, 2 or 3). So everything should looks like they falling down natively.

Examples


I tried to set velocityX on each collision, but its often goes into wrong direction.
Any ideas how to do that ?

var config = {
            type: Phaser.AUTO,
            width: 480,
            height: 605,
            backgroundColor: '#cecece',
            parent: 'phaser-container',
            physics: {
                
                default: 'matter',
                matter: {
                    enableSleeping: true,
                    debug: true,
                }
            },
            scene: {
                preload: preload,
                create: create
            }
        };

function create() {

            this.options = {
                plinkoCols: 6,
                plinkoRows: 11,

                ballCount: 5,

                dropArea: {
                    x: 90,
                    y: 110,
                    width: 304,
                    height: 476
                },
                ItemGrid: {
                    X: 130,
                    Y: 120,
                    ItemSpacingX: 44,
                    ItemSpacingY: 15,
                    NumColumns: 5
                },
                PrizesGrid: {
                    X: 78,
                    Y: 536,
                    ItemSpacingX: 110,
                    ItemSpacingY: 0,
                    NumColumns: 3
                }

            };


            var dropArea = this.options.dropArea;
            this.matter.world.setBounds(dropArea.x, dropArea.y, dropArea.width, dropArea.height, 32, true, true, false, true);


            for (var i = 0; i < this.options.PrizesGrid.NumColumns; i++) {

                var row = Math.floor(i / this.options.PrizesGrid.NumColumns);
                var column = i % this.options.PrizesGrid.NumColumns;
                var xPos = this.options.PrizesGrid.X + column * this.options.PrizesGrid.ItemSpacingX;
                var yPos = this.options.PrizesGrid.Y + row * this.options.PrizesGrid.ItemSpacingY;

                if (i !== 0) {
                    var sprite = this.matter.add.image(xPos, yPos, 'bottomSplitor', null, { isStatic: true });
                    sprite.setOrigin(0.5, 0.5);
                }
            }

            //  Add in a stack of balls
            var plinkoRadius = 4;

            this.pins = [];
            
            var width = this.options.dropArea.width / this.options.plinkoCols;
            for (var y = 0; y < this.options.plinkoRows - 1; y++) {
                var yPos = this.options.dropArea.y + 20 + (y + 1) * 32;
                for (var i = 0; i < this.options.plinkoCols - 1; i++) {
                    var xPos = (i + 1) * width + this.options.dropArea.x + y % 2 * width / 2 - plinkoRadius - 10;
                    var pin = this.matter.add.image(xPos, yPos, 'pin');
                    pin.setCircle();
                    pin.setStatic(true);
                    pin.body.label = 'pin';
                    pin.body.column = i;
                    pin.body.row = y;
                    this.pins.push(pin);
                }
            }

            this.balls = [];

            for (var i = 0; i < this.options.ballCount; i++) {
                var column = i % (this.options.ItemGrid.NumColumns + 1);
                var xPos = this.options.ItemGrid.X + column * this.options.ItemGrid.ItemSpacingX + this.options.ItemGrid.ItemSpacingX / 2;
                var ball = this.matter.add.image(xPos, this.options.ItemGrid.Y + this.options.ItemGrid.ItemSpacingY / 2, 'ball' + i);
                
                ball.setCircle();
                ball.setFriction(0.005);
                ball.setBounce(0.5 * Math.random() + 0.1);
                console.log(ball.body.restitution);
                ball.setToSleep();
                ball.body.label = 'ball';
                this.balls.push(ball);
            }

            var self = this;

            var r1 = this.add.rectangle(0, 0, 130, 130, 0x6666ff);
            r1.setInteractive();
            r1.on('pointerup', function () {
                for (var i = 0; i < self.balls.length; i++) {
                    var ball = self.balls[i];
                    ball.setAwake();
                    //break;
                }
            });
}

matter handles physics for you. so, normaly u wont have to change the “direction” if your game objects “falls” .
You have to set a y-gravity for your scene (i belive it defaults to 1 on y). Your game-objects should have a “mass” and “air-friction” set
And thats it.
If u change the x-Velocity on your own, u “overwrite” the physics logic.

Look at this example (i belive u allready did):

If i past your code in this example and it works ( i set circle to 6 because i dont know your image size :slight_smile: )

I saw these examples. I would like to control ange and direction of movement after “Collision start”.


body.frictionAir
body.setMass()

Can’t do this.

Hm.
i’m using this in my code:

// in create method
        this.matter.world.on("collisionstart", this.collisionDetection );
        this.matter.world.on("collisionactive", this.collisionDetection );

The collision detection:

    collisionDetection( event, bodyA, bodyB ){
        event.pairs.forEach( pair => {

than i check the objects and change some settings on the body depending on the collition (i for example use some “slowdown” effects).
Each element in my game is a custom class element

class Hero extends Phaser.Physics.Matter.Sprite{ 

there i overwrite the “update” method to change some body effects.
Maybe it could also be good to overwrite the “preupdate” method so your changes can take effect in the physics calculation.

    update( time, delta) {

            this.setVelocityX( - speed );

        super.update( time, delta);
    }

u need to set the “group” updateChild option:

        this.heros = new Phaser.GameObjects.Group( this, [], { runChildUpdate: true });