英文:
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 betile.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 exampletile.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 = '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, .5)
.setOrigin(.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)));
});
}
<!-- language: lang-html -->
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
<!-- end snippet -->
> Info: for performance reasons you should think about using only one forEach
- loop.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论