将图像添加到移动和碰撞的圆圈

时间:2013-09-02 14:57:21

标签: javascript html5 canvas three.js

我目前有一堆球(圆圈)在盒子里弹跳并相互碰撞。

现在他们现在是纯绿球。但是我想用这个圈子的图像。

我该怎么做?这是我的渲染功能。

  function render() {
  var ball;
  context.fillStyle = "#008800";
  for (var i = 0; i <balls.length; i++) {
     ball = balls[i];
     ball.x = ball.nextx;
     ball.y = ball.nexty;
     context.beginPath();
     context.arc(ball.x,ball.y,ball.radius,0,Math.PI*2,true);
     context.closePath();
     context.fill();
  }

有什么想法吗?可能吗?如果没有,是否有其他方法可以实现弹跳和碰撞球的图像?

2 个答案:

答案 0 :(得分:0)

结帐drawImage功能。这允许您在画布上的坐标点绘制图像。它需要一个Image实例作为它的第一个参数和各种其他位置和裁剪值。引用上面链接的MDN页面:

  

drawImage(image, dx, dy, dw, dh, sx, sy, sw, sh)

     

图片   吸引上下文的元素;规范允许任何图像元素(即<img><canvas><video>)。某些浏览器(包括Firefox)允许您使用任意元素。

     

dx 目标画布中放置源图像左上角的X坐标。

     

dy 目标画布中Y坐标,用于放置源图像的左上角。

     

dw 在目标画布中绘制图像的宽度。这允许缩放绘制的图像。如果未指定,则图像不是   绘制时按宽度缩放。

     

dh 在目标画布中绘制图像的高度。这允许缩放绘制的图像。如果未指定,则图像不是   绘制时按比例缩放。

     

sx 要绘制到目标上下文中的源图像的子矩形左上角的X坐标。

     

sy 要绘制到目标上下文中的源图像的子矩形左上角的Y坐标。

     

sw 要绘制到目标上下文中的源图像的子矩形的宽度。如果没有指定,则整个矩形来自   sx和sy指定的坐标到右下角   使用图像。如果指定负值,则图像为   绘制时水平翻转。

     

sh 要绘制到目标上下文中的源图像的子矩形的高度。如果指定负值,则   绘制时图像垂直翻转。

在您的情况下,您将使用drawImage替换路径绘图功能。

var img = new Image;
img.onload = function() {
    //You have to make sure the image is loaded first
    //Begin rendering!
    render();
};

img.src = "path/to/your/ball/img.png"

function render() {
  var ball;
  context.fillStyle = "#008800";
  for (var i = 0; i <balls.length; i++) {
     ball = balls[i];
     ball.x = ball.nextx;
     ball.y = ball.nexty;
     context.drawImage(img, ball.x - (img.width/2), ball.y - (img.height/2)); //Make x, y the centerpoint
  }
}

答案 1 :(得分:0)

你可以这三种方式:

方法1 - 使用模式填充球

定义要用作图案的图像:

/// create a pattern
var pattern = context.createPattern(img, 'repeat');

现在您可以将图案用作填充样式而不是绿色:

context.fillStyle = pattern;

但是,由于模式始终以坐标的 origo (默认为0,0)为基础绘制,因此您需要为每次移动进行平移。幸运的是没有那么多额外的代码:

/// to move pattern where the ball is
context.translate(x, y);

context.beginPath();

/// and we can utilize that for the ball as well so we draw at 0,0
context.arc(0, 0, radius, 0, Math.PI * 2);
context.closePath();

context.fillStyle = pattern;
context.fill();

现在,根据您的移动方式,您周围的球可能需要或可能不需要每次翻译。

<强> Here's an online demo showing this approach

方法2 - 使用路径剪辑

剪裁图像以适应球

我们可以使用drawImage来绘制图像,而不是模式。然而,问题是这将绘制一个正方形,所以除非你创建一个球形图像,它适合你的球顶部透明像素。

你可以因此使用剪辑来实现与模式方法相同:

这里只需要几行:

/// define the ball (we will use its path for clipping)
context.beginPath();
context.arc(x, y, radius, 0, Math.PI * 2);
context.closePath();

/// as we need to remove clip we need to save current satte
context.save(); 

/// uses current Path to clip the canvas
context.clip();

/// draw the ball which now will be clipped
context.drawImage(img, x - radius, y - radius);

/// remove clipping
context.restore();

<强> Here's an online demo of this approach

方法3 - 将球预剪辑为图像

在Photoshop或类似的程序中制作一个球,然后将其绘制为图像,而不是绘制一条弧然后填充。

你只是画球而不是创建一个带弧的路径:

drawImage(ballImage, x - radius, y -radius);

如果您需要绘制不同尺寸,只需将调用扩展为:

drawImage(ballImage, x - radius, y - radius, radius, radius);

如果性能至关重要,这就是要走的路,因为这比其他两种方法具有更好的性能,但不如它们那么灵活。

如果您需要在灵活性和性能之间取得平衡,剪辑方法似乎是最佳的(这可能因浏览器而异,因此测试)。

<强> Here's an online demo with drawImage