javascript - 在 HTML Canvas 上用 JavaScript 克隆一个移动的球

标签 javascript html canvas

需要在 JavaScript 中克隆移动球的帮助。因此,当单击球时,球会继承与移动球相同的属性和 Action 。我尝试过使用cloneNode(),使用原型(prototype)和继承。 代码中的克隆区域位于注释//克隆原型(prototype)和构造函数

之后

下面是完整的代码以及代码底部的 JS 演示。

    #balling {
      border:1px solid rgb(0,0,0);
    }

  </style>
</head>
<body>
  <canvas id="balling" width="500" height="400"></canvas>

  <script type="text/javascript">
    var canvas = document.getElementById('balling');
    var context = canvas.getContext('2d');

    // The Properties of the Circle and Position within the Viewport
    var CircleOptions = {
      posBall: {
        x: 160, 
        y: 180
      },
      radius: 40,
      startAngle: 0, 
      endAngle: Math.PI * 2, 
      anticlockwise: false,
      radians: 0,
      xMove: Math.random(),
      yMove: Math.random(),
      speed:2,
      angle:80,
      velocityX:1,
      velocityY:1
    }; 

    //Math to make the ball move
    function moveBall() {
      CircleOptions.radians = CircleOptions.angle * Math.PI/180;
      CircleOptions.xMove = Math.cos(CircleOptions.radians) * CircleOptions.speed * CircleOptions.velocityX;
      CircleOptions.yMove = Math.sin(CircleOptions.radians) * CircleOptions.speed * CircleOptions.velocityY;
    }

    //Function to draw the ball
    function DrawOptions() {

      //Reset Canvas
      context.fillStyle = "white";
      context.fillRect(0, 0, canvas.width, canvas.height);

      //Drawing of the ball
      context.fillStyle = "rgb(142, 68, 173)";
      context.beginPath();
      context.arc(CircleOptions.posBall.x, CircleOptions.posBall.y, CircleOptions.radius, CircleOptions.startAngle, CircleOptions.endAngle, CircleOptions.anticlockwise);
      context.closePath();
      context.fill(); 
    }

    //finding the coordinates of the circle
    function CircleCoordinates() {
      CircleOptions.left = CircleOptions.posBall.x - CircleOptions.radius,
      CircleOptions.right = CircleOptions.posBall.x + CircleOptions.radius,
      CircleOptions.top = CircleOptions.posBall.y - CircleOptions.radius,
      CircleOptions.bottom = CircleOptions.posBall.y + CircleOptions.radius;
    }

    // Animate and call the function to move the ball
    setInterval(Move, 20);

    //Function call for the ball
    moveBall();

    //The function to make it move, reset canvas for movement and color/create shape of ball
    function Move() {
      //Function call for drawing and pinpointing the coordinates
      DrawOptions();
      CircleCoordinates();

      //Power to make it move
      CircleOptions.posBall.x += CircleOptions.xMove;
      CircleOptions.posBall.y += CircleOptions.yMove; 

      //checks for ball hitting the Wall
      if(CircleOptions.posBall.x > canvas.width || CircleOptions.posBall.x < 0) {
        CircleOptions.angle -= 770;
        moveBall();
      } else if(CircleOptions.posBall.y > canvas.height || CircleOptions.posBall.y < 0) {
        CircleOptions.angle -= 2760;
        moveBall();
      } else if(CircleOptions.posBall.y == canvas.height || CircleOptions.posBall.y > canvas.width) {
        CircleOptions.angle += 90;
        moveBall();
      }
    }

    canvas.addEventListener('click', function (e) {
      var clickedX = e.pageX - this.offsetLeft;
      var clickedY = e.pageY - this.offsetTop;

      if (clickedX < CircleOptions.right && clickedX > CircleOptions.left && clickedY > CircleOptions.top && clickedY < CircleOptions.bottom) {
        // alert('Double Me Please!');
        Clone();
      }
    });

    // Clone prototype and constructor
    function Clone() {
      var newCanvas = document.getElementById('balling');
      var context = newCanvas.getContext('2d');

      context.fillStyle = "rgb(142, 68, 173)";
      context.beginPath();
      context.arc(CircleOptions.posBall.x, CircleOptions.posBall.y, CircleOptions.radius, CircleOptions.startAngle, CircleOptions.endAngle, CircleOptions.anticlockwise);
      context.closePath();
      context.fill(); 

      return newCanvas;
    }

    //function call for clone

    //For cursor style in and out element
    canvas.addEventListener('mouseover', function () {
      document.body.style.cursor = "pointer";
    });

    canvas.addEventListener('mouseout', function () {
      document.body.style.cursor = "default";
    });
  </script>

