只为不想阅读大量文字的人添加此内容,至少阅读本文并查看图片以了解我的问题;
我在“玩家”和“物体”之间设置了碰撞,因此当“玩家”击中“物体”的“左”时,“玩家”被置于“物体”的“左”。 (这就是我要的)。但我希望玩家能够击中物体的任何一侧(“顶部”,“左侧”,“右侧”,“底部”)并进行适当放置。
所以看看上面的图像,基本上我试图在黑色方块和其他对象之间创建碰撞。黑色方块是“玩家”对象,灰色方块是数字“墙”对象,红色方块是“下一级”对象。
我已经完成了这个,但它有点混乱,当涉及到移动墙壁物体时,玩家碰撞不再像我希望的那样工作。
所以无论如何这里是我的“墙”代码:
var canvasWalls1 = document.getElementById('canvasWalls');
var ctxWalls1 = canvasWalls.getContext('2d');
var walls1 = new Walls1();
var imgSprite = new Image();
imgSprite.src = 'sprite.png';
imgSprite.addEventListener('load',init,false);
WallLeft.prototype.draw = function (){
ctxWalls1.drawImage(imgSprite,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
this.checkHitPlayer();
};
WallLeft.prototype.checkHitPlayer = function() {
if (this.drawX > player1.drawX &&
this.drawX <= player1.drawX + player1.width &&
this.drawY >= player1.drawY &&
this.drawY < player1.drawY + player1.height) {
player1.isUpKey = false;
player1.isDownKey = false;
player1.isRightKey = false;
player1.isLeftKey = false;
player1.drawX = this.drawX - player1.width - 0.05;
player1.drawY = this.drawY - 0.05; }
};
我刚刚为wall1,2,3,...等复制了相同的代码。我确信有更好的方法可以做到这一点,如果有人可以提出更好的方法吗?我尝试在两个不同的地方绘制相同的精灵,但无法弄清楚如何正确实现这一点。我有不同“墙”对象的主要原因是因为我需要根据“玩家”与“墙”对象碰撞的位置在不同的位置绘制“玩家”对象。
如果玩家从左侧飞入player1.drawX = walls1.drawX - player width
。
但如果玩家从顶部飞来,player1.drawY = walls1.drawY + player1.height
。
我需要所有碰撞能够在任何“墙”对象上发生的原因,是因为每当“玩家”对象到达“完成”时我就会重新使用所有“墙”对象。
如果我知道一个更好的系统,也许我可以继续使用我的碰撞系统。无论如何,当“玩家”击中“完成”对象时会发生什么:
Finish.prototype.checkHitPlayer = function() {
if (this.drawX >= player1.drawX &&
this.drawX <= player1.drawX + player1.width &&
this.drawY >= player1.drawY &&
this.drawY <= player1.drawY + player1.height) {
increaseLevel();
} };
function increaseLevel() {
Level+=1;
if (Level===2) {
drawlevel2(); }
function drawlevel2()
{
player1.drawX = 288;
player1.drawY = 160;
walls1.drawX = 448;
walls1.drawY = 160;
walls2.drawX = 416;
walls2.drawY = 320;
walls3.drawX = 192;
walls3.drawY = 288;
finish1.drawX = 224
finish1.drawY = 96;
}
我再次完成了“玩家”和“墙壁”之间的碰撞,但只是为每个“墙”创建了一个单独的功能,当我想在不同的地方画出“墙”时,它不起作用。 我很抱歉,如果这看起来很多,我试着只包括相关的代码。非常感谢任何帮助/建议。
答案 0 :(得分:1)
检测所有4个边的矩形碰撞
给定如下定义的矩形对象:
var player={x:0,y:0, w:20,h:20};
var barrier={x:100,y:100, w:50,h:50};
您可以使用此功能测试2个矩形是否从任何一侧发生碰撞
// return true if the 2 rectangles are colliding
function RectsColliding(r1,r2){
return !(r1.x>r2.x+r2.w || r1.x+r1.w<r2.x || r1.y>r2.y+r2.h || r1.y+r1.h<r2.y);
}
你可以这样调用这个函数:
// test if the player and barrier are colliding
if( RectsColliding(player,barrier){
console.log(‘BANG’);
}else{
console.log(‘Congrats…No collision’);
}
即使你有很多屏障对象,也很容易检查碰撞
var CollisionOccured=false;
for(var i=0;i<barriers.length;i++){
if(RectsColliding(desiredPlayer,barriers[i])){
CollisionOccured=true;
}
}
return(CollisionOccured);
这是代码和小提琴:http://jsfiddle.net/m1erickson/sJfbd/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var defaultFill="lightgray";
var defaultStroke="skyblue";
ctx.fillStyle=defaultFill;
ctx.strokeStyle=defaultStroke;
var player={x:0,y:0, w:20,h:20, fill:"black",stroke:"black"};
console.log(player.fill);
var barriers=[];
barriers.push({x:50 ,y:100, w:40,h:30});
barriers.push({x:200,y:230, w:20,h:20});
barriers.push({x:150,y:100, w:20,h:20});
barriers.push({x:150,y:200, w:20,h:20});
barriers.push({x:240,y:25, w:10,h:150});
drawAll();
function drawAll(){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<barriers.length;i++){
drawRect(barriers[i]);
}
drawRect(player,player.fill,player.stroke);
}
function drawRect(r,fill,stroke){
ctx.beginPath();
ctx.rect(r.x,r.y,r.w,r.h);
ctx.closePath();
ctx.fillStyle=fill||defaultFill;
ctx.fill();
ctx.strokeStyle=stroke||defaultStroke;
ctx.stroke();
}
function movePlayer(desiredMoveX,desiredMoveY){
// calculate where the player would like to be
var desiredPlayer={
x:player.x+desiredMoveX,
y:player.y+desiredMoveY,
w:player.w,
h:player.h,
fill:"black",
stroke:"black"
}
// to start, set the move to be allowed
var allowMove=true;
// check every barrier for collisions
for(var i=0;i<barriers.length;i++){
// if the desiredPlayer has collided with a barrier
// set the allowMove flag to false
if(RectsColliding(desiredPlayer,barriers[i])){
allowMove=false;
}
}
// if the move is allowed, return the desiredPlayer position
// if the move is not allowed, return the old player position
if(allowMove){
player=desiredPlayer;
player.stroke="black";
}else{
player.stroke="red";
}
// redraw the screen
drawAll();
}
// return true if the 2 rectangles are colliding
function RectsColliding(r1,r2){
return !(r1.x>r2.x+r2.w || r1.x+r1.w<r2.x || r1.y>r2.y+r2.h || r1.y+r1.h<r2.y);
}
$(document).bind("keydown",function(event) {
switch(event.which){
case 37:
movePlayer(-1,0);
break;
case 39:
movePlayer(1,0);
break;
case 38:
movePlayer(0,-1);
break;
case 40:
movePlayer(0,1);
break;
default:
break;
}
});
}); // end $(function(){});
</script>
</head>
<body>
<p>Use arrowkeys to move player (black box)</p>
<p>Player's outline will become red if hitting barrier</p>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
答案 1 :(得分:0)
您可以检查屏幕x / y坐标,以及每个可碰撞对象的高度和宽度。
如果你的对手x / y在一定的范围内,则应该触发碰撞。
(但这只适用于街区)
我找到了一个可能有帮助的小提琴:
答案 2 :(得分:0)
所以我想出了一个适合我想做的方法。我不能用类似的东西
(player1.x >= wall1.x && player1.Y===walls1.Y)
或类似的东西因为当它归结为在玩家的不同侧面上有4个物体时...玩家的X值必须高于墙壁而低于另一个。与Y值相同。 (这也使它变得不稳定。)无论如何,这里是我使用的:
Player.prototype.checkHitWall = function() {
this.TopY = this.drawY; this.BottomY = this.drawY + this.height; this.LeftX = this.drawX; this.RightX = this.drawX + this.width;
if (this.LeftX===walls1.x + walls1.width - 16 && this.drawY===walls1.y) //If player flys in from the RIGHT of wall1
{
player1.isUpKey = false; player1.isDownKey = false; player1.isRightKey = false; player1.isLeftKey = false;
upkey = false;
rightkey = false;
downkey = false;
leftkey = true;
this.drawX = walls1.x + walls1.width;
this.drawY = walls1.y;
然后我添加了一些功能,当玩家撞墙或游戏重启时,使leftkey = false。对于任何想知道-16的人来说,那是墙壁宽度的一半,所以玩家必须打到墙的中心才能放在墙边,因为我有fps(我猜不管怎样)你永远不会看到玩家进入墙体对象,所以看起来玩家看起来像是完美地击中墙壁。 -16的原因是当玩家试图左右移动时,墙壁完全位于玩家上方,墙壁不会发现碰撞。