代码之家  ›  专栏  ›  技术社区  ›  Worker1432

如果球出界,如何使用p5.js和matter.js重置球的位置?

  •  1
  • Worker1432  · 技术社区  · 1 年前

    如果球飞离屏幕,或者如果球的位置。y<0(一旦弄清楚了这一点,我将添加其他边界条件)。

    我试着模拟一下,如果球飞出了,就把它移走(因为我找不到重置位置的方法)。

    但是,即使其他元素停止与圆碰撞,这也不会删除圆。它只是冻结了圆,我认为这是p5的问题。

    还有我的test-console.log语句,记录y坐标,保持无限记录y坐标。

    代码:

    这是鲍尔班。

    import Matter from 'matter-js'
    
    export default class Ball {
        constructor(x, y, r, world) {
            this.body = Matter.Bodies.circle(x, y, r);
            Matter.World.add(world, this.body);
            this.r = r;
        }
    
        show(p) {
            const pos = this.body.position;
            const angle = this.body.angle;
            p.push();
            p.translate(pos.x, pos.y);
            p.rotate(angle);
            p.rectMode(p.CENTER);
            p.fill("white");
            p.strokeWeight(0);
            p.circle(0, 0, this.r);
            p.pop();
        }
    }
    

    这是最后一个应用程序组件,所有内容都在其中渲染:

        import React, { useRef, useEffect } from 'react';
    import p5 from 'p5';
    import Matter from 'matter-js'
    import './App.css'
    import Ball from "./components/Ball.jsx";
    import Boundary from "./components/Boundary.jsx";
    
    let Engine = Matter.Engine;
    let World = Matter.World;
    let Mouse = Matter.Mouse;
    let MouseConstraint = Matter.MouseConstraint;
    let ground, box, ball, world, engine, mCon, leftWall, rightWall;
    
    function sketch(p) {
        p.setup = function() {
            const canvas = p.createCanvas(p.windowWidth, p.windowHeight);
            engine = Engine.create();
            world = engine.world;
    
            const canvasMouse = Mouse.create(canvas.elt);
            canvasMouse.pixelRatio = p.pixelDensity();
            const options = {
                mouse: canvasMouse,
            }
            mCon = MouseConstraint.create(engine, options);
    
            ground = new Boundary(p.width/2, p.height-10, p.width, 20, world);
            leftWall = new Boundary(10, p.height/2, 20, p.height, world);
            rightWall = new Boundary(p.width - 10, p.height/2, 20, p.height, world);
            ball = new Ball(50, p.height - 100, 25, world);
    
            World.add(world, [mCon,
            ]);
        }
    
        p.windowResized = function() {
            p.resizeCanvas(p.windowWidth, p.windowHeight);
        }
    
        p.draw = function () {
            p.background(51);
            Engine.update(engine);
            rightWall.show(p);
            leftWall.show(p);
            ground.show(p);
            ball.show(p);
    
            if (ball.body.position.y < 0) {
                console.log(ball.body.position.y);
                World.remove(world, ball.body);
            }
        }
    }
    
    function App() {
        const p5Container = useRef();
    
        useEffect(() => {
            const p5Instance = new p5(sketch, p5Container.current);
    
            return() => {
                p5Instance.remove();
            }
        }, []);
    
        return (
            <div ref={p5Container} className="container">
            </div>
        );
    }
    
    export default App;
    

    错误的证明

    你可以看到白色的球卡在顶部,不受重力的影响,y位置不断被记录。

    error demo

    我该如何着手解决这个问题?

    1 回复  |  直到 1 年前
        1
  •  1
  •   ggorlen Hoàng Huy Khánh    1 年前

    您正在从MJS世界中删除Matter.js实体,但您的Ball实例仍然存在,它也是 .body 属性,该属性仍然引用MJS主体。这个物体仍然以分离的状态存在,并且仍然可以用P5绘制。具有 World.remove() ,你已经把它从模拟中删除了,但没有从可视化中删除——这两者不同步。

    而不是 World.remove(world, ball.body); 尝试 Matter.Body.setPosition(ball.body, 50, p.height - 100) 把它移回原点,如果这是你的目标的话。您可能还想使用 setAngle , setVelocity setSpeed 以设置主体的默认值。

    也可以在进行时移除球,并在原点添加一个新球,方法与创建旧球相同:

    this.body = Matter.Bodies.circle(x, y, r);
    Matter.World.add(world, this.body);
    

    这可能是Ball类中的一个方法,您可能需要 x y 上的属性 this. 喜欢 this.originalX , this.originalY ,所以您可以在构造函数之外引用它们。

    顺便说一句, World 已弃用,取而代之的是 Matter.Composite .