Sprite/P5- 计算一个物体撞击另一个物体的次数

Sprite/P5- count how many times an object hits another

我正在尝试制作乒乓球,在球击中球拍 x 次后,会出现圣诞节动画。我不确定如何注册它,以及是否应该使用 if else 来切换到动画。 Whosebug 不会让我 post 我的问题,因为它说它“主要是代码”所以这是我试图占用更多文本 space。到目前为止,这是我的代码:

function setup() {
  createCanvas(windowWidth, windowHeight);
  //frameRate(6);

  paddleA = createSprite(30, height / 2, 10, 100);
  paddleA.immovable = true;

  paddleB = createSprite(width - 28, height / 2, 10, 100);
  paddleB.immovable = true;

  wallTop = createSprite(width / 2, -30 / 2, width, 30);
  wallTop.immovable = true;

  wallBottom = createSprite(width / 2, height + 30 / 2, width, 30);
  wallBottom.immovable = true;

  ball = createSprite(width / 2, height / 2, 10, 10);
  ball.maxSpeed = MAX_SPEED;

  paddleA.shapeColor = paddleB.shapeColor = ball.shapeColor = color(
    255,
    0,
    255
  );

  ball.setSpeed(MAX_SPEED, -180);
}

function draw() {
  background(0);

  paddleA.position.y = constrain(
    mouseY,
    paddleA.height / 2,
    height - paddleA.height / 2
  );
  paddleB.position.y = constrain(
    mouseY,
    paddleA.height / 2,
    height - paddleA.height / 2
  );

  ball.bounce(wallTop);
  ball.bounce(wallBottom);

  var swing;
  if (ball.bounce(paddleA)) {
    swing = (ball.position.y - paddleA.position.y) / 3;
    ball.setSpeed(MAX_SPEED, ball.getDirection() + swing);
  }

  if (ball.bounce(paddleB)) {
    swing = (ball.position.y - paddleB.position.y) / 3;
    ball.setSpeed(MAX_SPEED, ball.getDirection() - swing);
  }

  if (ball.position.x < 0) {
    ball.position.x = width / 2;
    ball.position.y = height / 2;
    ball.setSpeed(MAX_SPEED, 0);
  }

  if (ball.position.x > width) {
    ball.position.x = width / 2;
    ball.position.y = height / 2;
    ball.setSpeed(MAX_SPEED, 180);
  }
  
  drawSprites();

  //switch to Xmas animation
  //if (ball.bounce(paddleA)) {
    //background("brown");

根据您的评论,您可以采用以下方式:

你说你想在球在球拍上弹跳一定时间后显示动画,为此你可以创建一个变量来包含这个计数并在每次球接触球拍时更新.

因此您可以在 setup()draw() 之外创建例如 let hitCount=0; 这样您将拥有一个可以从任何地方访问的变量。

您已经根据您的条件 if (ball.bounce(paddleA)) {if (ball.bounce(paddleB)) { 检查了球何时接触球拍,因此您可以使用这些代码块来更新 hitCount:

if (ball.bounce(paddleA)) {
    hitCount++;
    swing = (ball.position.y - paddleA.position.y) / 3;
    ball.setSpeed(MAX_SPEED, ball.getDirection() + swing);
}

if (ball.bounce(paddleB)) {
    hitCount++;
    swing = (ball.position.y - paddleB.position.y) / 3;
    ball.setSpeed(MAX_SPEED, ball.getDirection() - swing);
}

然后您想隐藏精灵和 运行 动画。我认为最简单的方法是停止调用 drawSprites() 您可以将以下内容添加到您的 draw() 函数中:

if (hitCount < HITS_BEFORE_ANIMATION) {
    // Show the game if we didn't reach the number of hits
    drawSprites();        
} else {
    // Show the animation
    text('Merry christmas', width/2, height/2);
}

这要求您在声明 hitCount 的位置旁边创建一个 const HITS_BEFORE_ANIMATION=10。你在这里做的是在球反弹少于 X 次时显示精灵,否则显示动画(这里是简单的文本)。

最后您想在动画结束时再次显示游戏。有很多不同的方法可以做到这一点,这主要取决于您如何编写动画代码。为了这个答案,我会说我们想要显示 50 帧的动画,然后返回游戏。

所以让我们声明 let animationCount=0 将保存动画到目前为止已显示的帧数和 const ANIMATION_FRAMES=50 将保存显示动画的帧数。然后我们可以像这样更新以前的代码:

if (hitCount < HITS_BEFORE_ANIMATION) {
    // Show the game if we didn't reach the number of hits
    drawSprites();        
} else {
    // Show the animation
    text('Merry christmas', width/2, height/2);
    animationCount++;
    
    // Stop showing the animation and go back to the game after some time
    if (animationCount === ANIMATION_FRAMES) {
        hitCount=0; // Return to game
        animationCount = 0;
    }
}

这样当你完成动画时 hitCount 重置为零,重新启用 drawSprites() 我们也重置 animationCount 否则下次它应该显示 if (animationCount === ANIMATION_FRAMES) 将立即为真,我们将只显示一帧。

我用你的代码和我添加的内容创建了一个代码笔,这样你就可以看到它的工作原理。它可用 here 我认为它应该为您提供入门所需的内容,您可能需要在编写动画代码后进行一些调整,但至少您会知道如何进行。