切比雪夫距离与图块不起作用

huangapple go评论68阅读模式
英文:

Chebyshev Distance With tiles isnt working

问题

从Chebyshev距离示例中链接,可以看到有一个人和透明度距离。

我尝试通过拥有一个固定区域和一个跟随玩家的代码来扩展示例,

function updateMap () {
    var origin = map.getTileAtWorldXY(player.x, player.y);
    var origin2 = map.getTileAtWorldXY(400, 400);

    map.forEachTile(function (tile) {
        var dist = Phaser.Math.Distance.Chebyshev(
            origin.x,
            origin.y,
            tile.x,
            tile.y
        );

        tile.setAlpha(tile.alpha+(1 - 0.05 * dist));
    });

    map.forEachTile(function (tile) {
        var dist1 = Phaser.Math.Distance.Chebyshev(
            origin2.x,
            origin2.y,
            tile.x,
            tile.y
        );

        tile.setAlpha(tile.alpha+(1 - 0.05 * dist1));
    });
}

所以,与我预期的两个正方形不同,一个是玩家,一个是固定的光,我得到了这个

切比雪夫距离与图块不起作用

为什么会发生这种情况,我应该如何修复它?

英文:

So from The phaser Chebyshev distance Example Link, It shows the one Man and the transparency distance.

I tried to expand on the example by having one stationary area and one following the player, code,

function updateMap () {
    var origin = map.getTileAtWorldXY(player.x, player.y);
    var origin2 = map.getTileAtWorldXY(400, 400);

    map.forEachTile(function (tile) {
        var dist = Phaser.Math.Distance.Chebyshev(
            origin.x,
            origin.y,
            tile.x,
            tile.y
        );

        tile.setAlpha(tile.alpha+(1 - 0.05 * dist));
    });

    map.forEachTile(function (tile) {
        var dist1 = Phaser.Math.Distance.Chebyshev(
            origin2.x,
            origin2.y,
            tile.x,
            tile.y
        );

        tile.setAlpha(tile.alpha+(1 - 0.05 * dist1));
    });
}

So instead of the two squares I expected, One for the player and one for the stationary light, Instead, I get this

切比雪夫距离与图块不起作用

Why Does this Happen, And How can i Fix it?

答案1

得分: 0

Phaser的切比雪夫函数运行正常。问题在于,每次运行update函数时,图块的alpha值都会增加,直到达到1(= 100%),这是因为您在两个循环中都添加了当前的alpha值(tile.setAlpha(tile.alpha+(1 - 0.05 * dist)))。

解决方案是:

  • 在第一个forEach循环中设置alpha,不要添加当前的alpha值。在我的示例中,这将是tile.setAlpha(1 - 0.09 * dist);
  • 为了确保在第二个循环中防止alpha值变为负数,可以使用Math.max,在我的示例中是tile.setAlpha(tile.alpha + Math.max(0, (1 - 0.09 * dist)));

然后它应该按照您的期望工作。

这里是一个小型的工作演示:

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    scene: {
        preload,
        create
    }
};

var player;
var point1 = {x: 60, y: 31};
var point2 = {x: 500, y: 150};

new Phaser.Game(config);

function preload (){
    this.load.image('tiles', 'https://labs.phaser.io/assets/tilemaps/tiles/catastrophi_tiles_16.png');
    this.load.tilemapCSV('map', 'https://labs.phaser.io/assets/tilemaps/csv/catastrophi_level2.csv');
}

function create () {
    this.add.text(10, 10, 'Click to change "player" position')
        .setOrigin(0)
        .setDepth(100)
        .setStyle({fontFamily: 'Arial'});

    let map = this.make.tilemap({ key: 'map', tileWidth: 16, tileHeight: 16 });
    let tileset = map.addTilesetImage('tiles');
    map.createLayer(0, tileset, 0, 0);

    player = this.add.rectangle(point1.x, point1.y, 5, 5, 0xffffff, 0.5)
                .setOrigin(0.5);

    updateMap(map);

    this.input.on('pointerdown', (pointer) => {
          point1 = pointer;
          player.setPosition(point1.x, point1.y)
          updateMap(map);
    });
}

