1

I am trying to display an animation when a collision occurs between sprites. I have asteroids that I shoot and when I shoot them the asteroids disappear when the bullet collides or overlaps the asteroid. I would like to play an animation after the asteroid has been collided with. how can I go about this ?

see code bellow

function createAsteroids() { // code to spawn asteroids at random locations
    for (let i = 0; i < numAsteroids; i++) {
        asteroid = createSprite(random(0, 1000), random(-50, -350), 40, 40);
        asteroid.addImage(asteroidSprite)
        asteroidSprite.resize(65, 65);

        asteroid.maxSpeed = random(1, 3);
        rock.add(asteroid);
        asteroidArray.push(asteroid);
    }
}
function drawAsteroid() { // draws asteroids moving down and checking collision
    rock.overlap(turret, explode)
    for (let i = 0; i < asteroidArray.length; i++) {
        if (asteroidArray[i].position.y > height) {
            asteroidArray[i].position.y = 0;
            asteroidArray[i].position.x = random(0, 800);
        }
        asteroidArray[i].addSpeed(3, 90);   // code to move asteroids towards the turrets using attracttion point
        if (i % 3 == 0) {
            asteroidArray[i].attractionPoint(1, 100, 740);
        }
        if (i % 3 == 1) {
            asteroidArray[i].attractionPoint(1, 500, 740);
        }
        if (i % 3 == 2) {
            asteroidArray[i].attractionPoint(1, 1200, 740);
        }
    }
}
function createBullets() { // code to create bullet
    for (let i = 0; i < numBullets; i++) {
        bullets = createSprite(500, 740, 25, 25);
        bullets.addImage(bulletSprite)
        bullets.maxSpeed = 6;
        pew.add(bullets)
        bulletArray.push(bullets)
    }
}
function drawBullets() { // code to fire bullets
    pew.overlap(rock, explode)
    explodeSound.play()
    bulletArray[bullCount].attractionPoint(4, mouseX, mouseY);
    bullCount++;
}

function explode(sprite, obstical) { //code for explosion and collision and removal of sprites on collision
    sprite.remove()
    obstical.remove()
    explodeSound.play()
}

I believe I would need to implement something in the drawBullets() function, or the explode function. but not sure how to actually get the animation to play when the bullet collides with the asteroid.

explosion = loadAnimation('assets/0.png', 'assets/1.png', 'assets/2.png', 'assets/3.png', 'assets/5.png', 'assets/6.png',
        'assets/7.png', 'assets/8.png', 'assets/9.png', 'assets/10.png', 'assets/11.png', 'assets/12.png', 'assets/13.png',
        'assets/14.png', 'assets/15.png', 'assets/16.png', 'assets/17.png', 'assets/18.png', 'assets/19.png', 'assets/20.png',
        'assets/21.png', 'assets/22.png', 'assets/23.png', 'assets/24.png', 'assets/25.png', 'assets/26.png', 'assets/27.png',
        'assets/28.png', 'assets/29.png', 'assets/30.png', 'assets/31.png', 'assets/32.png', 'assets/33.png', 'assets/34.png',
        'assets/35.png', 'assets/36.png', 'assets/37.png', 'assets/38.png', 'assets/39.png', 'assets/40.png', 'assets/41.png',
        'assets/42.png', 'assets/43.png', 'assets/44.png', 'assets/45.png', 'assets/46.png', 'assets/47.png');
Yakob
  • 159
  • 1
  • 7

1 Answers1

1

When the collision happens, you could create a new object which contains the information about the collision, and how long you want the collision to take place for, and then add that object to a new explosions = []. Something like this:

 explosions.push({
  x: towers[j].position.x,
  y: towers[j].position.y,
  time: 20
 });

Of course, in your example, you'll want to create the object at the position of the bullet when the collision happens.

And then in your draw() you could simply iterate through that array backwards and display the animation:

function draw() {
  ...
  // loop backwards so we can remove from array
  for (let i = explosions.length - 1; i >= 0; i--) { 

    animation(explodeAnimation, explosions[i].x, explosions[i].y);
    explosions[i].time--;
    
    if (explosions[i].time <= 0) {
      explosions.splice(i, 1);
    }
  }
}

You could also potentially use a setTimeout but this is probably clearer.

Here's an example I created (The animation is a bit dodgy, I just copied it from this animation reference):

let numAsteroids = 10;
let towers;
let rock;

let spriteSheet;

let explosions = [];
function setup() {
  createCanvas(400, 400);
  spriteSheet = loadSpriteSheet('spritesheet.png', 171, 158, 11);
  explodeAnimation = loadAnimation(spriteSheet);
  
  rock = Group();
  towers = Group();
  createTowers();
  createAsteroids();
}

function draw() {
  background(220);
  

  drawSprites(rock);
  drawSprites(towers);
  updateAsteroids();
  
 // loop backwards so we can remove from array
  for (let i = explosions.length - 1; i >= 0; i--) { 

    animation(explodeAnimation, explosions[i].x, explosions[i].y);
    explosions[i].time--;
    
    if (explosions[i].time <= 0) {
      explosions.splice(i, 1);
    }
  }

}

function createAsteroids() {
  // code to spawn asteroids at random locations
  for (let i = 0; i < numAsteroids; i++) {
    let asteroid = createSprite(random(0, width), random(-50, -350), 40, 40);
    asteroid.maxSpeed = random(1, 3);
    rock.add(asteroid);
    
    let tower = floor(random(3))
    
    asteroid.attractionPoint(asteroid.maxSpeed, towers[tower].position.x, towers[tower].position.y);
  }
}


function updateAsteroids() {
  // draws asteroids moving down and checking collision
  for (let i = rock.length - 1; i >= 0; i--) {
    if (rock[i].position.y > height) {
      rock[i].position.y = 0;
      rock[i].position.x = random(0, width);
    }
    
    for (let j = towers.length - 1; j >=0; j--) {
      if (rock[i].overlap(towers[j])) {
        rock[i].position.y = 0;
        rock[i].position.x = random(0, width);
        
        explosions.push({
          x: towers[j].position.x,
          y: towers[j].position.y,
          time: 20
        });
      }
    }
  }
}

function createTowers() {
  towers.push(createSprite(40, height - 30, 40, 90));
  towers.push(createSprite(width/2, height - 30, 40, 90));
  towers.push(createSprite(width-40, height - 30, 40, 90));
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script>
        <script src="https://cdn.jsdelivr.net/gh/molleindustria/p5.play/lib/p5.play.js"></script>

    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="sketch.js"></script>
  </body>
</html>

Here's a link to the p5.js editor sketch I created for this.

Luke Garrigan
  • 4,571
  • 1
  • 21
  • 29