在画布,javascript的重力/跳跃球

时间:2015-04-05 14:42:24

标签: javascript html5 canvas gravity

我的项目是创造一个游戏,应该在按键上跳,左右移动。我的问题是,我在游戏中实施的引力给我带来了一个问题。球被卡在地上,这是我画布底部的一张照片。我猜是因为错误的碰撞代码而卡住了。

问题是,如果你可以帮助我解决这个问题并且可能会提示如何继续,因为我试图找出哪个碰撞造成了这个问题,但我一无所获。

该游戏的链接位于:Game JSFiddle:Fiddle

玩家碰撞所在的代码/其他代码正在工作,所以我不会把它们放在这里,只有你真的需要它们/

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

    };

2 个答案:

答案 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.sizeobj.y + obj.size到返回NaN,就像无限。你有几个这样的,实际上:它是草的对象。

所以这里有你的选择:要么不让草成为场景的一部分(它不应该参与碰撞),而是改变渲染逻辑以使用单独的对象阵列。碰撞逻辑(有意义),或为草设置size = 0;