我试图让我的玩家在另一个玩家周围移动,在X轴上似乎没问题,但Y轴无法正常工作。就像我希望它检测“边界”一样,就好像它是一个块一样,我想阻止玩家与敌人重叠......
if ((87 in keysDown) && player.y > 0) {
if ((player.x < player2.x -50 || player.x > player2.x+50))
if( player.y < player2.y+50){
player.y -= player.speed;
}
}
答案 0 :(得分:2)
阻止元素移动到地图/舞台之外
// After new x and y are set:
this.x = Math.min(Math.max(0,this.x), Stage.w-this.w);
this.y = Math.min(Math.max(0,this.y), Stage.h-this.h);
// Where `this` is the moving element and `Stage` is the game area.
function collision(A, B) {
return !(((A.y+A.h)<(B.y))||(A.y>(B.y+B.h))||((A.x+A.w)<B.x)||(A.x>(B.x+B.w)));
}
使用类似:
if( collision(Player,Enemy) ) {
// explodePlayer(); // or whatever, they collided!
}
如果您不想要被动碰撞检测,而是要解决移动玩家的碰撞:
function resolveCollision(A, B) {
// get the vectors to check against
var vX = (A.x + (A.w / 2)) - (B.x + (B.w / 2)),
vY = (A.y + (A.h / 2)) - (B.y + (B.h / 2)),
// Half widths and half heights of the objects
ww2 = (A.w / 2) + (B.w / 2),
hh2 = (A.h / 2) + (B.h / 2),
colDir = "";
// if the x and y vector are less than the half width or half height,
// they we must be inside the object, causing a collision
if (Math.abs(vX) < ww2 && Math.abs(vY) < hh2) {
// figures out on which side we are colliding (top, bottom, left, or right)
var oX = ww2 - Math.abs(vX),
oY = hh2 - Math.abs(vY);
if (oX >= oY) {
if (vY > 0) {
colDir = "TOP";
A.y += oY;
} else {
colDir = "BOTTOM";
A.y -= oY;
}
} else {
if (vX > 0) {
colDir = "LEFT";
A.x += oX;
} else {
colDir = "RIGHT";
A.x -= oX;
}
}
}
return colDir; // If you need info of the side that collided
}
使用类似:
resolveCollision(Player, Enemy);
或:
var res = resolveCollision(Player, Enemy);
console.log( res ); // "TOP", "BOTTOM"... (the side that collided uppercase)
// Collision boolean (useful for passive collision detection)
function collision(A, B) {
return !(((A.y+A.h)<(B.y))||(A.y>(B.y+B.h))||((A.x+A.w)<B.x)||(A.x>(B.x+B.w)));
}
// Resolve collision
function resolveCollision(A, B) {
// get the vectors to check against
var vX = (A.x + (A.w / 2)) - (B.x + (B.w / 2)),
vY = (A.y + (A.h / 2)) - (B.y + (B.h / 2)),
// Half widths and half heights of the objects
ww2 = (A.w / 2) + (B.w / 2),
hh2 = (A.h / 2) + (B.h / 2),
colDir = "";
// if the x and y vector are less than the half width or half height,
// they we must be inside the object, causing a collision
if (Math.abs(vX) < ww2 && Math.abs(vY) < hh2) {
// figures out on which side we are colliding (top, bottom, left, or right)
var oX = ww2 - Math.abs(vX),
oY = hh2 - Math.abs(vY);
if (oX >= oY) {
if (vY > 0) {
colDir = "TOP";
A.y += oY;
} else {
colDir = "BOTTOM";
A.y -= oY;
}
} else {
if (vX > 0) {
colDir = "LEFT";
A.x += oX;
} else {
colDir = "RIGHT";
A.x -= oX;
}
}
}
return colDir;
}
// Elements
var cvs= document.createElement("canvas"),
ctx= cvs.getContext("2d"),
EL_collisionInfo = document.getElementById("collisionInfo");
// Game variables
var Stage = {
w: 300,
h: 200
},
Keys = {},
Player = {
x: 0,
y: 0,
w: 30,
h: 30,
color: "blue",
velocity: 4,
move: function() {
if(Keys[65]) { // A
this.x -= this.velocity;
}
if(Keys[87]) { // W
this.y -= this.velocity;
}
if(Keys[68]) { // D
this.x += this.velocity;
}
if(Keys[83]) { // S
this.y += this.velocity;
}
// General Collision / Touching
var orgColor = "";
if(collision(this, Enemy)) {
this.color = "red";
} else { // not colliding
this.color = "blue";
}
// Resolve collision
var coll = resolveCollision(this, Enemy);
// And write info on screen
EL_collisionInfo.innerHTML = coll;
// Prevent go out of Stage
this.x = Math.min(Math.max(0,this.x), Stage.w-this.w);
this.y = Math.min(Math.max(0,this.y), Stage.h-this.h);
}
},
Enemy = {
x: 130,
y: 80,
w: 50,
h: 50,
color: "red"
};
// INIT canvas and size
document.body.appendChild(cvs);
cvs.width = Stage.w;
cvs.height = Stage.h;
function canvasDraw( el ) {
ctx.beginPath();
ctx.fillStyle = el.color;
ctx.fillRect(el.x, el.y, el.w, el.h);
}
// /////
// KEYBOARD LISTENERS
document.addEventListener("keydown", function(e){
Keys[e.which] = 1;
}, false);
document.addEventListener("keyup", function(e){
delete Keys[e.which];
}, false);
// /////
// ENGINE
(function engine() {
Player.move();
// Clear canvas and draw
ctx.clearRect(0, 0, cvs.width, cvs.height);
canvasDraw( Player );
canvasDraw( Enemy );
window.requestAnimationFrame( engine );
}());
*{box-sizing:border-box; -webkit-box-sizing:border-box;}
html, body{height:100%; margin:0; font:16px/20px sans-serif;}
canvas{background: #eee;}
#collisionInfo{position:absolute;}
WASD to move<br>
<p id="collisionInfo"></p>