何かの箱

01.文字出力

データの構造を考える

80x25とサイズを決めちゃいましたので、二次元配列の構造にすれば文字の位置を簡単に設定できます。 ただ、編集のしやすさとかtextareaへの反映のしやすさを考慮すると、80文字の文字列を25個もつ配列のほうがよさそう。 情報としては変更にも対応できるように、幅とか高さは持っておきたい。というわけでデータクリア含めてこんな感じ。
      {
        width: 80,
        height: 25,
        data: null,
        clear: function() {
          this.data = [];
          for (let i = 0; i < this.height; i++) {
            this.data.push(' '.repeat(this.width));
          }
          return this;
        },
      }
      

出力データの取得

下地ができたら、そのデータを取得できるようにしたいのが普通。 表示データすべてを取得するだけでなく、座標位置の内容も取れたりすると便利な気がします。 というわけでこうしました。
        /* 前略 */
        getData: function(x, y) {
          const w = this.data ?? this.clear().data;
          if (x == null || y == null) {
            return w;
          }
          return w[y].charAt(x);
        },
        /* 以下略 */
      

文字の編集

データ構造が整理できましたので、次に文字を編集できるようにします。 座標をもとに、既存の文字を入れ替えるようにすれば期待したふるまいになります。 行単位では文字列になっていますので、せっかくなので文字入れ替えの処理を作ってしまうことに。
        String.prototype.replaceAt = function(index, s) {
          return this.substring(0, index) + s + this.substring(index + s.length);
        };
      
文字入れ替えの処理を作りましたので、あとは差し替えのインタフェースを用意します。
        /* 前略 */
        setData : function(x, y, d) {
          const w = screen.getData();
          w[y] = w[y].replaceAt(x,d);
          return this;
        },
        /* 以下略 */
      

データの反映

データの取得と編集までできましたので、最後に描画処理を用意します。
        /* 前略 */
        elm: document.querySelector('#gconsole textarea'),
        redraw: function() {
          this.elm.value = this.getData().join('\n');
        },
        /* 以下略 */
      
ここまでできれば、試しに表示するだけです。
        screen.setData(40, 12, '@').redraw();
      

リソース

gconsole.css gconsole.js g01.js

関連

00.画面表示 02.無限ループ 03.画像出力 04.キー操作 05.速度を調整 06.敵の配置 07.ゲームにする 08.ゲームパッド