1. 创建P2物理项目一p2.js物理引擎详细教程

本文介绍如何使用P2物理引擎创建物理应用,包括创建world、shape、body的步骤,以及如何利用Egret等HTML渲染引擎展示物理模拟效果。详细解释了world、shape、body的概念及其在P2中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 创建P2物理项目:

  • 使用P2物理引擎创建物理应用的过程和Box2D类型,步骤是:创建world、创建shape、创建body刚体、实时调用step()函数更新物理模拟计算;基于形状、刚体使用Egret或其他HTML渲染以显示物理模拟效果。 
  • 1)世界world:

    • world是P2物理引擎入口,对应World类,用于承载所有物理模拟对象。world类的构造函数为: 
// 创建世界构造函数
function World([options]){options?:{gravity?:number[]=[0,-9.81];}} 
# 其中,gravity是重力加速度,这是一个Vec2类型的向量对象,默认为垂直向上的向量[0,-9.81]。将gravity设置为[0,0]可以取消重力,模拟太空失重状态。 
  • 2)形状Shape:

    • 形状是物理模拟计算的基础。任何物体都要有对应的形状,才可以基于P2进行物理碰撞检测和模拟。所有形状对象都需要通过addShape()添加到刚体中,才可以进行碰撞模拟计算: 

 


// 创建一个刚体
var body:p2.Body=new p2.Body(); 
// 创建一个形状
var shape:p2.Shape=new p2.Shape(); 
// 形状添加到刚体中
body.addShape(shape); 
# P2中的Shape类是一个抽象的父类,要使用Box、Circle等子类。
 
  • 3)刚体Body:

    • 刚体是P2物理引擎的核心概念和对象,拥有速度、角度、质量等物理属性,同时包含了形状对象,使刚体拥有具体的形状。将刚体添加到world中,World将以刚体为单位循环遍历,进行物理模拟计算,并将模拟的结果保存在刚体属性中,使刚体成为碰撞对象的原型。所有的刚体都必须通过addBody()添加到P2的world中,才会进行物理模拟: 
// 创建一个刚体
var body:p2.Body=new p2.Body(); 
// 创建一个形状
var shape:p2.Shape=new p2.Shape(); 
// 形状添加到刚体中
body.addShape(shape); 
// 刚体添加到世界中
world.addBody(body); 
  • 4)贴图Egret:

    • P2只是一个算法库,以刚体为对象模型,模拟并输出物理碰撞、运动结果。这个过程通过持续调用world中的step()方法来实现: 

// 通过持续调用world中的step()方法来实现以刚体为对象模型,模拟并输出物理碰撞、运动结果
function step(dt:number,  timeSinceLastCalled?:number=0,  maxSubSteps?:number=10) 
// dt: step方法执行的时间间隔,单位秒,通常取值为游戏帧频的倒数; 
// timeSinceLastCalled: 当游戏帧频降低时计算两帧之间的时间差作为参数值,此时P2会在一次step()中进行count= timeSinceLastCalled/dt次计算,以保证物理模拟的真实性,默认值为0;
// maxSubSteps: 单次step()进行物理模拟计算的最大次数,当timeSinceLastCalled不等于0时,单次step()中进行计算的次数count最大为maxSubSteps,默认值为10。 
    • 但P2本身不具备渲染功能,无法显示模拟结果,需要借助JavaScript渲染引擎,如Egret、Cocos2d-js、Pixi、phaser等,通过绘制或贴图来渲染物理模拟结果。在Egret中的简单示例: 
class SampleP2APP extends egret.DisplayObjectContainer{ 
    public constructor(){ 
        super(); 
        this.createP2App(); 
    } 
    private world:p2.World; 
    private factor:number=30; 
    public createP2App():void{ 
        // 创建了一个重力加速度gravity=[0,0]的失重环境world;
        this.world=new p2.World(); 
        var world=this.world; 
        world.gracity=[0,0]; 
        // 使用Box形状创建尺寸100x50像素矩形;
        var shape:p2.Box=new p2.Box({width:100/this.factor, height:50/this.factor}); 
        var body:p2.Body=new p2.Body({mass:1}); 
        // 通过addShape()方法将其添加到位于(275,100)位置的刚体body中;
        body.position=[275/this.factor, 100/this.factor]; 
        body.addShape(shape); 
        // 通过world的addBody()方法将刚体添加到世界中,完成一个基本的P2物理应用创建。
        world.addBody(body); 
        this.addEventListener(egret.Event.ENTER_FRAME, this.loop, this); 
    } 
    // 在游戏的loop更新方法中,每帧持续调用step()方法,实现P2物理模拟计算的持续更新。 
    private loop(e.egret.Event):void{ 
        this.world.step(1/60); 
    } 
} 
// 代码中创建了一个重力加速度gravity=[0,0]的失重环境world;
// 然后使用Box形状创建尺寸100x50像素矩形;
// 通过addShape()方法将其添加到位于(275,100)位置的刚体body中;
// 最后通过world的addBody()方法将刚体添加到世界中,完成一个基本的P2物理应用创建。在游戏的loop更新方法中,每帧持续调用step()方法,实现P2物理模拟计算的持续更新。 
​
// P2物理引擎中的坐标单位是米,而大部分的游戏引擎在屏幕上渲染游戏时,都是基于像素的,所以在创建刚体对象、设置形状尺寸时,需要将像素转换成米后再进行赋值。游戏中,1米通常看作30px,所以代码中声明了一个值为30的factor变量,在设置形状尺寸或刚体时,都是使用像素坐标除以factor变量,转换成米之后再赋值的。

本文整理自: http://www.dwenzhao.cn/profession/netbuild/egretp2.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值