如何解决使用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 举报,一经查实,本站将立刻删除。