8_2:p5.play マウス操作に関するイベントハンドラ

onMouseOverとonMouseOut

スプライトは、onMouseOverイベントハンドラプロパティと、それに対応するonMouseOutイベントハンドラプロパティを持っています。

スプライトのコライダー上にマウスカーソルが重なると、onMouseOverイベントハンドラプロパティに割り当てた関数が呼び出されます。その後マウスカーソルがスプライトのコライダーから出ると、onMouseOutイベントハンドラプロパテに割り当てた関数が呼び出されます。

次のサンプルでは、表示される花の写真の上にマウスカーソルを重ねると次の花の写真に変わります。

let flowerAnim;
let flowerSp;

function preload() {
    flowerAnim = loadAnimation('assets/kurinsou/image1.png', 'assets/kurinsou/image3.png');
}

function setup() {
    createCanvas(400, 300);
    // 花スプライトを作成
    flowerSp = createSprite();
    // アニメーションには3つの画像が含まれている
    flowerSp.addAnimation('idle', flowerAnim);
    flowerSp.position.x = width / 2;
    flowerSp.position.y = height / 2;
    // アニメーションを止めておく
    flowerSp.animation.stop();

    // 花スプライトのマウスオーバーで
    flowerSp.onMouseOver = function() {
        print('mouseOver');
        // カーソルをgrabに変更
        cursor('grab');
        // アニメーションを次のフレームに送る => スライドのようなもの
        this.animation.nextFrame();
    }

    // 花スプライトのマウスアウトで、
    flowerSp.onMouseOut = function() {
        print('mouseOut');
        // カーソルを元の矢印に戻す
        cursor(ARROW);
    }
}

function draw() {
    background(200);
    drawSprite(flowerSp);
}

ここでは花の写真を3つ持つAnimationオブジェクトを使って、スライドのような機能を実現しています。そのためにはまず、setup()でスプライトを作成した後すぐ、アニメーションの再生を止めます。

flowerSp.animation.stop();

そしてマウスオーバーイベントハンドラの定義で、Animationを次のフレームに送ります。

flowerSp.onMouseOver = function() {
    cursor('grab');
    this.animation.nextFrame();
}

onMousePressedとonMouseReleased

スプライトはまた、onMousePressedイベントハンドラプロパティと、それに対応するonMouseReleasedイベントハンドラプロパティを持っています。

スプライトの上でマウスボタンが押し下げられると、onMousePressedイベントハンドラプロパティに割り当てた関数が呼び出されます。その後マウスボタンが放されると、onMouseReleasedイベントハンドラプロパティに割り当てた関数が呼び出されます。

次のサンプルでは、画面下部の砲台を左クリックすると砲台が時計回りに回転し、右クリックすると反時計回りに回転します。マウスの真ん中のボタンを押すと、火の玉が連射できます。

let cannonimg;
let cannonSp;
let fireImg;
let fireSp;
let fireNum = 0;

function preload() {
    cannonimg = loadImage('assets/cannon.png');
    fireImg = loadImage('assets/fire.png');
}

function setup() {
    createCanvas(400, 300);
    // 砲台スプライトの作成
    cannonSp = createSprite();
    cannonSp.addImage(cannonimg);
    cannonSp.myName = 'cannon';
    cannonSp.position.x = width / 2;
    cannonSp.position.y = height - cannonSp.width / 2;

    // 砲台スプライトのマウスプレスで
    cannonSp.onMousePressed = function() {
            print('mousePressed');
            // 左ボタンの場合
            if (mouseButton === LEFT) {
                print('LEFT');
                // 時計回りに10度回転
                this.rotation += 10;
                // 右ボタンの場合
            }
            else if (mouseButton === RIGHT) {
                print('RIGHT');
                // 反時計回りに10度回転
                this.rotation -= 10;
                // センターボタンの場合
            }
            else if (mouseButton === CENTER) {
                print('CENTER');
                // 火の玉を発射
                fire(this.rotation);
            }
        }
        // 砲台スプライトのマウスリリースで
    cannonSp.onMouseReleased = function() {
            print('mouseReleased');
        }
        // コンテキストメニューを表示しない
    document.oncontextmenu = function() {
        return false;
    }
    textSize(15);
    fill(255, 0, 0);
}

// 火の玉スプライトを作成し発射する
function fire(angle) {
    fireNum++;
    // 火の玉スプライトを作成
    fireSp = createSprite();
    fireSp.addImage(fireImg);
    fireSp.scale = 0.3;
    // 砲台に重なるように位置取りする
    fireSp.position.x = cannonSp.position.x
    fireSp.position.y = height - cannonSp.width / 2;
    // 時間がたてば自動的に削除されるようにしておく
    fireSp.life = 100;
    // 確認用のカスタムプロパティ
    fireSp.myName = 'fire' + fireNum;
    // 深度の交換 => 砲台が火の玉を隠すように
    swapDepths(fireSp, cannonSp);
    // 火の玉の進む角度を砲台に合わせる
    fireSp.rotation = angle;
    // angle + 270の方向に移動 => 砲台から火の玉が発射されるように見える
    fireSp.setSpeed(5, angle + 270);
}

function draw() {
    background(200);
    update();
    drawSprites();
}

// 渡された2つのスプライトの深度を交換
function swapDepths(sp1, sp2) {
    const depth1 = sp1.depth;
    const depth2 = sp2.depth;
    sp1.depth = depth2;
    sp2.depth = depth1;
}

function update() {
    // 確認用にスプライトの深度を表示
    let txt = '';
    for (let i = 0; i < allSprites.length; i++) {
        txt += '深度' + allSprites[i].depth + ': ' + allSprites[i].myName + '\n';
    }
    text(txt, 30, 30, 220, 300);
    // 砲台スプライトだけの場合は、砲台スプライトの深度を1に戻す
    if (allSprites.length === 1) {
        allSprites[0].depth = 1;
        fireNum = 0;
    }
}

砲台スプライトをマウスダウンすると、次のイベントハンドラが発効します。

cannonSp.onMousePressed = function() {
    // 左ボタンの場合
    if (mouseButton === LEFT) {
        // 時計回りに10度回転
        this.rotation += 10;
    // 右ボタンの場合
    }
    else if (mouseButton === RIGHT) {
        // 反時計回りに10度回転
        this.rotation -= 10;
    // センターボタンの場合
    }
    else if (mouseButton === CENTER) {
        // 火の玉を発射
        fire(this.rotation);
    }
}

mouseButtonはp5.jsのmouseButtonプロパティで、マウスダウンが押されたときどのボタン(LEFT, RIGHT, CENTER)が押されたかを自動的に追跡します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA