つらねの日記

プログラムの進捗やゲームをプレイした感想などを書き連ねる日記。

processing.jsを使ってみた

前書き

processing.jsといったものがあるということは知っていたが、よくわからなかったので使い方すら勉強せずに放置していた。しかしせっかくブログを作ったのでそこで動くものを見せれたら面白いかなと思い、調べた。理屈はともかくはてなブログはてな記法を用いて使う書き方がわかったので記念という意味も込めて何か貼ってみようと思う。

使い方

><script src="http://cloud.github.com/downloads/processing-js/processing-js/processing-1.3.6.min.js"></script><script type="application/processing" data-processing-target="pjs" >

//ソース

</script><canvas id="pjs"/><
わかったこと

ソースはjs形式?に変えたものではなくてpdeの形式そのままを用いることができる。
processing.jsは本当は自分のサーバーに置くのがベストのようだが、GitHubに置いてあるのでそれを使うことも可能ではあるらしい。
"pjs"の部分は自分の好きなものに変えることができる。同ページに同じものがあるとダメみたいなので個別なidをつけるといいらしい。

なんか貼る

以前最新のスマートフォンのロック画面を再現する遊びをやった時の物があったのでそれを貼ってみようと思う。ロック解除するにはスワイプしてくださいとか書いてあるがもちろんそんな機能はつけていない。


ソース

import java.util.*;
import java.text.SimpleDateFormat;

ArrayList<Effect> effect;
PVector mp=new PVector();
SimpleDateFormat a, b, c;

float ZOOM=1;

void setup() {
  size(int(300*ZOOM), int(450*ZOOM));

//  a=new SimpleDateFormat("hh:mm");
//  b=new SimpleDateFormat("M月d日(E曜日)");
//  c=new SimpleDateFormat("ss");

  effect=new ArrayList<Effect>();
  textAlign(CENTER);
  noStroke();
  textFont(createFont("ほのか丸ゴシック", 50, true));

  gg=createGraphics(width, height);
  gg.beginDraw();
  gg.background(0);
  for (int i=0; i<20; i++) {
    gg.stroke(lerpColor(#330088, 0, i/20.));
    gg.line(0, i, width, i);
    gg.line(0, height-i, width, height-i);
  }
  gg.endDraw();
}

PGraphics gg;

void draw() {
  image(gg, 0, 0);
//  Date date=Calendar.getInstance().getTime();

  if (frameCount%3==0) {
    float r=random(TWO_PI);
    float d=random(0.5, 1);
    PVector p=new PVector(random(width*0.1, width*0.9), random(height*0.1, height*0.9));
    PVector s=new PVector(cos(r)*d, sin(r)*d);
    effect.add(new Effect(#ffaaaa, random(-PI/200, PI/200), p.x, p.y, s.x, s.y, (int)random(60, 120*2), (int)random(100, 200)));
  }

  PVector s=mp.get();
  mp.mult(9);
  mp.add(mouseX, mouseY, 0);
  mp.div(10);
  s.sub(mp);
  for (int i=0; i<5; i++) {
    float r=random(TWO_PI);
    float d=random(0, 15*max(s.mag()/5, 1));
    PVector pp=mp.get();
    pp.add(cos(r)*d, sin(r)*d, 0);
    PVector ss=s.get();
    ss.add(random(-2, 2), random(-2, 2), 0);
//    if (s.mag()<0.1) {
//      ss=new PVector(random(0, 3.5), 0);
//      ss.rotate(random(TWO_PI));
//    }
    ss.div(-5);
    effect.add(new Effect(#aaaaff, (s.mag()<0.1?5:1)*(random(2)>1?1:-1)*random(PI/30, PI/20)*ss.mag(), pp.x, pp.y, ss.x, ss.y, (int)random(60, 120), (int)random(100, 200)));
  }

  for (int i=0; i<effect.size (); i++)
    if (effect.get(i).update())
      effect.remove(i--);


  fill(255);
  textSize(50*ZOOM);
  //  text(a.format(date), width/2, height/4);
  text(hour()+":"+minute(), width/2, height/4);
  textSize(17*ZOOM);
  text(month()+"月"+day()+"日("+week_name(week_num(year(),month(),day()))+"曜日)", width/2, height/4+30);
  //  text(b.format(date), width/2, height/4+30);
  //  text(c.format(date), width*3/4, height/4);
  textSize(14*ZOOM);
  fill(255, (2+cos(radians(frameCount)))*255/3);
  text("ロック解除するにはスワイプしてください", width/2, height*2/3);
}

int week_num(int y, int m, int d) {
  if (m<=2) {
    m+=12;
    y--;
  }

  int Y=y % 100;
  int C=int(y/100);
  //int L=C/4-2*C;
  int L=5*C+C/4;
  return int(d+26*(m+1)/10+Y+Y/4+L+6)%7;
}

String week_name(int n){
    switch(n) {
    case 1:
      return "日";
    case 2:
      return "月";
    case 3:
      return "火";
    case 4:
      return "水";
    case 5:
      return "木";
    case 6:
      return "金";
    case 0:
      return "土";
    }
  return null;
}

public class Effect {
  color c=#aaaaff;
  float r=3;

  PVector p, s;
  int a, t, Maxt;
  float ang;
  public Effect(color c, float as, float x, float y, float sx, float sy, int t, int a) {
    this.c=c;
    p=new PVector(x, y);
    s=new PVector(sx, sy);
    Maxt=t;
    this.t=Maxt;
    this.a=a;

    ang=as;
  }

  public boolean update() {
    p.add(s);
//    s.rotate(PI/100*ang);
    float agl=PI/100*ang;
    float xx=s.x*cos(agl)-s.y*sin(agl);
    float yy=s.x*sin(agl)+s.y*cos(agl);
    s.set(xx,yy);

    fill(c, a*t/Maxt/2);
    ellipse(p.x, p.y, r*ZOOM, r*ZOOM);
    fill(c, a*t/Maxt);
    ellipse(p.x, p.y, r/2*ZOOM, r/2*ZOOM);

    return --t<0;
  }
}

感想とか

processing.jsができたとはいえど、すべての機能を使えるようではもちろんないようで、util.Calendarやtext.SimpleDateFormatが使えず、結局Processingの時刻関数とツェラーの公式を引っ張りだす羽目になったのと、PVector.rotateだけがなぜか使うことができず、回転行列を使う羽目になったのはせっかく使える機能が使えてない感じがして残念だ。