简体   繁体   中英

How to use X and Y positions of a Sprite for “Fling” physics in Phaser 3?

I am making a game using Phaser 3, specifically the Matter physics engine. I am trying to follow this tutorial on fling physics https://www.emanueleferonato.com/2019/03/08/fling-unity-game-built-in-html5-with-phaser-and-matter-js-updated-with-the-latest-constraints-tweaks-fly-through-the-screen-with-your-ninja-rope/

let game;
let gameOptions = {
    gravity: 1,
    constraintSpeed: 2,
    hookSpeed: 20,
    ropeTolerance: 6
};
const BALL = 1;
const HOOK = 2;

window.onload = function() {

    let gameConfig = {
        type: Phaser.AUTO,
        scale: {
            mode: Phaser.Scale.FIT,
            autoCenter: Phaser.Scale.CENTER_BOTH,
            parent: "thegame",
            width: 1200,
            height: 750
        },
        scene: playGame,
        physics: {
            default: "matter",
            matter: {
                gravity: {
                    y: gameOptions.gravity
                },
                debug: true
            }
        }
    }
    game = new Phaser.Game(gameConfig);
    window.focus();
};
class playGame extends Phaser.Scene{
    constructor(){
        super("PlayGame");
    }
    preload() {
        //Load background image
        this.load.image('background', 'images/background.png');

        this.load.atlas('sheet', 'assets/spiderTP.png', 'assets/spiderTP.json');
        this.load.json('shapes', 'assets/spritesPE.json');
    }
    create() {
        //Place background image
        let background = this.add.image(600, 375, 'background');

        //Update the game at 30Hz
        this.matter.world.update30Hz();

        //Get hitboxes
        var shapes = this.cache.json.get('shapes');

        //Set boundaries for physics
        this.matter.world.setBounds(0, 0, game.config.width, 800);

        //Player
        this.hero = this.matter.add.sprite(600, 500, 'sheet', '0001', {shape: shapes.s0001})
        this.hero.label = BALL;
        this.hook = null;

        //Fire the hook
        this.input.on("pointerdown", this.fireHook, this);

        this.rope = null;

        //Listen for collisions with the hook
        this.matter.world.on("collisionstart", function(e, b1, b2){
            if((b1.label == HOOK || b2.label == HOOK) && !this.rope) {
                Phaser.Physics.Matter.Matter.Body.setStatic(this.hook, true);
                let distance = Phaser.Math.Distance.Between(this.hero.body.position.x, this.hero.body.position.y, this.hook.position.x, this.hook.position.y);

                if (distance > gameOptions.heroSize * 2) {
                    this.rope = this.matter.add.constraint(this.hero, this.hook, distance, 0.1);
                }
            }
        }, this);
    }

    fireHook(e) {
        if(this.hook) {
            this.releaseHook();
        }
        else {
            let angle = Phaser.Math.Angle.Between(this.hero.body.position.x, this.hero.body.position.y, e.position.x, e.position.y);

            this.hook = this.matter.add.rectangle(this.hero.body.position.x + 40 * Math.cos(angle), this.hero.body.position.y + 40 * Math.sin(angle), 10, 10);
            this.hook.label = HOOK;

            Phaser.Physics.Matter.Matter.Body.setVelocity(this.hook, {
                x: gameOptions.hookSpeed * Math.cos(angle),
                y: gameOptions.hookSpeed * Math.sin(angle)
            });
        }
    }

    releaseHook() {
        if(this.rope) {
            this.matter.world.removeConstraint(this.rope);
            this.rope = null;
        }
        if(this.hook){
            this.matter.world.remove(this.hook);
            this.hook = null;
        };
    }
    update() {
        // is there a constraint? Shrink it
        if(this.rope){
            this.rope.length -= gameOptions.constraintSpeed;
            let hookPosition = this.hook.position;
            let distance = Phaser.Math.Distance.Between(hookPosition.x, hookPosition.y, this.hero.body.position.x, this.hero.body.position.y);
            if(distance - this.rope.length > gameOptions.ropeTolerance){
                this.rope.length = distance;
            }
            this.rope.length = Math.max(this.rope.length, gameOptions.heroSize * 2);
        }
    }
}

EDIT- I am getting closer. Now there are no errors, however, no ropes are shot

You can get the sprite position X & Y like so:

hero.body.position.x
hero.body.position.y

Let's look at this.hero .

"Cannot read property 'x' of undefined" means that the property stated before the x in this.hero.position.x is not found, and probably does not exist in its parent property. In this case, this.hero does not contain the position property.

We can see the property of this.hero by typing it in the console while the code is running:

this.hero 的属性

You can see that position does not exist as an accessible property.

In your case, you need to use the body property.

在此处输入图像描述

This property includes the position property that includes the x and y coordinates.

So as a conclusion, access the x and y coordinates of this.hook with the following lines:

this.hero.body.position.x
this.hero.body.position.y

(this answer is in response to the first revision of this question)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM