有没有更好的方法来分别用不同的颜色,x和速度调用这些球?

时间:2019-06-02 13:39:33

标签: javascript html5-canvas

几周前我开始学习JavaScript,所以我决定尝试从头开始制作我的第一款游戏,在下面的代码中,我试图制作游戏,以便使球每次落下时的位置,颜色和速度都不同,将会有另一个无法用鼠标移动的球并试图躲避这些球,所以我的问题是有没有比我产生更多球更好的方法,因为如果我想像5一样产生再加上-6个代码,看起来会很糟糕,我敢肯定有更好的方法可以做到这一点,但我仍在学习,以便您可以通过简单的解决方案来解决我并进行解释。

var canvas = document.getElementById("Canv");
var ctx = canvas.getContext("2d");
var x = random(1, 801);
var x2 = random(1, 801);
var y = 10;
var y2 = 10;
var ballRadius = random(2, 51);
var ballRadius2 = random(2, 51);
var color = "#" + ((1 << 24) * Math.random() | 0).toString(16);
var color2 = "#" + ((1 << 24) * Math.random() | 0).toString(16);
var dy = random(1, 6);
var dy2 = random(1, 6);

function random(min, max) {
    return Math.random() * (max - min) + min;
}

function drawBall() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
    ctx.fillStyle = color;
    ctx.fill();
    ctx.closePath();
}

function drawBall2() {
    ctx.beginPath();
    ctx.arc(x2, y2, ballRadius2, 0, Math.PI * 2);
    ctx.fillStyle = color2;
    ctx.fill();
    ctx.closePath();
}

function draw() {
    drawBall();
    drawBall2();
    y += dy;
    y2 += dy2;
}

setInterval(draw, 10);

我想知道简化代码的方法,所以我知道将来的项目。

1 个答案:

答案 0 :(得分:0)

考虑以下代码:

我所做的主要更改是增加了功能createBall,该功能允许每个刻度创建多个新球,并删除看不见的球。我试图在新零件中添加注释,如果您有任何疑问,请告诉我!

var canvas = document.getElementById("Canv");
var ctx = canvas.getContext("2d");
const desiredNumberOfBalls = 10;
let i = 0;

let balls = []; // Track each individual ball
const viewLimit = canvas.height; // The vertical distance a ball has when leaving sight

// For now we create a static paddle
const paddle = {
  x: 200,
  y: viewLimit - 10,
  width: 50,
  height: 10,
}

// This is a very rough calculation based on https://math.stackexchange.com/a/2100319 by checking first the corners and then the top edge
paddle.hitsBall = function(ball) {
  let hit = false;
  if (ball.y + ball.radius >= paddle.y) {
    // the ball is at the same level as the paddle
    if (Math.sqrt((ball.x - paddle.x) ** 2 + (ball.y - paddle.y) ** 2) < ball.radius) {
      // the upper left part of the paddle touches the ball
      hit = true;
    } else if (Math.sqrt((ball.x - paddle.x - paddle.width) ** 2 + (ball.y - paddle.y) ** 2) < ball.radius) {
      // the upper right part of the paddle touches the ball
      hit = true;
    } else if (ball.x >= paddle.x && ball.x <= paddle.x + paddle.width) {
      // the top edge of the paddle touches the ball
      hit = true;
    }
  }
  if (hit) console.log("Hit!");
  return hit;
}

function createBall() {
  let ball = {
    id: i++,
    x: random(1, canvas.width),
    y: 10,
    radius: random(2, 51),
    color: "#" + ((1 << 24) * Math.random() | 0).toString(16),
    speed: random(1, 6)
  };
  return ball;
}

function random(min, max) {
  return Math.random() * (max - min) + min;
}

function drawBall(ball) {
  ctx.beginPath();
  ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
  ctx.fillStyle = ball.color;
  ctx.fill();
  ctx.closePath();
}

function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddle.x, paddle.y, paddle.width, paddle.height);
  ctx.fillStyle = 'darkred';
  ctx.fill();
  ctx.closePath();
}

function clearView() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function draw() {
  clearView();

  // Move all existing balls by their designated speed
  balls.forEach((ball) => {
    ball.y += ball.speed;
  });

  // Implicitly delete all balls that have exited the viewport
  // by only retaining the balls that are still inside the viewport
  balls = balls.filter((ball) => ball.y <= viewLimit);

  // Implicitly delete all balls that touch the paddle
  // by only retaining the balls that don't
  balls = balls.filter((ball) => !paddle.hitsBall(ball));

  // Create newBallsPerTick new balls
  while (balls.length < desiredNumberOfBalls) {
    balls.push(createBall());
  }

  // Draw the paddle
  drawPaddle();

  // Draw the position of every ball - both the pre-existing ones
  // and the ones we just generated
  balls.forEach((ball) => {
    drawBall(ball);
  });
}
setInterval(draw, 1000 / 60);
canvas {
  width: 600px;
  height: 400px;
}
<canvas id="Canv" height="400" width="600"></canvas>