微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Matter.js和传感器进行碰撞检测

如何解决使用Matter.js和传感器进行碰撞检测

我正在尝试在p5js和something.js中开发一个包含壁(静态矩形)和播放器(非静态矩形)的小游戏。

我想知道玩家何时站在这些墙壁(或其他静态物体)上,因此我在玩家矩形下方创建了一个传感器,并使用“ collisionActive”事件来了解静态物体之间是否存在碰撞墙壁和播放器传感器。不幸的是,检测不稳定。

我希望有一个基于事件的解决方案(如果可能,不要创建自己的函数),该解决方案可以连续检测玩家是否在地面上。

sketch.js:

var World = Matter.World;
var Bodies = Matter.Bodies;
var Body = Matter.Body;
var Detector = Matter.Detector;
var Events = Matter.Events;
var Constraint = Matter.Constraint;

var engine = Engine.create();
var myWorld;
var wall1,wall2;
var player;

var PLAYER_ID = 0x0001;
var WALL_ID = 0x0002;
var PLAYER_JUMPSENSOR_ID = 0x0020;

function setup() {
 createCanvas(400,400);
//  engine = Engine.create();
 myWorld = engine.world;
 Engine.run(engine);
 
 player = new Player(100,100,10,20);
 
 wall1 = new Wall(width/2,height-5,width,10);
 wall2 = new Wall(width/4,height/2,width/3,20);
}

Events.on(engine,'collisionActive',function(event) {
 var pairs = event.pairs;
 
 pairs.forEach(function(obj){
   if (obj.bodyA.isSensor || obj.bodyB.isSensor) {
     if (player.isPlayerOnGround(obj.bodyA,obj.bodyB)) {
       console.log("the player is on the ground");
     }
   }
 })
});

function draw() {
 background(51);
 
 Engine.update(engine);
 player.update();
 
 wall1.show();
 wall2.show();
 player.show();
}

player.js:

  //PLAYER BODY
  var options1 = {
    friction: 0.9,frictionAir: 0.05,restitution: 0,inertia: 10,inverseInertia: 0.1,mass: 0.1,inverseMass: 10,groupId: PLAYER_ID,collisionFilter: {
      category: PLAYER_ID
    }
  };
  this.body = Bodies.rectangle(x,y,w,h,options1);
  this.grapple = null;
  this.w = w;
  this.h = h;
  World.add(myWorld,this.body);
  
  //PLAYER SENSOR
  var options2 = {
    isSensor: true,groupId: PLAYER_JUMPSENSOR_ID,};
  
  this.playerSensorBody_x = this.body.position.x;
  this.playerSensorBody_y_offset = this.h/2 + 1;
  this.playerSensorBody_y = this.body.position.y + this.playerSensorBody_y_offset;
  this.playerSensorBody_w = this.w - 2;
  this.playerSensorBody_h = 1;
  this.playerSensorBody = Bodies.rectangle(this.playerSensorBody_x,this.playerSensorBody_y,this.playerSensorBody_w,this.playerSensorBody_h,options2);
  World.add(myWorld,this.playerSensorBody);

  this.moveLeft = function() {
    Body.setVeLocity(this.body,{x: -2,y: this.body.veLocity.y});
  };
  
  this.moveRight = function() {
    Body.setVeLocity(this.body,{x: 2,y: this.body.veLocity.y});  
  };
  
  this.jump = function() {
    Body.setVeLocity(this.body,{x: this.body.veLocity.x,y: -3});
    this.jump_height -= 3;
  };
  
  this.isPlayerOnGround = function(a,b) {
      return ((a.groupId == WALL_ID && b.groupId == PLAYER_JUMPSENSOR_ID) || (a.groupId == PLAYER_JUMPSENSOR_ID && b.groupId == WALL_ID));
  };
  
  this.updateSensor = function() {    
    this.playerSensorBody_x = this.body.position.x;
    this.playerSensorBody_y = this.body.position.y + this.playerSensorBody_y_offset;
    Body.setPosition(this.playerSensorBody,{x: this.playerSensorBody_x,y: this.playerSensorBody_y});
  }
  
  this.update = function() {
    //Handle left right movements
    if (keyIsDown(81)) {
      this.moveLeft();
    } else if (keyIsDown(68)) {
      this.moveRight();
    } 
    
    //Handle jump
    if (keyIsDown(32)) {
      this.jump();
    }   
    this.updateSensor();
  }
  
  this.show = function() {
    if (this.grapple != null) {
      this.grapple.update();
    }
    if (this.grapple != null) {
      this.grapple.show();  
    }
    Body.setAngle(this.body,0);
    var pos = this.body.position;
    var angle = this.body.angle;
    push();
    translate(pos.x,pos.y);
    rotate(angle);
    rectMode(CENTER);
    strokeWeight(1);
    stroke('black');
    fill('green');
    rect(0,this.w,this.h);
    pop();
    
    var pos2 = this.playerSensorBody.position;
    push();
    translate(pos2.x,pos2.y);
    rectMode(CENTER);
    strokeWeight(1);
    stroke('white');
    rect(0,this.playerSensorBody_h);
    pop();
  }
}

wall.js:

  var options = {
    friction: 0,isstatic: true,groupId: WALL_ID
  };
  this.body = Bodies.rectangle(x,options);
  this.w = w;
  this.h = h;
  World.add(myWorld,this.body);
  
  this.show = function() {
    var pos = this.body.position;
    push();
    translate(pos.x,pos.y);
    rectMode(CENTER); 
    strokeWeight(1);
    stroke('black');
    fill('brown');
    rect(0,this.h);
    pop();
  }
}

感谢您的投入

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。