我的项目是创造一个游戏,应该在按键上跳,左右移动。我的问题是,我在游戏中实施的引力给我带来了一个问题。球被卡在地上,这是我画布底部的一张照片。我猜是因为错误的碰撞代码而卡住了。
问题是,如果你可以帮助我解决这个问题并且可能会提示如何继续,因为我试图找出哪个碰撞造成了这个问题,但我一无所获。
玩家碰撞所在的代码/其他代码正在工作,所以我不会把它们放在这里,只有你真的需要它们/
function Player(x, y) {
var size = 70;
GameObject.call(this, x, y, size);
this.img = document.getElementById("lopta");
this.rotation = 0;
this.dx = Math.random() * 50 - 25;
this.dy = Math.random() * 50 - 25;
}
// Dedi vlastnosti z GameObject
Player.prototype = Object.create(GameObject.prototype);
Player.prototype.move = function(dt) {
var x = this.x;
var y = this.y;
var sirka = canvas.width;
var vyska = canvas.height;
var bounce = 0.6;
// Gravitacia
this.dy += 9.8 * dt;
// Posun
if ( keys[37] ) {
this.rotation -= dt;
x-=5;
}
if ( keys[39] ) {
this.rotation += dt;
x+=5;
}
if ( keys[38] ) y-=5;
if ( keys[40] ) y+=5;
// Test novej pozicie
var collision = false;
for (i in scene) {
var obj = scene[i];
var test =
x -35>= obj.x + obj.size ||
x + this.size -35<= obj.x ||
y -35>= obj.y + obj.size ||
this.dy - 35 >= obj.dy + obj.size ||
y + this.size -35 <= obj.y ||
this.dy + this.size -35<= obj.dy;
if (!test) {
collision = true;
break;
}
}
// Posun bez kolizie
if (!collision) {
this.x = x;
this.y = y;
}
// Posun
//this.x += this.dx * dt;
this.y += this.dy * dt;
// podmienky aby lopta nevysla z hracieho pola cize z canvasu
if (this.x + this.size - 35> canvas.width) {
this.x = canvas.width - this.size +35;
}
if (this.x -35 < 0) {
this.x = 35;
}
if (this.y+this.size - 35 > canvas.height) {
this.y = canvas.height - this.size + 35;
this.dy *= -bounce;
if(this.dy * (-bounce) < 4)
this.dy = 0;
}
if (this.y - 35< 0) {
this.y = 35;
};
};
Player.prototype.draw = function() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.rotation);
ctx.translate(-35, -35);
//ctx.scale(this.size,this.size);
ctx.drawImage(this.img, 0, 0, this.size, this.size);
ctx.restore();
};
答案 0 :(得分:1)
首先,请原谅我没有完全理解你的要求。
如果您在检测球与球之间的碰撞时遇到问题砖块或球和球墙,这里有一些有用的实用功能:
// Given circle & rect definitions
var circle={x:50,y:50,r:25};
var rect={x:125,y:125,w:50,h:50};
// detect if circle & rect are colliding
function RectCircleColliding(circle,rect){
var distX = Math.abs(circle.x - rect.x-rect.w/2);
var distY = Math.abs(circle.y - rect.y-rect.h/2);
if (distX > (rect.w/2 + circle.r)) { return false; }
if (distY > (rect.h/2 + circle.r)) { return false; }
if (distX <= (rect.w/2)) { return true; }
if (distY <= (rect.h/2)) { return true; }
var dx=distX-rect.w/2;
var dy=distY-rect.h/2;
return (dx*dx+dy*dy<=(circle.r*circle.r));
}
// detect if circle is colliding with canvas sides
function CircleWallColliding(circle){
var cx=circle.x;
var cy=circle.y;
var r=circle.r;
if(cx-r<0 || cx+r>canvas.width || cy-r<0 || cy+r>canvas.height){return(true);}
return(false);
}
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
ctx.lineWidth=3;
var isDown=false;
var startX,startY;
var circle={x:50,y:50,r:25};
var rect={x:125,y:125,w:50,h:50};
$("#canvas").mousemove(function(e){handleMouseMove(e);});
draw('green');
function draw(circleFill){
ctx.clearRect(0,0,cw,ch);
ctx.fillStyle='blue';
ctx.fillRect(rect.x,rect.y,rect.w,rect.h);
ctx.beginPath();
ctx.arc(circle.x,circle.y,circle.r,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=circleFill;
ctx.fill();
ctx.stroke();
}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
circle.x=mouseX;
circle.y=mouseY;
var isColliding=RectCircleColliding(circle,rect)||CircleWallColliding(circle);
draw(isColliding?'red':'green');
}
// detect if circle & rect are colliding
function RectCircleColliding(circle,rect){
var distX = Math.abs(circle.x - rect.x-rect.w/2);
var distY = Math.abs(circle.y - rect.y-rect.h/2);
if (distX > (rect.w/2 + circle.r)) { return false; }
if (distY > (rect.h/2 + circle.r)) { return false; }
if (distX <= (rect.w/2)) { return true; }
if (distY <= (rect.h/2)) { return true; }
var dx=distX-rect.w/2;
var dy=distY-rect.h/2;
return (dx*dx+dy*dy<=(circle.r*circle.r));
}
// detect if circle is colliding with canvas sides
function CircleWallColliding(circle){
var cx=circle.x;
var cy=circle.y;
var r=circle.r;
if(cx-r<0 || cx+r>canvas.width || cy-r<0 || cy+r>canvas.height){return(true);}
return(false);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move ball with mouse.<br>Ball turns red if colling with rect or wall.</h4>
<canvas id="canvas" width=300 height=300></canvas>
答案 1 :(得分:0)
我注意到的一些事情。首先,您将碰撞运动逻辑与弹跳逻辑分开,这样球基本上可以直接穿过物体。据我所知,物体只能阻止手动移动。此外,所述手动移动忽略dt
,因此它的速度可能随帧速率而变化。
无论如何,在collision = true;
行上设置的断点显示了问题:您的一个场景对象没有设置大小,导致obj.x + obj.size
和obj.y + obj.size
到返回NaN
,就像无限。你有几个这样的,实际上:它是草的对象。
所以这里有你的选择:要么不让草成为场景的一部分(它不应该参与碰撞),而是改变渲染逻辑以使用单独的对象阵列。碰撞逻辑(有意义),或为草设置size = 0;
。