0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

p5.play のSpriteクラスを継承させたい

Last updated at Posted at 2023-10-20

p5.play のSpriteクラスを継承させるには?

p5.play のSpriteはなかなか便利なものですが、Spriteクラスを継承したクラスを作ることができたらもっと便利ですよね?

(2023/10/21 修正) p5.registerMethod('init')を使った Spriteクラス継承ができないと思い込み元記事を投稿しましたが、勘違いでしたので訂正しています。

前提条件

Right align
p5.js 1.7.0
plank.js v1.0.0-beta.16
p5play.js 3.14

p5 をインスタンスモードで動かしたい。

p5.js Web Editorでやってみた

index.html

Web Editor を使って検証します。
p5.play を使う前提で 次のように index.html を作ります。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/addons/p5.sound.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/planck@latest/dist/planck.min.js"></script>
    <script src="https://p5play.org/v3/p5play.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />
  </head>
  <body>
    <main>
    </main>
    <script src="sketch.js"></script>
  </body>
</html>

sketch.js

p5 をインスタンスモードで起動させます。

sketch.js
window.onload = () => {
  new p5( sketch );
};

const sketch = function( p ) {

 p.preload = function(){
  };
  
  p.setup = function(){
  };
  
  p.draw = function(){
  };

};

注意)p5 のインスタンスを作るところは、window.onload のタイミングでないと いろいろまずいです。

p5.playのSprite はいつ定義されるのか?

p5play.js をみてみますと、いきなり先頭にこんなものが書かれています。

p5.prototype.registerMethod('init', function p5playInit() {
	if (typeof window.planck == 'undefined') {
		throw 'planck.js must be loaded before p5play';
	}
    :
 (略)
    :
	this.Sprite = class {
    :
 (略)
    :

p5.js の init処理が動くなかで、Spriteクラスが定義されています。
つまり p5.jsのinit処理の前では Spriteクラスを参照することはできません。

処理の順番

init

p5.prototype.registerMethod('init', 処理 );

init処理は registerMethod() で複数登録ができます。
登録した順に実行されます。

preload()

initで登録した処理が終わった後に、preload 関数 が1回だけ動きます。

setup()

preload 内の loadする処理が全て終わったあとにsetupが動きます。
setup の名前をもつ関数 は1回だけ動きます。

pre

p5.prototype.registerMethod('pre', 処理 );

pre処理は registerMethod() で複数登録ができます。
draw処理が実行される都度、その前に毎回動きます。
pre処理は registerMethod() で登録しないと動作しません。

draw()

preloadの後、pre処理の後に draw が動きます。
draw処理は、設定されたFPSに従い(FPSに近くなるように)呼び出されます。

post

p5.prototype.registerMethod('post', 処理 );

post処理は registerMethod() で複数登録ができます。
draw処理が実行される都度、その後のpreが開始される前に毎回動きます。
post処理は registerMethod() で登録しないと動作しません。

remove

p5.prototype.registerMethod('remove', 処理 );

remove処理は registerMethod() で複数登録ができます。
p5のremove()が実行されるタイミングで実行されます。
remove処理は registerMethod() で登録しないと動作しません。

image.png

p5.playのSprite はどのタイミングで使えるのか?

結論:preload()処理が動く直前、以降で使えます。
結論:p5のinitのタイミング以降で p5PlayのSpriteクラスが使えます。

p5.play Spriteを継承したクラスを作れるのは、どのタイミングですか?

結論:preload()処理が動く直前以降であれば次の形で継承できます。
結論:p5のinitのタイミング以降で p5PlayのSpriteクラスを継承できます。

const Clazz = class extends p.Sprite {

};

継承したクラスを作る

【A】p5のinitのタイミングで作る

こんな感じでかけそうです。

js/pico.js (名前は任意)
p5.prototype.registerMethod('init', function (){

  this.PicoSprite = class extends this.Sprite {
      
      constructor(...args){
        
        super(...args);
        // 追加処理があれば書く。
      }      
      
    };
});

sketch.js
const sketch = function( p ) {

    p.setup = function() {
        pico = new p.PicoSprite();

    }

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/addons/p5.sound.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/planck@latest/dist/planck.min.js"></script>
    <script src="https://p5play.org/v3/p5play.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />
  </head>
  <body>
    <main>
    </main>
    <script src="./js/pico.js"></script> <!-- ここで 継承クラスを定義 -->
    <script src="sketch.js"></script>
  </body>
</html>


ちょっとした説明

registerMethod() へ渡すファンクションは、アロー関数ではNGです。
p5Playで作ったSpriteクラスを参照できなくなります。
registerMethod() へ渡すファンクションの中での this は p5 です。

上の例では sketch.jsの先頭に registerMethod() を 書いていますが、この部分を別JSファイルとして外だしにしてもOKです。 むしろ外だしにしたほうがすっきりするかも。

【B】setup の中で作る

こんな感じでかけそうです。

sketch.js
    p.setup = function() {

        PicoSprite = class extends p.Sprite {

            constructor(...args) {
                super(...args);
                // 追加処理があれば書く。
            }
        };

        pico = new PicoSprite();

    }

【C】setup の中のタイミングで生成、別ファイルにする

こんな感じでかけそうです。

js/PicoSprite.js

const createPicoSpriteClass = function(p){

    return class Pico extends p.Sprite {

        constructor(...args) {
            super(...args);
            // 追加処理があれば書く。
        }
    };
};

sketch.js
    p.setup = function() {
        PicoSprite = createPicoSprite(p);
        pico = new PicoSprite();
    }

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/addons/p5.sound.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/planck@latest/dist/planck.min.js"></script>
    <script src="https://p5play.org/v3/p5play.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />
  </head>
  <body>
    <main>
    </main>
    <script src="js/PicoSprite.js"></script>
    <script src="sketch.js"></script>
  </body>
</html>

まとめ

Spriteを使えるのは?

p5 の Initフェーズの最後以降

Spriteの継承クラスを書くやり方は?

【A】、【B】、【C】のうち、お好きなやり方でどうぞ。

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?