更新的 fiddle 演示:http://jsfiddle.net/coder101/CMW24/5/

最佳答案

在您的 jsFiddle 版本中:

底部的 Clone 方法和调用不会执行任何操作。

你的 CircleOptions 实际上不是选项,它是代表球的对象。

您的“移动”功能是使其移动的重复 Controller 。

您的 setInterval 方法是通过调用 Move 启动它运行并使用现有的 DrawOptions 和 CircleOptions 的; CircleCoordinates 根本不执行任何操作。

如果你想克隆球,你需要创建一个 CircleOptions 对象数组(更改名称),然后在 Move 中循环它们,或者它们可能应该每个都有自己的 Move 方法并对其进行操作。但如果是 JavaScript,让它们全部在一个方法中移动将减少处理器的密集程度。

我清理了代码并删除了没有做任何事情的代码。现在,我将使球属于一个数组,并使您的点击事件添加更多球。我会把这个练习留给你。

var canvas = document.getElementById('balling');
var context = canvas.getContext('2d');

var ball = function( new_x, new_y) {
    var b = {};
    b.posBall = {
        x: new_x,
        y: new_y
    };
    b.radius = 40;
    b.startAngle = 0;
    b.endAngle = Math.PI * 2;
    b.anticlockwise = false;
    b.radians = 0;
    b.xMove = Math.random();
    b.yMove = Math.random();
    b.speed = 2;
    b.angle = 80;
    b.velocityX = 1;
    b.velocityY = 1;

    return b;
}

//Function to clear the canvas
function DrawReset() {
    //Reset Canvas
    context.fillStyle = "white";
    context.fillRect(0, 0, canvas.width, canvas.height);
    //Drawing of the ball
    context.fillStyle = "rgb(142, 68, 173)";
    context.beginPath();
    context.arc(CurrentBall.posBall.x, CurrentBall.posBall.y, CurrentBall.radius, CurrentBall.startAngle, CurrentBall.endAngle, CurrentBall.anticlockwise);
    context.closePath();
    context.fill();
}

//Math to make the ball move
function moveBall() {
    CurrentBall.radians = CurrentBall.angle * Math.PI / 180;
    CurrentBall.xMove = Math.cos(CurrentBall.radians) * CurrentBall.speed * CurrentBall.velocityX;
    CurrentBall.yMove = Math.sin(CurrentBall.radians) * CurrentBall.speed * CurrentBall.velocityY;
}

//The function to make it move, reset canvas for movement and color/create shape of ball
function Move() {
    //Function call for drawing and pinpointing the coordinates
    DrawReset();

    //Power to make it move
    CurrentBall.posBall.x += CurrentBall.xMove;
    CurrentBall.posBall.y += CurrentBall.yMove;

    //checks for ball hitting the Wall
    if (CurrentBall.posBall.x > canvas.width || CurrentBall.posBall.x < 0) {
        CurrentBall.angle -= 770;
        moveBall();
    } else if (CurrentBall.posBall.y > canvas.height || CurrentBall.posBall.y < 0) {
        CurrentBall.angle -= 2760;
        moveBall();
    } else if (CurrentBall.posBall.y == canvas.height || CurrentBall.posBall.y > canvas.width) {
        CurrentBall.angle += 90;
        moveBall();
    }
}

canvas.addEventListener('click', function (e) {
    var clickedX = e.pageX - this.offsetLeft;
    var clickedY = e.pageY - this.offsetTop;
    alert(e.pageX + ' ' + e.pageY);

    if (clickedX > CurrentBall.right && clickedX > CurrentBall.left && clickedY > CurrentBall.top && clickedY < CurrentBall.bottom) {
        alert('clicked number ');
    }
});

var CurrentBall = ball(160,180);

// Animate and call the function to move the ball
setInterval(Move, 20);

关于javascript - 在 HTML Canvas 上用 JavaScript 克隆一个移动的球,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21179439/

相关文章:

javascript - 以编程方式将 DOM 元素绑定(bind)到 $scope

javascript - 将二进制数据发送到 servlet

javascript - 简单的 jquery + javascript 不工作 : add ".has-error" not working and onclick event not defined

javascript - 带有自定义模板的 AngularJS 指令

javascript - 将推送的元素拆分为 Javascript 空数组

html - html5中为什么要用canvas做动画?

java - Android - Canvas 圆必须在第二秒左右向右进行圆周运动?

javascript - 使用chart.js在 donut chart 中心的事件处理程序

jquery - Nivo Slider 未居中

javascript - 如何使图像 "coming"成为前景