簡體   English   中英

等距網格坐標

[英]Isometric grid coordinates

我正在嘗試在 HTML5 中進行等距投影,我能得到的最接近的是通過縮放和旋轉視口

window.addEventListener('DOMContentLoaded', (event) => {
    class Point {
        constructor() {
            this.x = 0;
            this.y = 0;
        }
    }
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    function tick(time) {
        ctx.save();

        ctx.translate(250,0);

        ctx.scale(1, 0.5);
        ctx.rotate(45 * Math.PI /180);
        let p = new Point();
        p.x = 4*32;
        p.y = 2*32;

        ctx.fillStyle = 'green';
        ctx.fillRect(p.x,p.y,32,32);
        for (var x = 0; x < 10; ++x) {
            for (var y = 0; y < 10; ++y) {
                ctx.strokeStyle = 'black';
                ctx.strokeRect(x*32, y*32, 32, 32);
            }
        }

        ctx.restore();

        requestAnimationFrame(tick);
    }
    requestAnimationFrame(tick);
});

它確實有效..但這不是一個實用的解決方案,因為當我嘗試在該縮放和旋轉視圖中繪制等距精靈時,它看起來真的很扭曲。 所以我寧願不要 go 那條路線,除非我可以讓它工作而不扭曲我的精靈。

我也試過這個網站https://gamedevelopment.tutsplus.com/tutorials/creating-isometric-worlds-primer-for-game-developers-updated--cms-28392

它提供了一個生成等距網格的方程。 我用他們的cartesianToIsometric function 來嘗試制作一個iso網格

window.addEventListener('DOMContentLoaded', (event) => {
    class Point {
        constructor() {
            this.x = 0;
            this.y = 0;
        }
    }
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    function cartesianToIsometric(cartPt) {
        var tempPt = new Point();
        tempPt.x = cartPt.x - cartPt.y;
        tempPt.y = (cartPt.x + cartPt.y) / 2;
        return (tempPt);
    }
    function tick(time) {

        for (var x = 0; x < 50; ++x) {
            for (var y = 0; y < 50; ++y) {
                let p = new Point();
                p.x = x * 32;
                p.y = y * 32;
                let iso = cartesianToIsometric(p);

                ctx.strokeStyle = 'black';
                ctx.strokeRect(iso.x, iso.y, 32, 32);
            }
        }
        requestAnimationFrame(tick);
    }
    requestAnimationFrame(tick);
});

但它看起來仍然是錯誤的,除非我旋轉或縮放視口來糾正它。 在此處輸入圖像描述

所以我的問題是..如何在不縮放和旋轉視口的情況下繪制等距網格(如果可能)

如果我必須像第一個示例一樣縮放我的視口,我怎樣才能在不扭曲我的精靈的情況下做到這一點……抱歉,如果這個問題讓我對這方面的知識感到困惑,我的知識是不確定的……

這是我的 html 文件index.html

<html>
    <head>
        <script src="index.js"></script>
    </head>
    <body>
        <canvas id="canvas"></canvas>
    </body>
</html>

看起來您非常接近解決方案,但有點困惑。 讓我解釋:

通常,您不必旋轉和縮放 canvas 視口。 這是您在創建等距精靈時所做的事情。 你應該已經有了一些等距精靈,你所要做的只是將它們放在正確的等距坐標中。

您的第二種方法完全符合我的意思,使用笛卡爾坐標計算等距點。 它應該可以工作,無需繪制矩形,只需將圖像放在等距坐標上。

這里唯一的技巧是你應該從它們的底部中心點放置你的等距精靈

for (var x = 0; x < 50; ++x) {
    for (var y = 0; y < 50; ++y) {
        let p = new Point();
        p.x = x * 32;
        p.y = y * 32;
        let iso = cartesianToIsometric(p);

        // Apply offset to place each isometric image from its bottom center. 
        // The default pivot point (top left) won't do good 
        // because we need to stack them up according to their heights.
        let offset = {x: floorImageWidth/2, y: floorImageHeight}
        ctx.drawImage(floor, iso.x - offset.x, iso.y - offset.y);
    }
}

我還建議使用單獨的 function 來繪制等值點(不是矩形),以便您可以調試您的位置

let debug = true;

function debugDraw(time) {
    for (var x = 0; x < 50; ++x) {
        for (var y = 0; y < 50; ++y) {
            let p = new Point();
            p.x = x * tileWidth;
            p.y = y * tileWidth;
            let iso = cartesianToIsometric(p);

            // draw pivot point for each tile
            ctx.fillStyle = 'yellow';
            ctx.fillRect(iso.x - 5, iso.y - 5, 10, 10);
        }
    }
}

if(debug){
    requestAnimationFrame(debugDraw)
}

另外,這里有一個工作演示供您進一步實驗: https://codepen.io/justintc/pen/eYpMabx

希望有幫助,加油!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM