見出し画像

つぶやきProcessing Tips

こんにちは、AQUARING かに です。

みなさん「つぶやきProcessing」はご存知でしょうか?
Processingを用いて1ツイートに収まる文字数のプログラムでアート表現に挑戦するものです。

Twitterで「#つぶやきProcessing」で検索するとどのようなものかわかるかと思います。

ProcessingにはJava, JavaScript, Pythonなどいくつか種類がありますが、自分はJavaScript版であるp5.jsを使用しています。
↓最近描いて投稿したもの

自分はまだ最近始めたばかりではありますが、他の参加者のスケッチ(​Processingではプログラムのことをスケッチと呼びます)を見たり自分でもいくつかスケッチを書く中でつぶやきProcessing特有の書き方の知見が貯まってきたので、備忘録として残しておきます。

つぶやきProcessingはスケッチの文字数をいかに削減するかにかかっているので、そこを中心にまとめていきます。(文字数が削減できれば余りの使える文字数が増えて、表現の可能性も広がりますよね。)

グローバル変数を使う

let a=0

↓ ↓ ↓

a=0

グローバル(window)変数にすることで let が不要になります。

アロー関数を使う

function draw(){}

↓ ↓ ↓

draw=_=>{}

function は1単語が長いので、アロー関数を使いましょう。
アロー関数の引数の () は _ にすると1文字削減できます。

frameCountとsetup()

t=0
draw=_=>{t++||createCanvas(W=400,W)
}

変数 t=0 を定義し、drawの最初で t++ して frameCount としての役割を持たせます。
t++ するところで 論理和 (||) を使用することで、t == 0 のとき(最初の一回)だけ実行される箇所ができます。
つまり setup関数 を書くことなく、それと同等の挙動を draw関数 ひとつで実現できます。

t=0
draw=_=>{t++||(createCanvas(W=400,W),g=createGraphics(W,W))
}

また、論理和 (||) の右側を () で囲うことで複数の処理を 最初の一回だけ 実行することができます。

W=0
draw=_=>{W||createCanvas(W=400,W)
}

上記はあまりないケースですが、「frameCountとしての変数 t は使わないけど、drawでスケッチを書きたい」場合には t=0, t++W=0, W に置き換えても動作します。

複数回呼ぶ処理は1文字の変数に代入する

t=0
draw=_=>{t++||createCanvas(W=400,W)
l=line
l(0,0,W,W)
l(W,0,0,W)
}

4文字以上の計算や関数を複数回使う場合は、1文字の変数に代入しましょう。

繰り返し - for

// 16文字
for(i=0;i<9;i++)

昇順の for文 から スペース と let を取り除いた状態

for(i=0;i<9;)print(i++)

繰り返し内で i を使う場合は () 内の i++ を消して最後に i を使うところを i++ に置き換えると1文字分削減ができます。

// 15文字
for(i=9;i-->0;)

降順にしたパターン。

// 13文字
for(i=9;i--;)

降順にする場合は、i == 0 のときに false として評価されるため、 >0 を省略できます。いまのところこれが一番少ない文字数で書けるループだとおもいます。(もっと短い書き方があれば教えてください)

また、i=9の部分を

background(i=9)
for(;i--;)

このようにfor文以前で同じ数値(またはそれに近い数値を入れても問題ない)の部分を代入式におきかえることで最低1文字削減できます。

グリッド配置などでよく使う二重for文は、

for(i=9;i--;){
for(j=9;j--;){
point(i,j)
}
}
for(i=81;i--;)point(i%9,~~(i/9))

このように一重のfor文にまとめてしまって、i, j を計算で求めることで文字数を短縮できます。

繰り返し - while

// 16文字
i=0
while(i++<9)

昇順パターン。
↑だと繰り返し内で i の値が 1 ~ 9 になるので注意が必要です。

i=0
while(i<9)print(i++)

for文 とおなじく、繰り返し内で i を使う場合は 最後に i を使うところを i++ に置き換えますが、while文の場合は文字数は変わりません。

i=9
while(i-->0)

降順パターン。
文字数そのままで i の範囲を 0 ~ 8 にするには逆順にします。

// 14文字
i=9
while(i--)

