英文:
Phaser 3 : Distort shape of grid
问题
如何使一个5x5的网格像下面的图片一样扭曲?原因是为了制作一条走道,最近的是较大的瓷砖,最远的是较小的瓷砖,并且能够动态在顶部添加5x1的瓷砖。
英文:
If there is grid with 5x5, how to make the grid distort like the image below ? The reason is to make a walk way, the nearest is bigger tiles, furthest is smaller tiles, and able to dynamic prepend 5x1 on top
答案1
得分: 2
以下是您要翻译的内容:
如果您想自己绘制它,您可以使用内置函数来帮助完成。我创建了一个简短的演示,展示了我如何使用Phaser的graphics
,'line' - gameobject,'intersects'等方法来解决这个问题。 (这可能会有所帮助)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: { create }
};
function create () {
this.add.text(10,10, '绘制网格 5 x 5')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.add.graphics({ lineStyle: { width: 1, color: 0xaa00aa } });
let leftX = config.width/2 - ( 50 * 5);
let vertricalLines = [];
// 创建垂直辅助线
for(let lineIdx = 0; lineIdx < 6; lineIdx++){
let line = new Phaser.Geom.Line(config.width/2, 10, leftX, config.height -15);
vertricalLines.push(line)
leftX += 100;
}
// 绘制水平和垂直线
let bottomY = config.height - 15;
let height = 40;
for(let lineIdx = 0; lineIdx < 7; lineIdx++){
let horizontalLine = new Phaser.Geom.Line(config.width/2 - ( 50 * 5), bottomY, leftX, bottomY);
let startPoint = { x: 0, y: 0 };
let endPoint = { x: 0, y: 0 };
Phaser.Geom.Intersects.LineToLine(vertricalLines[0], horizontalLine, startPoint);
Phaser.Geom.Intersects.LineToLine(vertricalLines[vertricalLines.length - 1], horizontalLine, endPoint);
let drawLine = new Phaser.Geom.Line(startPoint.x, bottomY, endPoint.x, bottomY);
graphics.strokeLineShape(drawLine);
bottomY -= height;
height *= .75
if(lineIdx == 6){
vertricalLines.forEach(line =>{
let point = { x: 0, y: 0 };
Phaser.Geom.Intersects.LineToLine(line, horizontalLine, point);
line.x1 = point.x;
line.y1 = point.y;
graphics.strokeLineShape(line);
});
}
}
}
new Phaser.Game(config);
免责声明:
通常我不会编写完整的解决方案,只是帮助找到解决方案 (但我想自己尝试一下)。以下代码是一种粗糙/快速的解决方案,可能不是解决此问题的最佳方法,可能需要一些改进。
英文:
If you want to draw it yourself, you can use builtin functions to help with that. I created a short demo showing, how I would approach this problem, using Phaser's graphics
, 'line' - gameobject, intersects
and some other stuff. (it might help)
<!-- 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: { create }
};
function create () {
this.add.text(10,10, 'Draw Grid 5 x 5')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.add.graphics({ lineStyle: { width: 1, color: 0xaa00aa } });
let leftX = config.width/2 - ( 50 * 5);
let vertricalLines = [];
// create vertical helper lines
for(let lineIdx = 0; lineIdx < 6; lineIdx++){
let line = new Phaser.Geom.Line(config.width/2, 10, leftX, config.height -15);
vertricalLines.push(line)
leftX += 100;
}
// draw horziontal and vertical lines
let bottomY = config.height - 15;
let height = 40;
for(let lineIdx = 0; lineIdx < 7; lineIdx++){
let horizontalLine = new Phaser.Geom.Line(config.width/2 - ( 50 * 5), bottomY, leftX, bottomY);
let startPoint = { x: 0, y: 0 };
let endPoint = { x: 0, y: 0 };
Phaser.Geom.Intersects.LineToLine(vertricalLines[0], horizontalLine, startPoint);
Phaser.Geom.Intersects.LineToLine(vertricalLines[vertricalLines.length - 1], horizontalLine, endPoint);
let drawLine = new Phaser.Geom.Line(startPoint.x, bottomY, endPoint.x, bottomY);
graphics.strokeLineShape(drawLine);
bottomY -= height;
height *= .75
if(lineIdx == 6){
vertricalLines.forEach(line =>{
let point = { x: 0, y: 0 };
Phaser.Geom.Intersects.LineToLine(line, horizontalLine, point);
line.x1 = point.x;
line.y1 = point.y;
graphics.strokeLineShape(line);
});
}
}
}
new Phaser.Game(config);
<!-- language: lang-html -->
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
<!-- end snippet -->
> Disclaimer:
> I usually don't code the whole solution, just help find a solution (but I wanted to try it out myself). And the following code is a crude/fast solution, it might not be the best way to solve this, and/or could need some improvement.
<!-- 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: { create }
};
function create () {
let infoLabel = this.add.text(10,10, 'Draw Grid 5 x 5')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let button = this.add.rectangle(10, 45, 120, 30, 0x00ff00 )
.setOrigin(0)
.setDepth(100)
.setInteractive();
let buttonLabel = this.add.text(10,10, 'Add row')
.setScale(1)
.setDepth(101)
.setColor('#000000')
.setStyle({fontStyle: 'bold', fontFamily: 'Arial', aligin: 'Center'});
Phaser.Display.Align.In.Center(buttonLabel, button);
this.grid = this.add.graphics({ lineStyle: { width: 1, color: 0xaa00aa } })
.setInteractive(new Phaser.Geom.Rectangle(0, 0, config.width, config.height), Phaser.Geom.Rectangle.Contains);
button.on('pointerdown', () => {
this.maxRows++;
drawGrid( this );
});
this.grid.on('pointerdown', p => {
infoLabel.setText('');
let selectedCols = this.cols.map( ( col, idx ) => {
return { idx, wasClicked:Phaser.Geom.Triangle.Contains(col, p.x, p.y)}
}).filter( i => i.wasClicked);
if(selectedCols[0]){
let selectedRows = this.rows.map( ( row, idx ) => ({ idx, wasClicked: Phaser.Geom.Polygon.Contains(row, p.x, p.y)}))
.filter( i => i.wasClicked);
if(selectedRows[0]){
infoLabel.setText(`Cell ( ${ selectedCols[0].idx }, ${ selectedRows[0].idx } )`);
}
}
});
this.maxRows = 5;
drawGrid( this );
}
function drawGrid(scene){
scene.grid.clear();
let leftX = config.width/2 - ( 50 * 5);
let vertricalLines = [];
let horizontaLines = [];
scene.cols = [];
scene.rows = [];
// create vertical helper lines
for(let lineIdx = 0; lineIdx < 6; lineIdx++){
let line = new Phaser.Geom.Line(config.width/2, 10, leftX, config.height -15);
vertricalLines.push(line)
leftX += 100;
// just for interactivity
if(lineIdx > 0 ){
let lastLine = vertricalLines[lineIdx -1];
scene.cols.push(
new Phaser.Geom.Triangle ( line.x1, line.y1, line.x2 , line.y2, lastLine.x2, lastLine.y2)
);
}
}
// draw horziontal and vertical lines
let bottomY = config.height - 15;
let height = 40;
for(let lineIdx = 0; lineIdx < scene.maxRows ; lineIdx++){
let horizontalLine = new Phaser.Geom.Line(config.width/2 - ( 50 * 5), bottomY, leftX, bottomY);
let startPoint = { x: 0, y: 0 };
let endPoint = { x: 0, y: 0 };
horizontaLines.push(horizontalLine);
Phaser.Geom.Intersects.LineToLine(vertricalLines[0], horizontalLine, startPoint);
Phaser.Geom.Intersects.LineToLine(vertricalLines[vertricalLines.length - 1], horizontalLine, endPoint);
scene.grid.strokeLineShape(new Phaser.Geom.Line(startPoint.x, bottomY, endPoint.x, bottomY));
bottomY -= height;
height *= .75
if(lineIdx == scene.maxRows - 1){
vertricalLines.forEach(line =>{
let point = { x: 0, y: 0 };
Phaser.Geom.Intersects.LineToLine(line, horizontalLine, point);
line.x1 = point.x;
line.y1 = point.y;
scene.grid.strokeLineShape(line);
});
}
// just for interactivity
if(lineIdx > 0 ){
let lastLine = horizontaLines[lineIdx -1];
scene.rows.push(
new Phaser.Geom.Polygon ( [horizontalLine.x1, horizontalLine.y1, horizontalLine.x2 , horizontalLine.y2, lastLine.x2, lastLine.y2, lastLine.x1, lastLine.y1 ])
);
}
}
}
new Phaser.Game(config);
<!-- language: lang-html -->
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论