Processingで障子に穴を開ける

小さい頃、障子に穴を開けて怒られてしまったことはありませんか？

Processingを使って、障子に穴を開けましょう。もう二度と怒られることはありません。

（用意するもの）
・障子
・プロジェクター
・テンキー
・プログラム（下に記載しています）

こんな感じです↓

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Processing with &quot;Shoji&quot;<a href="https://twitter.com/hashtag/Processing?src=hash&amp;ref_src=twsrc%5Etfw">#Processing</a> <a href="https://twitter.com/hashtag/shoji?src=hash&amp;ref_src=twsrc%5Etfw">#shoji</a> <a href="https://twitter.com/hashtag/%E9%9A%9C%E5%AD%90?src=hash&amp;ref_src=twsrc%5Etfw">#障子</a> <a href="https://twitter.com/hashtag/interactive?src=hash&amp;ref_src=twsrc%5Etfw">#interactive</a> <a href="https://twitter.com/hashtag/mediaart?src=hash&amp;ref_src=twsrc%5Etfw">#mediaart</a> <a href="https://t.co/Q0E9kuhuqB">pic.twitter.com/Q0E9kuhuqB</a></p>&mdash; kdmyk (@kd_myk) <a href="https://twitter.com/kd_myk/status/1223116860809367554?ref_src=twsrc%5Etfw">January 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

指のアニメーションは、2000 x 500 pix のキャンバスに 250 x250 pix のコマを貼っています。
Processingでは、この一つのキャンバスの左上から順に画像を切り出し、表示すると云う処理を行います。

![yubi_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397861/9db7b048-2036-87b7-b0cb-9136a8f4297c.jpeg)

こちらがコードです↓

````
class shojiScene{
  
  //devide image
  ArrayList<PImage>  shojiFrame = new ArrayList<PImage>(); 
  int yubiframe = 0; 

  shojiScene( int mx, int my, int fx, int fy, String image ){

    PImage  yubi;
    yubi = loadImage( image );
    
    for( int ycount = 0; ycount < fy; ycount++ ){
      for( int xcount = 0; xcount < fx; xcount++ ){
        
        PImage  work1;
        int x = xcount * mx;
        int y = ycount * my;
        work1 = yubi.get( x, y, mx, my );
        shojiFrame.add( work1 );  
      }
    }
  }
   
  //pick up from the top
  boolean disp( int x, int y ){
    
    PImage work2;
    work2 = shojiFrame.get( yubiframe );
    image( work2, x, y );
    yubiframe++;
    
    boolean  ret = false;
    if( yubiframe > shojiFrame.size() - 1 ){
      yubiframe = 0;
      ret = true; 
    }
    return( ret );
  } 
}
 


class anime {
  class sceneMng {
    shojiScene   ds;  //scene
    int        dx;  //point of x axis
    int        dy;  //point of y axis
  
    sceneMng( shojiScene s, int x, int y ){
      ds = s;
      dx = x;
      dy = y;
    }
  }
  
  //manage for different scenes
  ArrayList<sceneMng>  sceneList;
  
  anime(){
    sceneList = new ArrayList<sceneMng>();
  }
  
  //add scene
  //sn : adding scene  x / y : locate of display
  void addScene( shojiScene sn, int x, int y ){
    sceneMng sm = new sceneMng( sn, x, y );
    sceneList.add( sm );
  }
  
  void disp(){
    boolean dispEnd = false;
    
    //pick up all scenes from top and show it in order 
    for( int index = 0; index < sceneList.size(); index++ ){
      sceneMng  dispSheen = sceneList.get( index );
      dispEnd = dispSheen.ds.disp( dispSheen.dx, dispSheen.dy );
      if( dispEnd == true ){

        sceneList.remove( index );
      }
    }  
  }  
}

 
 
anime      animeList;    
shojiScene   Shoji;    
 
final float TARGET_FPS = 12.0f;                // frame rate 
final float FRAME_TIME = 1000.0f / TARGET_FPS; // processing time of one frame
int lastUpdateTime = 0;                        // update time 
float passageTime = 0.0f;                      // passage time orom previors frame

 
void setup(){
  size( 1300,768 );
  animeList = new anime();
  
  frameRate( TARGET_FPS );  
}
 
void draw(){
  background( 255 );
  fill(0);

      
  //sikaku
  rect(0,0,670,90);//rahmen
  rect(670,0,1300,80);//rahmen
  rect(0,760,760,10);//rahmen
  rect(670,760,1300,20);//rahmen
  rect(0,0,195,780);//rahmen
  rect(1175,0,1130,800);//rahmen  
  
  rect(435,80,240,230);
  rect(940,305,240,225);
  rect(195,535,240,230);
  rect(680,530,255,230);
    
  //measure from last time and this time 
  int curTime = millis();     //current time  
  passageTime += curTime - lastUpdateTime; //passage time 
  lastUpdateTime = curTime;   // update time
  
  //display the time of late frames 
  for( ; passageTime >= FRAME_TIME; passageTime -= FRAME_TIME) {
    animeList.disp();
  }
  

  }

 
void keyPressed(){

    if( key == '1' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 940,540 );
      }
    if( key == '3' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 440,540 );
      }
    if( key == '5' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 690,310 );
      }
    if( key == '6' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 440,310 );
      }
    if( key == '7' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 940,80 );
      }
    if( key == '8' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 690,80 );
      }
    if( key == '+' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 200,310 );
      }
    if( key == '-' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 200,80 );
      }
    if( key == '/' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 960,0 );
          }
    if( key == '*' ){
    Shoji = new shojiScene( 250, 250, 8, 2, "yubi_2.png" );
    animeList.addScene( Shoji, 690,0 );
       
  }
    
else {

  }
  }
```

ぜひお試しを！