function updateMap (map) {
    let fullLightDistanceInTiles = 3; 
    let originPoint1 = map.getTileAtWorldXY(point1.x, point1.y);
    let originPoint2 = map.getTileAtWorldXY(point2.x, point2.y);

    map.forEachTile(function (tile) {
        var dist = Phaser.Math.Distance.Chebyshev(
            originPoint1.x,
            originPoint1.y,
            tile.x,
            tile.y
        ) ;

        tile.setAlpha(1 - 0.09 * dist);
    });

   map.forEachTile(function (tile) {
        var dist = Phaser.Math.Distance.Chebyshev(
            originPoint2.x,
            originPoint2.y,
            tile.x,
            tile.y
        );
        tile.setAlpha(tile.alpha + Math.max(0, (1 - 0.09 * dist)));
    });
}

**信息:**出于性能原因,您应该考虑只使用一个forEach循环。

英文:

Phaser's Chebyshev function works fine. the problem is, that on each run of the update function the alpha value of the tiles are increased until it reaches 1 (= 100%), due to the fact, that you are adding the current alpha value in both loops (tile.setAlpha(tile.alpha+(1 - 0.05 * dist)))

The solution is to:

  • set the alpha in the first forEach- loop. without adding the current alpha value. In my example this would be tile.setAlpha(1 - 0.09 * dist);
  • And for good measure prevent in the second loop, that the alpha getd negative, with a Math.max, in my example tile.setAlpha(tile.alpha + Math.max(0, (1 - 0.09 * dist)));

Than it should work, as you expect it.

Here a small working demo:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

document.body.style = &#39;margin:0;&#39;;
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: {
preload,
create
}
};
var player;
var point1 = {x: 60, y: 31};
var point2 = {x: 500, y: 150};
new Phaser.Game(config);
function preload (){
this.load.image(&#39;tiles&#39;, &#39;https://labs.phaser.io/assets/tilemaps/tiles/catastrophi_tiles_16.png&#39;);
this.load.tilemapCSV(&#39;map&#39;, &#39;https://labs.phaser.io/assets/tilemaps/csv/catastrophi_level2.csv&#39;);
}
function create () {
this.add.text(10, 10, &#39;Click to change &quot;player&quot; position&#39;)
.setOrigin(0)
.setDepth(100)
.setStyle({fontFamily: &#39;Arial&#39;});
let map = this.make.tilemap({ key: &#39;map&#39;, tileWidth: 16, tileHeight: 16 });
let tileset = map.addTilesetImage(&#39;tiles&#39;);
map.createLayer(0, tileset, 0, 0);
player = this.add.rectangle(point1.x, point1.y, 5, 5, 0xffffff, .5)
.setOrigin(.5);
updateMap(map);
this.input.on(&#39;pointerdown&#39;, (pointer) =&gt; {
point1 = pointer;
player.setPosition(point1.x, point1.y)
updateMap(map);
});
}
function updateMap (map) {
let fullLightDistanceInTiles = 3; 
let originPoint1 = map.getTileAtWorldXY(point1.x, point1.y);
let originPoint2 = map.getTileAtWorldXY(point2.x, point2.y);
map.forEachTile(function (tile) {
var dist = Phaser.Math.Distance.Chebyshev(
originPoint1.x,
originPoint1.y,
tile.x,
tile.y
) ;
tile.setAlpha(1 - 0.09 * dist);
});
map.forEachTile(function (tile) {
var dist = Phaser.Math.Distance.Chebyshev(
originPoint2.x,
originPoint2.y,
tile.x,
tile.y
);
tile.setAlpha(tile.alpha + Math.max(0, (1 - 0.09 * dist)));
});
}

<!-- language: lang-html -->

&lt;script src=&quot;//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

> Info: for performance reasons you should think about using only one forEach - loop.

huangapple
  • 本文由 发表于 2023年2月14日 09:48:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75442765.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定