【Matrix Rain Code】映画「マトリックス」の”あの”画面作ってみた!

コードの雨

今回は、映画「マトリックス」風のコードの雨が流れる画面を作ってみました。

Matrix Rain Code

参考資料

ソースコード

HTML(index.html)

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Matrix</title>
<style>
html{
    background:black;
    height:100%;
    overflow:hidden;
}

body{
    margin:0;
    padding:0;
    height:100%;
}

</style>
</head>
<body>
    <canvas id="Matrix"></canvas>
<script>

let canvas=document.getElementById("Matrix");
let context=canvas.getContext("2d");

canvas.width=window.innerWidth;
canvas.height=window.innerHeight;

//出力文字の候補
const katakana="ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ";
const latin="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const nums="0123456789";

const alphabet=katakana+ latin+nums;

//出力文字サイズ
const fontSize=16;
    
//行数列数決め
let colums=canvas.width/fontSize;
let lines=canvas.height/fontSize

//落ちるコードを管理する配列
let rains=[];

//落ちるコードのコンストラクタ
var Rain=function(context,i,text,rainDrops){
    this.context=context;
    this.i=i;
    this.text=[];
    this.rainDrops=rainDrops;
};
    
//落ちるコードの描写
Rain.prototype.draw=function(){
    context=this.context;
    context.fillStyle="#0F0";
    context.font=fontSize+"px monospace";
    
    //出力文字決め
    this.text.push(alphabet.charAt(Math.floor(Math.random()*alphabet.length)));
    
    //薄くなっていく処理
    for(let j=0;j<this.rainDrops;j++){
            context.globalAlpha = 1.0-1.0*(j/lines);
            context.fillText(this.text[this.rainDrops-j-1],this.i*fontSize,(this.rainDrops-j)*fontSize);
            };
    
    //画面外に出たときの処理        
    if(this.rainDrops*fontSize>(canvas.height*2)&&Math.random()>0.975){
            this.rainDrops=0;
            this.text=[];
        }
    
    //下に一文字分下がる
    this.rainDrops++;
        };
    
//落ちるコードインスタンスを列の数だけ生成
for  (i = 0; i < colums; i++) {
        rainDrops=1;
        text=[];
        rain=new Rain(context,i,text,rainDrops);
        rains.push(rain);
    };
       
//実行関数の作成
function go(){
    //キャンバス上クリア
    context.clearRect(0, 0, canvas.width, canvas.height);

    //格納されたrainsの各要素を実行
    for(var k=0;k<colums;k++){
    rains[k].draw();
        }};
        
    //30フレームごとに繰り返しgoを実行
    setInterval(go,30);
    </script>
</body>
</html>
出力文字の候補

ここで出力したい全文字を記述して、あとでここから一文字をランダムで抜き出せるようにします。

行数列数決め

ここで画面のサイズとフォントサイズ(今回は16px)から文字を隣り合わせられるように、行と列の数を割り出します。

落ちるコードのコンストラクタ

ここでprototypeを用いて、落ちるコードのクラスを定義します。

落ちるコードの描写

ここで落ちるコード描写用のRainのdrawメソッドを定義します。

出力文字決め

ここで先ほど書いた全文字の中から、一文字ランダムに選んで空の配列textに追加していきます。

薄くなっていく処理

ここで文字が落ちていくときの残像の表現をしています。

for文で前に出力された文字はglobalAlphaでだんだんと透明度が増していくようになっています。

もし落ちてきたコードの位置が最後の行に行った場合、context.globalAlpha = 1.0-1.0*(j/lines)で最初の行で透明度100%、最後の行で透明度0%のグラデーションになるようにしてあります。

画面外に出たときの処理

落ちてきたコードが画面外に出たとき、RainDrops(どこの行にいるか決めている変数)が0となり、またその列の一行目から落ち始めるようになっています。

それぞれの列でタイミングをずらすためにMath.random()>0.975という条件式を加えています。

下に一文字分下がる

RainDropsがインクリメントされることで、drawメソッドが実行される度に描写されるコードは一行ずつ下がっていくようになっています。

落ちるコードインスタンスを列の数だけ生成

colums(画面内の列の数)だけfor文をまわして、落ちるコードインスタンスを生成し、配列rainsに格納していきます。

実行関数の作成
格納されたrainsの各要素を実行

各落ちるコードインスタンスのdrawメソッドを実行していきます。


ぜひ作ってみてください!

コメント

タイトルとURLをコピーしました