Javascript 我正在制作一个Atari突破克隆&我想知道如何判断球是否击中了街区的某一侧
我已经得到了当球与块体碰撞时,它会删除块体的部分,但我也想知道球是否击中块体的顶部或底部或左侧或右侧,并相应地反弹。我试过了,但效果不太好。它只是在跳来跳去。我已经从下面的代码中删除了该部分,因为它不起作用。有人能帮我解决这个问题吗?也许可以举个例子或者告诉我它是如何工作的Javascript 我正在制作一个Atari突破克隆&我想知道如何判断球是否击中了街区的某一侧,javascript,html,arrays,canvas,Javascript,Html,Arrays,Canvas,我已经得到了当球与块体碰撞时,它会删除块体的部分,但我也想知道球是否击中块体的顶部或底部或左侧或右侧,并相应地反弹。我试过了,但效果不太好。它只是在跳来跳去。我已经从下面的代码中删除了该部分,因为它不起作用。有人能帮我解决这个问题吗?也许可以举个例子或者告诉我它是如何工作的 <canvas id="can" height="500" width="1000"></canvas> var c = document.getElementById("can"
<canvas id="can" height="500" width="1000"></canvas>
var c = document.getElementById("can");
var ctx = c.getContext("2d");
var blocks= [];
var paddle = {x:450,y:480,h:10,w:100};
var ball = {r:7,x:500,y:469};
var rows=[0,1,2,3,4];
var px = paddle.x, py = paddle.y;
var pxv=0;
var by = ball.y, bx = ball.x;
var bxv = -1.5, byv = -1.5;
function Block(h,w,x,y,c) {
this.h = h;
this.w = w;
this.x = x;
this.y = y;
this.c = c;
}
for(var i =0, len=rows.length;i<len;i++){
for(var j=0; j<20;j++) {
blocks.push(new Block(20,50,j*50,i*20,rows[i]))
}
}
document.addEventListener("keydown",keyPush);
document.addEventListener("keyup",keyRelease);
function keyRelease(evt) {
switch(evt.keyCode) {
case 37:
pxv=0;
break;
case 39:
pxv=0;
break;
}
}
function keyPush(evt) {
switch(evt.keyCode) {
case 37:
pxv=-5;
break;
case 39:
pxv=5
break;
}
}
function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
return ax < bx+bw && bx < ax+aw && ay < by+bh && by < ay+ah;
};
function draw(){
ctx.clearRect(0,0,1000,500)
bx+=bxv;
by+=byv;
px+=pxv;
if(px > 900) {
px = 900;
}
else if(px < 0) {
px = 0;
}
for(var i = 0, len=blocks.length;i<len;i++) {
var bl = blocks[i];
if(AABBIntersect(bx,by,ball.r,ball.r,bl.x,bl.y,bl.w,bl.h)) {
blocks.splice(i,1);
i--;
len--;
}
}
if(bx < 0) {
bxv = bxv*-1;
}
if(bx > 1000) {
bxv = bxv*-1;
}
ctx.fillStyle = "#ff4b38"
ctx.fillRect(px,py,paddle.w,paddle.h);
for(var i = 0, len=blocks.length; i<len; i++){
if(blocks[i].c === 0) {
ctx.fillStyle = "#ff4b38"
}
else if(blocks[i].c === 1) {
ctx.fillStyle = "#ffba19"
}
else if(blocks[i].c === 2) {
ctx.fillStyle = "#fcee25"
}
else if(blocks[i].c === 3) {
ctx.fillStyle = "#26db02"
}
else if(blocks[i].c === 4) {
ctx.fillStyle = "#2d69ff"
}
ctx.fillRect(blocks[i].x,blocks[i].y,blocks[i].w,blocks[i].h);
ctx.beginPath();
ctx.arc(bx,by,ball.r,0,2*Math.PI,false);
ctx.fillStyle = "gray";
ctx.fill();
}
}
setInterval(draw,10);
我相信有更多的方法可以做到这一点,但我会这样做 在碰撞检测函数中,您应该有if语句来检测是否从x或y侧进行。您需要对其进行调整,因为不确定稍后是否会出错,但其主要影响如下:
function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
var bool = ax < bx + bw && bx < ax + aw && ay < by + bh && by < ay + ah;
if(bool){
if(ax == bx || ax == bx + bw){
bxv *= -1;
cl("x");
}else{
byv *= -1;
cl("y");
}
}
return bool;
};
我也会把你的设定时间间隔放在一个var上,这样你可以在所有的挡块都没了或者你的球在桨下面的时候清除它。否则它就会无限地到处传播 你的碰撞检测在哪里?啊?是的。它是draw函数之外的函数。
if(bx >= px && bx <= px + paddle.w && by >= py && by <= py + paddle.h){
byv *= -1;
}