8KB JavaScriptマリオもコードリーディングしたけど……
14KB JavaScriptマリオを作ったJacob Seidelinさんが自らの記録を更新しました。今度は8KBです。
8 kilobytes of Mario
JavaScriptをPNGに埋め込んでるそうです。何を言ってるのかまるで分かりませんね。とりあえず前回と同じように読んでいきましょう。
m.js 324B
m.png 7.7KB
JavaScriptのソースは3行です。頭がおかしくなりそうです。読みやすいように適当に改行とインデントを入れるとこんな感じ。これで全文です。
var o = new Image(); o.onload = function() { var r = "", s = 119, c = document.createElement("canvas"); c.width = c.height = c.style.width = c.style.height = s, t = c.getContext("2d"); t.drawImage(o,0,0); var d = t.getImageData(0,0,s,s).data; for(var i = 0; i < d.length; i += 4) { if(d[i] > 0) r += String.fromCharCode(d[i]); } eval(r); Mario(true,1) }; o.src="m.png";
まずImageオブジェクトを作ってます。
var o = new Image();
キャンバスの縦横サイズを設定するだけの処理ですが、変数s(=119)の値を一気に代入して文字数を節約しています。
c.width = c.height = c.style.width = c.style.height = s,
今回のキモはここです。画像データを端から読んでいって文字列として連結します。すべて終わったらその文字列を実行(eval)しちゃいます。つまり本来ピクセルデータを格納するところにJavaScriptのプログラムを無理やり突っ込んでるわけです。
var d = t.getImageData(0,0,s,s).data; for(var i = 0; i < d.length; i += 4) { if(d[i] > 0) r += String.fromCharCode(d[i]); } eval(r);
ちなみにこの時の連結文字列を表示してみると、おなじみの(?)14KB Marioのソースが現れました。めでたしめでたし。
var Mario=function(AF,P){var Y=parseInt,U=setTimeout,AH=function(c){return(省略)
そんなわけで前回の14KBのプログラムを画像として圧縮したら8KBになったよ、というのが実状なわけで反則技ではありますが、ちょっと面白いアイデアですね。