如何使用 p5.js/p5.play 在精灵 collide/overlap 后显示动画
how to display animation after sprites collide/overlap using p5.js/p5.play
我试图在精灵之间发生碰撞时显示动画。我有我射击的小行星,当我射击它们时,当子弹碰撞或与小行星重叠时,小行星就会消失。我想在与小行星相撞后播放动画。我该怎么做?
查看下面的代码
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()
}
我相信我需要在 drawBullets() 函数或 explode 函数中实现一些东西。但不确定当子弹与小行星相撞时如何真正播放动画。
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');
当碰撞发生时,您可以创建一个新对象,其中包含有关碰撞的信息,以及您希望碰撞发生多长时间,然后将该对象添加到新的 explosions = []
。像这样:
explosions.push({
x: towers[j].position.x,
y: towers[j].position.y,
time: 20
});
当然,在您的示例中,您会希望在发生碰撞时在子弹的位置创建对象。
然后在您的 draw()
中,您可以简单地向后遍历该数组并显示动画:
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);
}
}
}
您也可以使用 setTimeout
但这可能更清楚。
这是我创建的一个示例(动画有点不可靠,我只是从 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>
这是我为此创建的 p5.js editor sketch 的 link。
我试图在精灵之间发生碰撞时显示动画。我有我射击的小行星,当我射击它们时,当子弹碰撞或与小行星重叠时,小行星就会消失。我想在与小行星相撞后播放动画。我该怎么做?
查看下面的代码
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()
}
我相信我需要在 drawBullets() 函数或 explode 函数中实现一些东西。但不确定当子弹与小行星相撞时如何真正播放动画。
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');
当碰撞发生时,您可以创建一个新对象,其中包含有关碰撞的信息,以及您希望碰撞发生多长时间,然后将该对象添加到新的 explosions = []
。像这样:
explosions.push({
x: towers[j].position.x,
y: towers[j].position.y,
time: 20
});
当然,在您的示例中,您会希望在发生碰撞时在子弹的位置创建对象。
然后在您的 draw()
中,您可以简单地向后遍历该数组并显示动画:
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);
}
}
}
您也可以使用 setTimeout
但这可能更清楚。
这是我创建的一个示例(动画有点不可靠,我只是从 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>
这是我为此创建的 p5.js editor sketch 的 link。