元Webデザイナー兼コーダーの備忘録

HTML,CSSの入門記事やブログのカスタマイズについてアウトプットしています。

 メニュー

【p5.js】円を追いかける円のアニメーション

円を追いかける円のアニメーションについて書きます。まずは、小さなプログラムから作っていきます。次に円の数を増やして、配列の扱い方を見ていきます。おまけとして、プログラムをオブジェクト指向的な書き方に書き換えてみます。

作成手順

  1. マウスを追いかける円を1つ作る
  2. 円を追いかける円を1つ作る
  3. 円を追いかける円を複数作る
  4. おまけ:プログラムをオブジェクト指向的な書き方に書き換える

マウスを追いかける円を1つ作る

function setup() {
    createCanvas(400, 400);
}

let x = 0, y = 0;

function draw() {
  background(127);

    x = mouseX;
    y = mouseY;
    //マウスを追いかける円
    fill(0, 0, 0);
    ellipse(x, y, 30, 30);
}

円を追いかける円を1つ作る

function setup() {
    createCanvas(400, 400);
}

let x = 0, y = 0;
let x1 = 0, y1 = 0, vx1 = 0, vy1 = 0;    //座標と追いかけるスピード

function draw() {
    background(127);

    //マウスを追いかける円
    x = mouseX;
    y = mouseY;
    fill(0, 0, 0);
    ellipse(x, y, 30, 30);

    // 円を追いかける円
    fill(0, 0, 255);
    vx1 = (x - x1) * 0.1;  // 速さ:1/10だけ前に進ませる
    vy1 = (y - y1) * 0.1;
    x1 += vx1;
    y1 += vy1;
    ellipse(x1, y1, 30, 30);
}

円を追いかける円を複数作る(配列)

常に1つ前の円を追いかける円。

function setup() {
    createCanvas(400, 400);
}

// 座標と追いかけるスピード
const x = new Array(10).fill(0);
const y = new Array(10).fill(0);
const vx = new Array(10).fill(0);
const vy = new Array(10).fill(0);

function draw() {
    background(127);

    // 1つ目の円
    x[0] = mouseX;
    y[0] = mouseY;
    fill(0, 0, 0);
    ellipse(x[0], y[0], 30, 30);

    // 2つ目以降の円
    for(let i = 1; i < x.length; i++){
        fill(0, 0, 255);
        vx[i] = int((x[i-1] - x[i]) * 0.1);
        vy[i] = int((y[i-1] - y[i]) * 0.1);
        x[i] += vx[i];
        y[i] += vy[i];
        ellipse(x[i], y[i], 30, 30);
    }
}

おまけ:プログラムをオブジェクト指向的な書き方に書き換える

const Circle = function(){
    // 座標と追いかけるスピード
    this.x = 0;
    this.y = 0;
    this.vx = 0;
    this.vy = 0;
};

Circle.prototype = {
    draw: function(){
        ellipse(this.x, this.y, 30, 30);
    },
    moveTo: function(target){
        this.vx = int((target.x - this.x) * 0.1);
        this.vy = int((target.y - this.y) * 0.1);
        this.x += this.vx;
        this.y += this.vy;
    },
};

const circles = new Array(10).fill(0); // 複数の円を扱う

function setup() {
    createCanvas(400, 400);
    // 円の生成
    for(let i = 0; i < circles.length; i++){
        circles[i] = new Circle();
    }
}

function draw() {
    background(127);

    // 1つ目の円
    circles[0].x = mouseX;
    circles[0].y = mouseY;
    fill(0, 0, 0);
    circles[0].draw();

    // 2つ目以降の円
    for(let i = 1; i < circles.length; i++){
        fill(0, 0, 255);
        circles[i].moveTo(circles[i-1]);
        circles[i].draw();
    }
}

デモ

キャンバス上にマウスを置くと、アニメーションが始まる。

まとめ

  • 作成手順を考えてからコードを書き始める
  • データを大量に扱うときは配列を使う
  • プログラムを配列からオブジェクト指向的な書き方に書き換える

ちなみに、群れの行動をシミュレートするアルゴリズムのことを「フロッキング(群集)アルゴリズム」と言うそうです。今回の円にフロッキングアルゴリズムを適用すると、魚や鳥の群れの動きを再現することができます。