whileで書ける最短のループ

色に255以上の変数を入れる

t=0
draw=_=>{t++||createCanvas(W=400,W)
background(W,W,0)
}

↑backgroundには (400,400,0) が入りますが、実質 (255,255,0) と同義になります。
255以上の値を入れている別の用途で定義した変数を色(0 ~ 255)の引数に渡すことで、自動的に255にclampされる仕様を利用しています。

円周率にTAUを使う

rotate(TWO_PI)
rotate(PI*2)

// ↓ ↓ ↓

rotate(TAU)

円周率*2を表す TWO_PI のエイリアスとして TAU というシステム変数も定義されています。(つぶやきProcessingをやるまで存在を知りませんでした...!)

不要な改行の削減

for(i=0;i<9;){push()
rotate(i++*TAU/9)
line(0,0,W,0)
pop()}

ブロック内の処理の始まりと終わりには区切り文字は必要ないので、 { の直後と } の直前の改行は省略しましょう。

for(i=0;i<9;)push(),rotate(i++*TAU/9),line(0,0,W,0),pop()

さらに文字数を削減したい場合は区切り文字を改行から , カンマ に変えて1行の省略記法にすると、 { } も削減できます。

三項演算子を使う

x=mouseX
y=mouseY
if(x<W/2)circle(x,y,W)
else square(x,y,W)

↓ ↓ ↓

x=mouseX
y=mouseY
x<W/2?circle(x,y,W):square(x,y,W)

if else 文は 三項演算子 で書き換えができます。

文字列を1文字ずつ分割

[...'🐶🐱🐰🐻'][0]
>> 🐶

文字列を スプレッド演算子 で展開することで、絵文字や2バイト文字などのサロゲートペアを考慮した分割ができます。

小数点以下切り捨て

floor(random(W))

↓ ↓ ↓

~~random(W)

floor() ではなく、ビット否定 (~) 演算子 をふたつ(~~)つけることでも小数点以下の切り捨てができます。

タグ付きテンプレート

color系の関数はタグ付きテンプレートを使うことで実行できます。

t=0
draw=_=>{t++||createCanvas(W=400,W)
background(W)}//#つぶやきProcessing

↓ ↓ ↓

t=0
draw=_=>{t++||createCanvas(W=400,W)
background`#つぶやきProcessing`}

詳しい解説をすると長くなるので省きますが、カラーコードやCSSの色名以外の文字列を指定すると真っ白になります。
これを利用してハッシュタグを文字列内に入れるとコメントアウト分の2文字も削減できます。

()に関数実行や変数代入をもってくる

push()
noStroke()
fill(0)
rotate(t+=.01)
box(99)
pop()​

↓ ↓ ↓

push(noStroke(fill(0)))
rotate(t+=.01)
pop(box(99))​

実行順に気をつける必要がありますが、()の中に関数実行や変数代入を持ってくることで改行が削減できます。

定数を数値に置き換える

t=0
draw=_=>{t++||createCanvas(W=800,W,WEBGL)
background(0)
g=drawingContext
g.depthFunc(gl.ALWAYS)
g.blendFunc(gl.SRC_ALPHA,gl.ONE)
}

↓ ↓ ↓

t=0
draw=_=>{t++||createCanvas(W=800,W,WEBGL)
background(0)
g=drawingContext
g.depthFunc(519) // gl.ALWAYS -> 519
g.blendFunc(770,1) // gl.SRC_ALPHA -> 770, gl.ONE -> 1
}

WebGLRenderingContext.blendFunc() などの引数に渡すWebGL定数は、中身の数値をハードコーディングすることで大幅に文字数を削減できます。

ひとこと

普段のデイリーコーディングでも p5.js でスケッチを書いていますが、 つぶやきProcessing を始めてみて、「1ツイートに収まるというルールがあるだけで使う脳の部位が全く変わるな〜」と感じました。

始める前はちょっと難しそうなイメージがありましたが、実際やってみるとそんなこともなく、逆に普段絶対書かないような書き方を強いられるのでJavaScriptの文法の再学習にもなるので良いですね。

今後もゆるっと続けていけたらと思います。

この記事が気に入ったらサポートをしてみませんか?