LoginSignup
0
1

htmlでRPGのマップ作成サイトを作る時にchatGPTと奮闘した話

Posted at

htmlでRPGのマップ作成サイトを作る時にchatGPTと奮闘した話

先日、私が作成しているhtmlのRPGで、マップの追加をするとき、それまではドット絵エディターである、『Pixel Studio(アップルストアの方 グーグルプレイの方)というものを使ってマップを描いていたのですが、面倒になってきました。なのでhtmlで、マップの画像と、当たり判定用のリストを作るコードを書こうと思ったのですが、技術が足りないのでchatGPTにお願いしました。でも、「画像をペイントできるドット絵メーカーを作ってください」「画像"が"ペイントされるのではなくて、画像"を"ペイントできるようにしてください」など...
ちなみに以下が初号機です。
スクリーンショット 2024-02-10 5.31.43.png
なんか違う...と思い、1時間近く奮闘していたところ、ようやくいい感じのものができたのでソースコードを紹介します。
因みに以下が完成図です。
スクリーンショット 2024-02-10 5.35.44.png
というわけで早速コード紹介〜

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pixel Art Editor</title>
<style>
  canvas {
    border: 1px solid black;
    cursor: crosshair;
  }
</style>
</head>
<body>
<input type="file" id="fileInput0" accept="image/*">
<br>
<canvas id="canvas" width="640" height="640"></canvas>
<br>
<button onclick="downloadImage()">Download Image</button>
<button onclick="showList()">Show List</button>
<div id="listContainer"></div>

<script>
var paintList = []; // ペイントされた情報を格納する配列
var gridSize = 20; // リストのサイズ
var pixelSize = 32; // 1つのピクセルのサイズ

window.onload = function() {
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var fileInput0 = document.getElementById('fileInput0');
    var img1 = new Image();
    var img0 = new Image();
    var isPainting = false; // ペイント中かどうかを示すフラグ
    
    // 2つの画像アップローダーにイベントリスナーを追加
    
    fileInput0.addEventListener('change', function(e) {
        handleFileUpload(e, img0);
    });
    
    function handleFileUpload(e, img) {
        var file = e.target.files[0];
        var reader = new FileReader();
        
        reader.onload = function(event) {
            img.onload = function() {
                drawGrid();
            }
            img.src = event.target.result;
        }
        reader.readAsDataURL(file);
    }
    
    function drawGrid() {
        for (var x = 0; x < canvas.width; x += pixelSize) {
            for (var y = 0; y < canvas.height; y += pixelSize) {
                ctx.strokeStyle = '#ccc';
                ctx.strokeRect(x, y, pixelSize, pixelSize);
            }
        }
    }
    
    // キャンバスにペイントする機能を追加
    canvas.addEventListener('mousedown', function(e) {
        isPainting = true;
        drawPixel(e);
    });
    
    canvas.addEventListener('mousemove', function(e) {
        if (isPainting) {
            drawPixel(e);
        }
    });
    
    canvas.addEventListener('mouseup', function() {
        isPainting = false;
    });
    
    function drawPixel(e) {
        var gridX = Math.floor((e.clientX - canvas.offsetLeft) / pixelSize) * pixelSize;
        var gridY = Math.floor((e.clientY - canvas.offsetTop) / pixelSize) * pixelSize;
        ctx.imageSmoothingEnabled = false; // 画像の拡大時に品質を維持
        if (img1.complete) {
            ctx.drawImage(img1, gridX, gridY, pixelSize, pixelSize);
            paintList.push({ x: gridX, y: gridY, id: 1 }); // ペイントされた情報をリストに追加
        }
        if (img0.complete) {
            ctx.drawImage(img0, gridX, gridY, pixelSize, pixelSize);
            paintList.push({ x: gridX, y: gridY, id: 0 }); // ペイントされた情報をリストに追加
        }
    }
};

function showList() {
    var listContainer = document.getElementById('listContainer');
    listContainer.innerHTML = ''; // 一旦リストをクリア
    
    // 初期状態のリストを作成
    var initialList = [];
    for (var i = 0; i < gridSize; i++) {
        var row = [];
        for (var j = 0; j < gridSize; j++) {
            row.push(0);
        }
        initialList.push(row);
    }
    
    // ペイントされた情報を元にリストを更新
    paintList.forEach(function(item) {
        var x = Math.floor(item.x / pixelSize);
        var y = Math.floor(item.y / pixelSize);
        initialList[y][x] = 1;
    });
    
    // リストを表示
    initialList.forEach(function(row) {
        var listItem = document.createElement('div');
        listItem.textContent = row.join(', ');
        listContainer.appendChild(listItem);
    });
}

function downloadImage() {
    var canvas = document.getElementById('canvas');
    var link = document.createElement('a');
    link.download = 'pixel_art.png';
    link.href = canvas.toDataURL('image/png');
    link.click();
}
</script>
</body>
</html>

技術的な解説は...面倒なのでGPTニキにでも聞いてください。とにかくこれでいい感じになります。

使い方(初心者用)

上に書いたコードをコピーしてメモ張やテキストエディタ、VScodeなど、お好きなアプリに貼り付け、保存します。windowsの方は、エクスプローラー → 表示(上のタブ) → 「拡張子を表示」に、チェックを入れてください。テキストエディタに戻って、任意の方法で保存します。保存されたファイルの拡張子を、.htmlに置き換えます。
完了したら、ファイルを開いてください。

ツールの使い方

まず、画像をアップロードします。そしたら、canvasにグリッドが表示されます。好きなようにペイントしてください。描いたところを1としたリストを生成する機能もついています。(デフォルトでは0で埋め尽くされています)
描き終わったら、画面下部の、showlistと書かれたところをクリックするとリストが表示され、downloadと書かれたところを押すとダウンロードされます。

カスタマイズについて

こちらのコードは、
画面サイズ 640px * 640px
ペイントとする画像のサイズ 32px四方
グリッド 20 * 20
となっていますが、お使いの環境・目的に合わせてカスタマイズできます。

画面サイズの変更

17行目の、

<canvas id="canvas" width="640" height="640"></canvas>

を変更します。widthとheightの値を変更するとエディターのサイズを変更できます。※どちらも同じ値にしてください。

ペイントする画像のサイズ

26行目の、

var pixelSize = 32; // 1つの画像のサイズ

を編集してください。一つのセルサイズが変更されます。

グリッドサイズ(リストのサイズ)

25行目の

var gridSize = 20; // リストのサイズ

ここを編集してください。画面サイズ÷画像サイズの値になるように設定しないとバグります。

質問はこちら

著者のXのDMにて質問していただければと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1