gpt4 book ai didi

javascript - 如何正确地从每一侧(上、左、下、右)创建 2d 对象碰撞

转载 作者:行者123 更新时间:2023-11-28 02:04:47 26 4
gpt4 key购买 nike

只是为不想阅读一大堆文字的人添加此内容,至少阅读此内容并查看图片以理解我的问题;
我在“玩家”和“对象”之间设置了碰撞,这样当“玩家”击中“对象”的“左侧”时,“玩家”就会被放置到“对象”的“左侧”。 (这就是我要的)。但我希望玩家能够击中对象的任何一侧(“顶部”、“左侧”、“右侧”、“底部”)并适当放置。 Block collision example image所以看上面的图片,基本上我试图在黑色方 block 和其余物体之间创建碰撞。黑色方 block 是“玩家”对象,灰色方 block 是编号“墙”对象,红色方 block 是“下一级”对象。我已经完成了这一点,但它有点困惑,当涉及到移动墙壁对象时,玩家碰撞不再像我希望的那样起作用。所以无论如何,这是我的“墙”代码:

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,.. 等复制了相同的代码。我确信有更好的方法来做到这一点,如果有人可以建议更好的方法吗?我尝试在两个不同的地方绘制相同的 Sprite ,但不知道如何正确实现这一点。我有不同的“墙”对象的主要原因是因为我需要根据“玩家”与“墙”对象碰撞的位置在不同的位置绘制“玩家”对象。如果玩家从左侧飞入,player1.drawX = wall1.drawX - 玩家宽度。但如果玩家从顶部飞入,则player1.drawY = wall1.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;
}

我再次完成了“玩家”和“墙”之间的碰撞,但只是通过为每个“墙”创建一个单独的函数,当我想在不同的地方绘制“墙”时,这不起作用。如果这看起来需要阅读很多内容,我深表歉意,我尝试只包含相关代码。非常感谢任何帮助/建议。

最佳答案

检测所有 4 个侧面的矩形碰撞

enter image description here

给定如下定义的矩形对象:

var player={x:0,y:0, w:20,h:20};

var barrier={x:100,y:100, w:50,h:50};

您可以使用此函数来测试两个矩形是否从任意一侧发生碰撞

// 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);

这是代码和 fiddle :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>

关于javascript - 如何正确地从每一侧(上、左、下、右)创建 2d 对象碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17932679/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com